/// <summary> /// Constructor /// </summary> /// <param name="e">Arguments</param> public ExecutionEngine(ExecutionEngineArgs e) : base(e) { _interopCache = new List <InteropCacheEntry>(); _interopCacheIndex = new List <object>(); _internalInvokeInterop = new NeoVM.InvokeInteropCallback(InternalInvokeInterop); _internalLoadScript = new NeoVM.LoadScriptCallback(InternalLoadScript); _internalGetMessage = new NeoVM.GetMessageCallback(InternalGetMessage); _handle = NeoVM.ExecutionEngine_Create ( _internalInvokeInterop, _internalLoadScript, _internalGetMessage, out IntPtr invHandle, out IntPtr resHandle ); if (_handle == IntPtr.Zero) { throw new ExternalException(); } _invocationStack = new ExecutionContextStack(this, invHandle); _resultStack = new StackItemStack(this, resHandle); if (Logger != null) { if (Logger.Verbosity.HasFlag(ELogVerbosity.StepInto)) { _internalOnStepInto = new NeoVM.OnStepIntoCallback(InternalOnStepInto); NeoVM.ExecutionEngine_AddLog(_handle, _internalOnStepInto); } } }
public void TestParallel() { var args = new ExecutionEngineArgs() { ScriptTable = new DummyScriptTable ( new byte[] { (byte)EVMOpCode.EQUAL }, new byte[] { (byte)EVMOpCode.EQUAL } ) }; // 5 Scripts var engines = new List <IExecutionEngine>() { CreateEngine(args), CreateEngine(args), CreateEngine(args), CreateEngine(args), CreateEngine(args), CreateEngine(args), CreateEngine(args), CreateEngine(args), CreateEngine(args), CreateEngine(args) }; Parallel.ForEach(engines, (engine) => { using (engine) { for (ushort x = 0; x < 1000; x++) { // Load script engine.Clean(x); using (var script = new ScriptBuilder()) { script.EmitPush(x); script.EmitPush(x); script.EmitAppCall(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, }); engine.LoadScript(script); } // Execute Assert.IsTrue(engine.Execute()); // Check result Assert.IsTrue(engine.ResultStack.TryPop(out bool var) && var); }
public ApplicationEngine(ExecutionEngineArgs args) : base(args) { _isDisposed = false; _gasConsumed = _gasAmount = 0; _state = EVMState.None; _scriptTable = new List <byte[]>(); _contractScriptTable = new ContractScriptTable(args.ScriptTable); _engine = new ExecutionEngine( new ScriptContainerWrapper(args.MessageProvider), _crypto, _contractScriptTable, new InteropServiceAdapter(this, args.InteropService)); _resultStack = new StackWrapper(_engine.ResultStack); _invocationStack = new StackExecutionContextWrapper(_engine.InvocationStack); }
private static ExecutionEngineArgs GetExecutionEngineArgs(IContainer container, IMessageProvider messageProvider) { var args = new ExecutionEngineArgs { Trigger = ETriggerType.Application, InteropService = container.Resolve <InteropService>(), ScriptTable = container.Resolve <IScriptTable>(), MessageProvider = messageProvider, Logger = container.Resolve <ExecutionEngineLogger>() }; var logger = container.Resolve <ILogger <ExecutionEngineLogger> >(); args.InteropService.OnLog += (s, e) => logger.LogDebug("Log: " + e.Message); args.InteropService.OnNotify += (s, e) => logger.LogDebug("Notification: " + e.State.ToString()); args.Logger.OnStepInto += ctx => logger.LogDebug(ctx.ToString()); return(args); }
public virtual void Setup() { if (!NeoSharp.VM.Interop.NeoVM.IsLoaded) { NeoSharp.VM.Interop.NeoVM.TryLoadLibrary(NeoSharp.VM.Interop.NeoVM.DefaultLibraryName, out var error); } _HyperVM = new NeoVM(); _crypto = Cryptography.Crypto.Default; _args = new ExecutionEngineArgs() { Trigger = ETriggerType.Application, InteropService = null, Logger = null, MessageProvider = null, ScriptTable = null }; }
/// <summary> /// Constructor /// </summary> /// <param name="e">Arguments</param> public ExecutionEngine(ExecutionEngineArgs e) : base(e) { _InternalInvokeInterop = new NeoVM.InvokeInteropCallback(InternalInvokeInterop); _InternalLoadScript = new NeoVM.LoadScriptCallback(InternalLoadScript); _InternalGetMessage = new NeoVM.GetMessageCallback(InternalGetMessage); InteropCache = new List <object>(); Handle = NeoVM.ExecutionEngine_Create ( _InternalInvokeInterop, _InternalLoadScript, _InternalGetMessage, out IntPtr invHandle, out IntPtr resHandle ); if (Handle == IntPtr.Zero) { throw (new ExternalException()); } _InvocationStack = new ExecutionContextStack(this, invHandle); _ResultStack = new StackItemStack(this, resHandle); if (Logger != null) { if (Logger.Verbosity.HasFlag(ELogVerbosity.StepInto)) { _InternalOnStepInto = new NeoVM.OnStepIntoCallback(InternalOnStepInto); NeoVM.ExecutionEngine_AddLog(Handle, _InternalOnStepInto); } if (Logger.Verbosity.HasFlag(ELogVerbosity.ExecutionContextStackChanges)) { _InternalOnExecutionContextChange = new NeoVM.OnStackChangeCallback(InternalOnExecutionContextChange); NeoVM.ExecutionContextStack_AddLog(invHandle, _InternalOnExecutionContextChange); } if (Logger.Verbosity.HasFlag(ELogVerbosity.ResultStackChanges)) { _InternalOnResultStackChange = new NeoVM.OnStackChangeCallback(InternalOnResultStackChange); NeoVM.StackItems_AddLog(resHandle, _InternalOnResultStackChange); } } }
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()); }
/// <summary> /// Create new Execution Engine /// </summary> /// <param name="e">Arguments</param> public IExecutionEngine Create(ExecutionEngineArgs e) { return(new ExecutionEngine(e)); }
/// <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}: "); } } } } }
public ExecutionEngineBase Create(ExecutionEngineArgs args) { return(new ApplicationEngine(args)); }
public void TestSmartVote(byte[] script) { const string VoteId = "q01"; // Create arguments var args = new ExecutionEngineArgs() { InteropService = new DummyInteropService(), ScriptTable = new DummyScriptTable(), Trigger = ETriggerType.Application, MessageProvider = new DummyMessageProvider(), Logger = new ExecutionEngineLogger(ELogVerbosity.None) }; args.Logger.OnStepInto += (context) => { Console.WriteLine(context.ToString()); }; args.InteropService.OnLog += (sender, e) => { Console.WriteLine("Log: " + e.Message); }; args.InteropService.OnNotify += (sender, e) => { Console.WriteLine("Notification: " + e.State.ToString()); }; using (var arguments = new ScriptBuilder()) using (var engine = CreateEngine(args)) // for (int x = 0; x < 5000; x++) // Benchmark { // Register proposal Console.WriteLine("** Register proposal **" + Environment.NewLine); arguments.EmitMainPush("register_proposal", new object[] { VoteId, "My proposal", new byte[20], new byte[20] }); engine.Clean(0); int scriptIndex = engine.LoadScript(script); engine.LoadScript(arguments); // Execute Assert.IsTrue(engine.Execute()); using (var item = engine.ResultStack.Pop <IntegerStackItem>()) { Assert.AreEqual(item.Value, 0x01); } CheckClean(engine); // Vote Console.WriteLine(Environment.NewLine + "** Vote **" + Environment.NewLine); arguments.Clear(); arguments.EmitMainPush("vote", new object[] { VoteId, new byte[20], 1 }); engine.Clean(1); Assert.IsTrue(engine.LoadScript(scriptIndex)); engine.LoadScript(arguments); // Execute Assert.IsTrue(engine.Execute()); using (var item = engine.ResultStack.Pop <IntegerStackItem>()) { Assert.AreEqual(item.Value, 0x01); } CheckClean(engine); // Count Console.WriteLine(Environment.NewLine + "** Count **" + Environment.NewLine); arguments.Clear(); arguments.EmitMainPush("count", new object[] { VoteId }); engine.Clean(2); Assert.IsTrue(engine.LoadScript(scriptIndex)); engine.LoadScript(arguments); // Execute Assert.IsTrue(engine.Execute()); using (var item = engine.ResultStack.Pop <IntegerStackItem>()) { Assert.AreEqual(item.Value, 0x01); } CheckClean(engine); } }