diff --git a/Fairy.Debugger.cs b/Fairy.Debugger.cs index 2489fb9..5673eb3 100644 --- a/Fairy.Debugger.cs +++ b/Fairy.Debugger.cs @@ -41,14 +41,14 @@ protected virtual JObject DebugFunctionWithSession(JArray _params) Attributes = System.Array.Empty(), Witnesses = signers.Witnesses, }; - ulong timestamp; - if (!sessionToTimestamp.TryGetValue(session, out timestamp)) // we allow initializing a new session when executing - sessionToTimestamp[session] = 0; + RuntimeArgs runtimeArgs; + if (!sessionToRuntimeArgs.TryGetValue(session, out runtimeArgs)) // we allow initializing a new session when executing + sessionToRuntimeArgs[session] = new RuntimeArgs(); FairyEngine newEngine; logs.Clear(); FairyEngine.Log += CacheLog; BreakReason breakReason = BreakReason.None; - if (timestamp == 0) + if (runtimeArgs.timestamp == 0) { FairyEngine? oldEngine; if (sessionToEngine.TryGetValue(session, out oldEngine)) @@ -63,7 +63,7 @@ protected virtual JObject DebugFunctionWithSession(JArray _params) else { FairyEngine oldEngine = debugSessionToEngine[session]; - newEngine = DebugRun(script, oldEngine.Snapshot.CreateSnapshot(), out breakReason, persistingBlock: CreateDummyBlockWithTimestamp(oldEngine.Snapshot, system.Settings, timestamp: timestamp), container: tx, settings: system.Settings, gas: settings.MaxGasInvoke); + newEngine = DebugRun(script, oldEngine.Snapshot.CreateSnapshot(), out breakReason, persistingBlock: CreateDummyBlockWithTimestamp(oldEngine.Snapshot, system.Settings, timestamp: runtimeArgs.timestamp), container: tx, settings: system.Settings, gas: settings.MaxGasInvoke); } FairyEngine.Log -= CacheLog; if (writeSnapshot) diff --git a/Fairy.Engine.cs b/Fairy.Engine.cs index 15f18bf..129876d 100644 --- a/Fairy.Engine.cs +++ b/Fairy.Engine.cs @@ -3,6 +3,7 @@ using Neo.SmartContract; using Neo.SmartContract.Native; using Neo.VM; +using System.Numerics; namespace Neo.Plugins { @@ -10,9 +11,7 @@ public partial class Fairy { public class FairyEngine : ApplicationEngine { - protected FairyEngine(TriggerType trigger, IVerifiable container, DataCache snapshot, Block persistingBlock, ProtocolSettings settings, long gas, IDiagnostic diagnostic) : base(trigger, container, snapshot, persistingBlock, settings, gas, diagnostic) - { - } + protected FairyEngine(TriggerType trigger, IVerifiable container, DataCache snapshot, Block persistingBlock, ProtocolSettings settings, long gas, IDiagnostic diagnostic) : base(trigger, container, snapshot, persistingBlock, settings, gas, diagnostic){} public static new FairyEngine Create(TriggerType trigger, IVerifiable container, DataCache snapshot, Block persistingBlock = null, ProtocolSettings settings = null, long gas = TestModeGas, IDiagnostic diagnostic = null) { diff --git a/Fairy.Tester.Snapshot.cs b/Fairy.Tester.Snapshot.cs index 89a3413..2f8d92c 100644 --- a/Fairy.Tester.Snapshot.cs +++ b/Fairy.Tester.Snapshot.cs @@ -1,12 +1,23 @@ using Neo.IO.Json; using System.Collections.Concurrent; +using System.Numerics; namespace Neo.Plugins { public partial class Fairy { public readonly ConcurrentDictionary sessionToEngine = new(); - public readonly ConcurrentDictionary sessionToTimestamp = new(); + public struct RuntimeArgs + { + public ulong timestamp = 0; + // public BigInteger? designatedRandom = null; + + public new string ToString() + { + return $"timestamp: {timestamp}";//\tdesignatedRandom: {designatedRandom}"; + } + } + public readonly ConcurrentDictionary sessionToRuntimeArgs = new(); private FairyEngine BuildSnapshotWithDummyScript(FairyEngine engine = null) { @@ -25,7 +36,7 @@ protected virtual JObject NewSnapshotsFromCurrentSystem(JArray _params) else json[session] = false; sessionToEngine[session] = FairyEngine.Run(new byte[] { 0x40 }, system.StoreView, settings: system.Settings, gas: settings.MaxGasInvoke); - sessionToTimestamp[session] = 0; + sessionToRuntimeArgs[session] = new(); } return json; } @@ -37,7 +48,7 @@ protected virtual JObject DeleteSnapshots(JArray _params) foreach (var s in _params) { string str = s.AsString(); - json[str] = sessionToEngine.Remove(str, out var _) ? sessionToTimestamp.Remove(str, out var _) : false; + json[str] = sessionToEngine.Remove(str, out var _) ? sessionToRuntimeArgs.Remove(str, out var _) : false; } return json; } @@ -60,8 +71,8 @@ protected virtual JObject RenameSnapshot(JArray _params) string to = _params[1].AsString(); sessionToEngine[to] = sessionToEngine[from]; sessionToEngine.Remove(from, out var _); - sessionToTimestamp[to] = sessionToTimestamp[from]; - sessionToTimestamp.Remove(from, out var _); + sessionToRuntimeArgs[to] = sessionToRuntimeArgs[from]; + sessionToRuntimeArgs.Remove(from, out var _); JObject json = new(); json[to] = from; return json; @@ -73,7 +84,7 @@ protected virtual JObject CopySnapshot(JArray _params) string from = _params[0].AsString(); string to = _params[1].AsString(); sessionToEngine[to] = BuildSnapshotWithDummyScript(sessionToEngine[from]); - sessionToTimestamp[to] = sessionToTimestamp[from]; + sessionToRuntimeArgs[to] = sessionToRuntimeArgs[from]; JObject json = new(); json[to] = from; return json; @@ -84,7 +95,9 @@ protected virtual JObject SetSnapshotTimestamp(JArray _params) { string session = _params[0].AsString(); ulong timestamp = ulong.Parse(_params[1].AsString()); - sessionToTimestamp[session] = timestamp; + RuntimeArgs runtimeArgs = sessionToRuntimeArgs[session]; + runtimeArgs.timestamp = timestamp; + sessionToRuntimeArgs[session] = runtimeArgs; JObject json = new(); json[session] = timestamp; return json; @@ -97,9 +110,47 @@ protected virtual JObject GetSnapshotTimeStamp(JArray _params) foreach (var s in _params) { string session = s.AsString(); - json[session] = sessionToTimestamp.GetValueOrDefault(session, (ulong)0); + json[session] = sessionToRuntimeArgs.GetValueOrDefault(session, new RuntimeArgs()).timestamp; } return json; } + + //[RpcMethod] + //protected virtual JObject SetSnapshotRandom(JArray _params) + //{ + // string session = _params[0].AsString(); + // string? designatedRandomString = _params[1]?.AsString(); + // if (designatedRandomString == null) + // { + // RuntimeArgs runtimeArgs = sessionToRuntimeArgs[session]; + // runtimeArgs.designatedRandom = null; + // sessionToRuntimeArgs[session] = runtimeArgs; + // } + // else + // { + // BigInteger designatedRandom = BigInteger.Parse(designatedRandomString); + // RuntimeArgs runtimeArgs = sessionToRuntimeArgs[session]; + // runtimeArgs.designatedRandom = designatedRandom; + // sessionToRuntimeArgs[session] = runtimeArgs; + // } + // JObject json = new(); + // json[session] = designatedRandomString; + // return json; + //} + + //[RpcMethod] + //protected virtual JObject GetSnapshotRandom(JArray _params) + //{ + // JObject json = new(); + // foreach (var s in _params) + // { + // string session = s.AsString(); + // if (sessionToRuntimeArgs.ContainsKey(session)) + // json[session] = sessionToRuntimeArgs[session].designatedRandom.ToString(); + // else + // json[session] = null; + // } + // return json; + //} } } diff --git a/Fairy.Tester.cs b/Fairy.Tester.cs index 8e50c81..095545b 100644 --- a/Fairy.Tester.cs +++ b/Fairy.Tester.cs @@ -60,15 +60,15 @@ private JObject GetInvokeResultWithSession(string session, bool writeSnapshot, b Attributes = System.Array.Empty(), Witnesses = signers.Witnesses, }; - ulong timestamp; - if (!sessionToTimestamp.TryGetValue(session, out timestamp)) // we allow initializing a new session when executing - sessionToTimestamp[session] = 0; + RuntimeArgs runtimeArgs; + if (!sessionToRuntimeArgs.TryGetValue(session, out runtimeArgs)) // we allow initializing a new session when executing + sessionToRuntimeArgs[session] = new RuntimeArgs(); FairyEngine oldEngine, newEngine; DataCache validSnapshotBase; Block block = null; logs.Clear(); FairyEngine.Log += CacheLog; - if (timestamp == 0) + if (runtimeArgs.timestamp == 0) { if (sessionToEngine.TryGetValue(session, out oldEngine)) { @@ -85,7 +85,7 @@ private JObject GetInvokeResultWithSession(string session, bool writeSnapshot, b { oldEngine = sessionToEngine[session]; validSnapshotBase = oldEngine.Snapshot; - block = CreateDummyBlockWithTimestamp(oldEngine.Snapshot, system.Settings, timestamp: timestamp); + block = CreateDummyBlockWithTimestamp(oldEngine.Snapshot, system.Settings, timestamp: runtimeArgs.timestamp); newEngine = FairyEngine.Run(script, oldEngine.Snapshot.CreateSnapshot(), persistingBlock: block, container: tx, settings: system.Settings, gas: settings.MaxGasInvoke); } FairyEngine.Log -= CacheLog; @@ -140,7 +140,7 @@ private JObject GetInvokeResultWithSession(string session, bool writeSnapshot, b } foreach (LogEventArgs log in logs) { - string contractName = NativeContract.ContractManagement.GetContract(newEngine.Snapshot, log.ScriptHash).Manifest.Name; + string contractName = NativeContract.ContractManagement.GetContract(newEngine.Snapshot, log.ScriptHash)?.Manifest.Name; traceback += $"\r\n[{log.ScriptHash}] {contractName}: {log.Message}"; } json["traceback"] = traceback; diff --git a/Fairy.Utils.cs b/Fairy.Utils.cs index 36bd180..09ccdfd 100644 --- a/Fairy.Utils.cs +++ b/Fairy.Utils.cs @@ -36,7 +36,7 @@ protected virtual JObject VirtualDeploy(JArray _params) { Transaction tx = fairyWallet.MakeTransaction(snapshot.CreateSnapshot(), script); UInt160 hash = SmartContract.Helper.GetContractHash(tx.Sender, nef.CheckSum, manifest.Name); - sessionToEngine[session] = FairyEngine.Run(script, snapshot.CreateSnapshot(), persistingBlock: CreateDummyBlockWithTimestamp(oldEngine.Snapshot, system.Settings, timestamp: sessionToTimestamp.GetValueOrDefault(session, (ulong)0)), container: tx, settings: system.Settings, gas: settings.MaxGasInvoke); + sessionToEngine[session] = FairyEngine.Run(script, snapshot.CreateSnapshot(), persistingBlock: CreateDummyBlockWithTimestamp(oldEngine.Snapshot, system.Settings, timestamp: sessionToRuntimeArgs.GetValueOrDefault(session, new RuntimeArgs()).timestamp), container: tx, settings: system.Settings, gas: settings.MaxGasInvoke); json[session] = hash.ToString(); } catch (InvalidOperationException ex) diff --git a/FairyPlugin.cs b/FairyPlugin.cs index 10b5c78..0230c89 100644 --- a/FairyPlugin.cs +++ b/FairyPlugin.cs @@ -40,16 +40,16 @@ protected override void OnSystemLoaded(NeoSystem system) [ConsoleCommand("fairy", Category = "Fairy Commands", Description = "List Fairy snapshots")] private void OnFairyCommand() { - ulong timestamp; + Fairy.RuntimeArgs runtimeArgs; ConsoleHelper.Info("Test snapshots:"); if (fairy.sessionToEngine.Keys.Count > 0) { - Console.WriteLine("session\t\t\ttimestamp set for runtime (0 for current time)"); + Console.WriteLine("session\t\t\tRuntimeArgs"); foreach (string k in fairy.sessionToEngine.Keys) { - if (!fairy.sessionToTimestamp.TryGetValue(k, out timestamp)) - timestamp = 0; - ConsoleHelper.Info($"{k}\t\t\t{timestamp}"); + if (!fairy.sessionToRuntimeArgs.TryGetValue(k, out runtimeArgs)) + runtimeArgs = new Fairy.RuntimeArgs(); + ConsoleHelper.Info($"{k}\t\t\t{runtimeArgs.ToString()}"); } } else @@ -61,12 +61,12 @@ private void OnFairyCommand() ConsoleHelper.Info("Debug snapshots:"); if (fairy.debugSessionToEngine.Keys.Count > 0) { - Console.WriteLine("session\t\t\ttimestamp set for runtime (0 for current time)"); + Console.WriteLine("session\t\t\tRuntimeArgs"); foreach (string k in fairy.debugSessionToEngine.Keys) { - if (!fairy.sessionToTimestamp.TryGetValue(k, out timestamp)) - timestamp = 0; - ConsoleHelper.Info($"{k}\t\t\t{timestamp}"); + if (!fairy.sessionToRuntimeArgs.TryGetValue(k, out runtimeArgs)) + runtimeArgs = new Fairy.RuntimeArgs(); + ConsoleHelper.Info($"{k}\t\t\t{runtimeArgs.ToString()}"); } } else @@ -85,7 +85,7 @@ private void OnFairyCommand() string? testSession = null; foreach (string s in fairy.sessionToEngine.Keys) { - contractName = NativeContract.ContractManagement.GetContract(fairy.sessionToEngine[s].Snapshot, k).Manifest.Name; + contractName = NativeContract.ContractManagement.GetContract(fairy.sessionToEngine[s].Snapshot, k)?.Manifest.Name; if (contractName != null) { testSession = s;