diff --git a/Fairy.Debugger.DebugInfo.cs b/Fairy.Debugger.DebugInfo.cs index cf38699..01f43df 100644 --- a/Fairy.Debugger.DebugInfo.cs +++ b/Fairy.Debugger.DebugInfo.cs @@ -20,6 +20,7 @@ public struct SourceFilenameAndLineNum { public string sourceFilename; public ui public readonly ConcurrentDictionary contractScriptHashToNefDbgNfo = new(); struct DumpNefPatterns { + public DumpNefPatterns() { } public Regex opCodeRegex = new Regex(@"^(\d+)\s(.*?)\s?(#\s.*)?$"); // 8039 SYSCALL 62-7D-5B-52 # System.Contract.Call SysCall public Regex sourceCodeRegex = new Regex(@"^#\sCode\s(.*\.cs)\sline\s(\d+):\s""(.*)""$"); // # Code NFTLoan.cs line 523: "ExecutionEngine.Assert((bool)Contract.Call(token, "transfer", CallFlags.All, tenant, Runtime.ExecutingScriptHash, neededAmount, tokenId, TRANSACTION_DATA), "NFT payback failed");" public Regex methodStartRegex = new Regex(@"^# Method\sStart\s(.*)$"); // # Method Start NFTLoan.NFTLoan.FlashBorrowDivisible diff --git a/Fairy.Debugger.cs b/Fairy.Debugger.cs index b50e363..5046024 100644 --- a/Fairy.Debugger.cs +++ b/Fairy.Debugger.cs @@ -368,6 +368,14 @@ protected virtual JToken GetEvaluationStack(JArray _params) return new JArray(newEngine.InvocationStack.ElementAt(invocationStackIndex).EvaluationStack.Select(p => ToJson(p, settings.MaxIteratorResultItems))); } + [RpcMethod] + protected virtual JToken GetInvocationStack(JArray _params) + { + string session = _params[0].AsString(); + FairyEngine newEngine = sessionStringToFairySession[session].debugEngine; + return new JArray(newEngine.InvocationStack.Select(p => ToJson(p.InstructionPointer, settings.MaxIteratorResultItems))); + } + [RpcMethod] protected virtual JToken GetInstructionPointer(JArray _params) { diff --git a/Fairy.Tester.cs b/Fairy.Tester.cs index 9a3f36d..af196b8 100644 --- a/Fairy.Tester.cs +++ b/Fairy.Tester.cs @@ -38,6 +38,28 @@ protected virtual JObject InvokeFunctionWithSession(JArray _params) return GetInvokeResultWithSession(session, writeSnapshot, script, signers, witnesses); } + [RpcMethod] + protected virtual JObject InvokeManyWithSession(JArray _params) + { + string session = _params[0].AsString(); + bool writeSnapshot = _params[1].AsBoolean(); + Signer[]? signers = _params.Count >= 4 ? SignersFromJson((JArray)_params[3], system.Settings) : null; + Witness[]? witnesses = _params.Count >= 5 ? WitnessesFromJson((JArray)_params[4]) : null; + byte[] script = Array.Empty(); + using (ScriptBuilder sb = new()) + { + foreach (JArray invokeParams in (JArray)_params[2]) + { + UInt160 script_hash = UInt160.Parse(invokeParams[0].AsString()); + string operation = invokeParams[1].AsString(); + ContractParameter[] args = invokeParams.Count >= 3 ? ((JArray)invokeParams[2]).Select(p => ContractParameter.FromJson((JObject)p)).ToArray() : System.Array.Empty(); + sb.EmitDynamicCall(script_hash, operation, args); + } + script = sb.ToArray(); + } + return GetInvokeResultWithSession(session, writeSnapshot, script, signers, witnesses); + } + [RpcMethod] protected virtual JObject InvokeScriptWithSession(JArray _params) {