public void OnPersist(Snapshot snapshot, IReadOnlyList <Blockchain.ApplicationExecuted> applicationExecutedList) { _height = snapshot.Height; if (DebuggerActive) { foreach (Blockchain.ApplicationExecuted a in applicationExecutedList) { ApplicationExecutionResult r = a.ExecutionResults[0]; InvocationTransaction tx = (InvocationTransaction)a.Transaction; using (Snapshot newsnapshot = Blockchain.Singleton.GetSnapshot()) { using (_engine = new ApplicationEngine(TriggerType.Application, tx, newsnapshot, tx.Gas, false)) { _engine.LoadScript(tx.Script); _debugger = new Debugger(_engine); _lineOffset = 0; Execute(r); } } } } }
public bool Execute(ApplicationExecutionResult r) { bool reportResults = false; try { _continue = true; while (true) { if (DebuggerActive) { InvocationTransaction tx = (InvocationTransaction)_engine.ScriptContainer; // Script:offset breakpoint UInt160 scripthash = new UInt160(_engine.CurrentContext.ScriptHash); uint pos = (uint)_engine.CurrentContext.InstructionPointer; if (_continue && _script_break_points.TryGetValue(scripthash, out HashSet <uint> hashset) && hashset.Contains(pos)) { Console.WriteLine($"Breakpoint hit at script {scripthash.ToString()}:{pos}"); Console.WriteLine($"Block: {_height}"); Console.WriteLine($"Tx: {tx.Hash.ToString()}"); PrintNext(); _continue = false; reportResults = true; } if (_engine.CurrentContext.InstructionPointer == 0) { // Transaction breakpoint if (_continue && _tx_break_points.Contains(tx.Hash)) { Console.WriteLine($"Breakpoint hit at tx {tx.Hash.ToString()}"); Console.WriteLine($"Block: {_height}"); PrintNext(); _continue = false; reportResults = true; } // Block height breakpoint else if (_continue && _block_break_points.Contains(_height)) { Console.WriteLine($"Breakpoint hit at block {_height}"); Console.WriteLine($"Tx: {tx.Hash.ToString()}"); PrintNext(); _continue = false; reportResults = true; } } } SpinWait.SpinUntil(() => _continue == true); StepInto(false); if (_engine.State.HasFlag(VMState.HALT) || _engine.State.HasFlag(VMState.FAULT)) { break; } } } catch (Exception ex) { //Console.WriteLine($"Execute() failed: {ex}"); //_engine.State |= VMState.FAULT; } if (reportResults) { Console.WriteLine("Debug execution results:"); Console.WriteLine($"VMState = {_engine.State}"); Console.WriteLine($"GasConsumed = {_engine.GasConsumed}"); Console.WriteLine("EvaluationStack = "); DumpStack(_engine.ResultStack); Console.WriteLine($"Notifications = "); foreach (NotifyEventArgs n in _engine.Service.Notifications) { Console.WriteLine(ItemToJson(n.State)); } Console.WriteLine("Real execution results:"); Console.Write($"VMState = {r.VMState},"); Console.Write($"GasConsumed = {r.GasConsumed},"); Console.Write($"Stack = {r.Stack.Count()} items,"); Console.WriteLine($"Notifications = {r.Notifications.Count()} items"); } return(!_engine.State.HasFlag(VMState.FAULT)); }