private static InvocationResult ExecuteFrame(IExecutionFrame frame) { var result = new InvocationResult(); ExecutionFrames.Push(frame); try { result.Status = frame.Execute(); if (result.Status == ExecutionStatus.Ok) { result.ReturnValue = frame.ReturnValue; } result.GasUsed = frame.GasUsed; } catch (OutOfGasException e) { result.GasUsed = e.GasUsed; result.Status = ExecutionStatus.GasOverflow; } catch (HaltException e) { result.Status = e.HaltCode == 0 ? ExecutionStatus.Ok : ExecutionStatus.ExecutionHalted; result.ReturnValue = e.HaltCode == 0 ? frame.ReturnValue : new[] { (byte)e.HaltCode }; result.GasUsed = frame.GasUsed; } catch (Exception e) { Logger.LogError($"Unknown exception in VM: {e}"); result.Status = ExecutionStatus.UnknownError; result.GasUsed = frame.GasUsed; } ExecutionFrames.Pop(); return(result); }
private static InvocationResult _InvokeSystemContract( InvocationContext context, UInt160 address, byte[] input, ulong gasLimit ) { var call = _contractRegisterer.DecodeContract(context, address, input); if (call is null) { return(InvocationResult.WithStatus(ExecutionStatus.ExecutionHalted)); } return(VirtualMachine.InvokeSystemContract(call, context, input, gasLimit)); }
public static InvocationResult InvokeSystemContract( SystemContractCall systemContractCall, InvocationContext context, byte[] input, ulong gasLimit ) { var status = FrameFactory.FromSystemContractCall( systemContractCall, context, input, out var rootFrame, gasLimit ); return(status == ExecutionStatus.Ok ? ExecuteFrame(rootFrame) : InvocationResult.WithStatus(status)); }
public static InvocationResult Invoke(UInt160 address, InvocationContext context, byte[] input, ulong gasLimit) { var systemContract = _contractRegisterer.GetContractByAddress(address); if (systemContract != null) { return(_InvokeSystemContract(context, address, input, gasLimit)); } var contract = context.Snapshot.Contracts.GetContractByHash(address); return(contract is null ? InvocationResult.WithStatus(ExecutionStatus.ContractNotFound) : VirtualMachine.InvokeWasmContract(contract, context, input, gasLimit)); }
public static InvocationResult InvokeWasmContract( Contract contract, InvocationContext context, byte[] input, ulong gasLimit ) { var status = FrameFactory.FromInvocation( contract.ByteCode, context, contract.ContractAddress, input, BlockchainInterface, out var rootFrame, gasLimit ); return(status == ExecutionStatus.Ok ? ExecuteFrame(rootFrame) : InvocationResult.WithStatus(status)); }