private void ExecuteInternal(State state, EVMMessage message) { // Obtain the code from our account if it's not a precompile address we're calling. byte[] codeSegment = null; if (!EVMPrecompiles.IsPrecompileAddress(message.CodeAddress)) { codeSegment = state.GetCodeSegment(message.CodeAddress); } // Execute on it ExecuteInternal(state, message, codeSegment); }
public static EVMExecutionResult Execute(State state, EVMMessage message) { // Obtain the code from our account if it's not a precompile address we're calling. byte[] codeSegment = null; if (!EVMPrecompiles.IsPrecompileAddress(message.CodeAddress)) { codeSegment = state.GetCodeSegment(message.CodeAddress); } // Execute on it return(Execute(state, message, codeSegment)); }
private void ExecuteInternal(State state, EVMMessage message, Memory <byte> code) { // Set our current state and message State = state; Message = message; // Create a fresh execuction state. ExecutionState = new EVMExecutionState(this); GasState = new EVMGasState(Message.Gas); Code = code; // Record our call's execution start State.Configuration.DebugConfiguration.RecordExecutionStart(this); // We'll want to wrap our actual execution in a try block to catch any internal VM exceptions specifically bool isPrecompile = EVMPrecompiles.IsPrecompileAddress(Message.CodeAddress); bool threwException = false; try { // Check if address is in precompiles. If so, we execute precompile instead of the provided code. if (isPrecompile) { // Execute our precompiled code. EVMPrecompiles.ExecutePrecompile(this, Message.CodeAddress); } else { // Register our code coverage for this contract (if we're not mining). CoverageMap = State.Configuration.CodeCoverage.Register(Message, Code); // Execute until we have an execution result. while (ExecutionState.Result == null) { // Run another instruction. Step(); } } } catch (Exception exception) { // Record our exception. If we're not a precompile, we mark it as being an in-contract-execution exception. State.Configuration.DebugConfiguration.RecordException(exception, true); // If our exception is an evm exception, we set our execution result. if (exception is EVMException) { // An internal VM exception occurred, we'll want to return nothing, burn all the gas, and revert any changes. ExecutionState.Result = new EVMExecutionResult(this, null, 0, false); } else { // If it's any other type of exception, throw it. throw; } threwException = true; } // If we didn't succeed, record an exception indicating we failed and will revert. if (State.Configuration.DebugConfiguration.ThrowExceptionOnFailResult && !ExecutionState.Result.Succeeded && !threwException) { State.Configuration.DebugConfiguration.RecordException(new Exception("Execution returned a failed result. REVERTING..."), true); } // Record our call's execution end State.Configuration.DebugConfiguration.RecordExecutionEnd(this); }