public void TestInvoke(UInt160 contractHash, ETriggerType trigger, string operation = null, [PromptCommandParameterBody] object[] parameters = null) { if (_scriptTable.GetScript(contractHash.ToArray(), false) == null) { throw new ArgumentNullException("Contract not found"); } var args = new ExecutionEngineArgs { ScriptTable = _scriptTable, Logger = new ExecutionEngineLogger(ELogVerbosity.StepInto), Trigger = trigger }; var log = new StringBuilder(); args.Logger.OnStepInto += context => { log.AppendLine(context.NextInstruction.ToString()); }; using (var script = new ScriptBuilder()) using (var vm = _vmFactory.Create(args)) { script.EmitMainPush(operation, parameters); script.EmitAppCall(contractHash.ToArray()); vm.LoadScript(script); var ret = vm.Execute(); var result = new { vm.State, Result = vm.ResultStack, vm.ConsumedGas }; _consoleHandler.WriteObject(result, PromptOutputStyle.json); } //_logger.LogDebug("Execution opcodes:" + Environment.NewLine + log.ToString()); }
public Task Persist(InvocationTransaction transaction) { var messageContainer = _container.Resolve <IMessageContainer>(); var executionEngineArgs = GetExecutionEngineArgs(_container, messageContainer); PrepareMessage(transaction, messageContainer); using (var engine = _vmFactory.Create(executionEngineArgs)) { engine.GasAmount = (ulong)transaction.Gas.Value; engine.LoadScript(transaction.Script); if (!engine.Execute()) { throw new InvalidOperationException($"The transaction {transaction.Hash} cannot be executed by VM."); } } return(Task.CompletedTask); }
/// <summary> /// Create new Engine /// </summary> /// <param name="args">Arguments</param> /// <returns>Return new engine</returns> public ExecutionEngineBase CreateEngine(ExecutionEngineArgs args) { return(_VMFactory.Create(args)); }
/// <summary> /// Execute this test /// </summary> /// <param name="factory">Factory</param> /// <param name="ut">Test</param> public void ExecuteTest(IVMFactory factory, VMUT ut) { foreach (var test in ut.Tests) { // Arguments var storages = new ManualStorage(); var interopService = new InteropService(); var contracts = new ManualContracts(); var state = new StateMachine ( null, null, null, contracts, storages, interopService, null, null, null, test.Trigger ); var args = new ExecutionEngineArgs() { Trigger = test.Trigger, InteropService = interopService, Logger = new ExecutionEngineLogger(ELogVerbosity.StepInto), ScriptTable = contracts, }; var log = new StringBuilder(); var logBag = new List <string>(); var notBag = new List <JToken>(); interopService.OnLog += (sender, e) => { logBag.Add(e.Message); }; interopService.OnNotify += (sender, e) => { notBag.Add(ItemToJson(e.State)); }; args.Logger.OnStepInto += (context) => { log.AppendLine(context.InstructionPointer.ToString("x6") + " - " + context.NextInstruction); }; interopService.OnSysCall += (o, e) => { // Remove last line log.Remove(log.Length - Environment.NewLine.Length, Environment.NewLine.Length); log.AppendLine($" [{e.MethodName} - {e.Result}]"); }; // Script table if (test.ScriptTable != null) { foreach (var script in test.ScriptTable) { var contract = new Contract() { Code = new Code() { Script = script.Script, ScriptHash = script.Script.ToScriptHash(), Metadata = ContractMetadata.NoProperty } }; if (script.HasDynamicInvoke) { contract.Code.Metadata |= ContractMetadata.HasDynamicInvoke; } if (script.HasStorage) { contract.Code.Metadata |= ContractMetadata.HasStorage; } if (script.Payable) { contract.Code.Metadata |= ContractMetadata.Payable; } contracts.Add(contract.ScriptHash, contract); } contracts.Commit(); } // Create engine using (var engine = factory.Create(args)) { engine.GasAmount = ulong.MaxValue; engine.LoadScript(test.Script); // Execute Steps if (test.Steps != null) { foreach (var step in test.Steps) { // Actions log.Clear(); logBag.Clear(); notBag.Clear(); foreach (var run in step.Actions) { switch (run) { case VMUTActionType.Execute: engine.Execute(); break; case VMUTActionType.StepInto: engine.StepInto(); break; case VMUTActionType.StepOut: engine.StepOut(); break; case VMUTActionType.StepOver: engine.StepOver(); break; case VMUTActionType.Clean: engine.Clean(); break; } } // Review results var add = string.IsNullOrEmpty(step.Name) ? "" : "-" + step.Name; AssertResult(engine, step.State, logBag, notBag, $"{ut.Category}-{ut.Name}{add}: "); } } } } }