Exemple #1
0
        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);
        }
Exemple #2
0
        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));
        }
Exemple #3
0
        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);
        }