Skip to content

Commit

Permalink
book 📝 (bluealloy#494)
Browse files Browse the repository at this point in the history
* book 📝

initialization
intro + chapters
interpreter

* Gas + Memory

* added to examples and refactor

* precompiles

* Update primitives.md

* added docs through `instructions`

* book

- utilities
- revm
- restructure book for subchapters

* final touches

* Update SUMMARY.md reorder topics

Change order of book items

---------

Co-authored-by: Colin Roberts <[email protected]>
Co-authored-by: rakita <[email protected]>
  • Loading branch information
3 people authored Jun 18, 2023
1 parent 63f9460 commit 5ca4741
Show file tree
Hide file tree
Showing 40 changed files with 1,416 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ pkg/
bins/revme/temp_folder
bins/revme/tests
ethereumjs-util.js
book
6 changes: 6 additions & 0 deletions book.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[book]
authors = ["Colin, Waylon Jepsen"]
language = "en"
multilingual = false
src = "documentation/src"
title = "Rust EVM"
1 change: 1 addition & 0 deletions documentation/bins/revm-test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# revm-test
1 change: 1 addition & 0 deletions documentation/bins/revme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# revme
34 changes: 34 additions & 0 deletions documentation/src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Summary

- [Introduction](./introduction.md)
- [Revm](./crates/revm.md)
- [evm](./crates/revm/evm.md)
- [evm_impl](./crates/revm/evm_impl.md)
- [inspector](./crates/revm/inspector.md)
- [journaled_state](./crates/revm/journaled_state.md)
- [Interpreter](./crates/interpreter.md)
- [gas](./crates/interpreter/gas.md)
- [host](./crates/interpreter/host.md)
- [inner_models](./crates/interpreter/inner_models.md)
- [instruction_result](./crates/interpreter/instruction_result.md)
- [instructions](./crates/interpreter/instructions.md)
- [Examples](./examples.md)
- [Primitives](./crates/primitives.md)
- [database](./crates/primitives/database.md)
- [result](./crates/primitives/result.md)
- [environment](./crates/primitives/environment.md)
- [specifications](./crates/primitives/specifications.md)
- [bits](./crates/primitives/bits.md)
- [bytecode](./crates/primitives/bytecode.md)
- [constants](./crates/primitives/constants.md)
- [log](./crates/primitives/log.md)
- [precompile](./crates/primitives/precompile.md)
- [state](./crates/primitives/state.md)
- [utils](./crates/primitives/utils.md)
- [Precompile](./crates/precompile.md)
- [blake2](./crates/precompile/blake2.md)
- [bn128 curve](./crates/precompile/bn128.md)
- [Hash functions](./crates/precompile/hash.md)
- [Identity function](./crates/precompile/identity.md)
- [Modular Exponentiation](./crates/precompile/modexp.md)
- [Secp256k1](./crates/precompile/secp256k1.md)
1 change: 1 addition & 0 deletions documentation/src/bins/revm-test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# revm-test
1 change: 1 addition & 0 deletions documentation/src/bins/revme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# revme
26 changes: 26 additions & 0 deletions documentation/src/crates/interpreter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Interpreter

The `interpreter` crate is concerned with the execution of the EVM opcodes and serves as the event loop to step through the opcodes. The interpreter is concerned with attributes like gas, contracts, memory, stack, and returning execution results. It's structured as follows:

Modules:

- [gas](./interpreter/gas.md): This module deals with handling the gas mechanics in the EVM, such as calculating gas costs for operations.
- [host](./interpreter/host.md): This module defines the `Host` trait, and any types or functions that the host machine (the machine running the EVM).
- [inner_models](./interpreter/inner_models.md): Based on the name, this module could contain the inner data structures or models used in the EVM implementation.
- [instruction_result](./interpreter/instruction_result.md): This module likely contains definitions related to the result of instruction execution.
- [instructions](./interpreter/instructions.md): This module is expected to include the definitions of the EVM opcodes (instructions).
- [interpreter](./interpreter/interpreter.md): This module would contain the Interpreter struct and related functionality for executing EVM instructions.

External Crates:

- alloc: The alloc crate is used to provide the ability to allocate memory on the heap. It's a part of Rust's standard library that can be used in environments without a full host OS.
- core: The core crate is the dependency-free foundation of the Rust standard library. It includes fundamental types, macros, and traits.

Constants:

- `USE_GAS`: This constant determines whether gas measurement should be used. It's set to false if the no_gas_measuring feature is enabled.

Re-exported Types:
Several types and functions are re-exported for easier access by users of this library, such as Gas, Host, InstructionResult, OpCode, Interpreter, Memory, Stack, and others. This allows users to import these items directly from the library root instead of from their individual modules.
Re-exported Crate:
revm_primitives: This crate is re-exported, likely providing primitive types or functionality used in the EVM implementation.
47 changes: 47 additions & 0 deletions documentation/src/crates/interpreter/gas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# The `gas.rs` Module

The `gas.rs` module in this Rust EVM implementation manages the concept of "gas" within the Ethereum network. In Ethereum, "gas" signifies the computational effort needed to execute operations, whether a simple transfer of ether or the execution of a smart contract function. Each operation carries a gas cost, and transactions must specify the maximum amount of gas they are willing to consume.

## `Gas` Struct

The `Gas` struct represents the gas state for a particular operation or transaction. The struct is defined as follows:

```rust
#[derive(Clone, Copy, Debug)]
pub struct Gas {
/// Gas Limit
limit: u64,
/// used+memory gas.
all_used_gas: u64,
/// Used gas without memory
used: u64,
/// Used gas for memory expansion
memory: u64,
/// Refunded gas. This gas is used only at the end of execution.
refunded: i64,
}
```

### Fields in `Gas` Struct

- `limit`: The maximum amount of gas allowed for the operation or transaction.
- `all_used_gas`: The total gas used, inclusive of memory expansion costs.
- `used`: The gas used, excluding memory expansion costs.
- `memory`: The gas used for memory expansion.
- `refunded`: The gas refunded. Certain operations in Ethereum allow for gas refunds, up to half the gas used by a transaction.

## Methods of the `Gas` Struct

The `Gas` struct also includes several methods to manage the gas state. Here's a brief summary of their functions:

- `new`: Creates a new `Gas` instance with a specified gas limit and zero usage and refunds.
- `limit`, `memory`, `refunded`, `spend`, `remaining`: These getters return the current state of the corresponding field.
- `erase_cost`: Decreases the gas usage by a specified amount.
- `record_refund`: Increases the refunded gas by a specified amount.
- `record_cost`: Increases the used gas by a specified amount. It also checks for gas limit overflow. If the new total used gas would exceed the gas limit, it returns `false` and doesn't change the state.
- `record_memory`: This method works similarly to `record_cost`, but specifically for memory expansion gas. It only updates the state if the new memory gas usage is greater than the current usage.
- `gas_refund`: Increases the refunded gas by a specified amount.

## Importance of the `Gas` Struct

These features of the `Gas` struct allow for effective management and tracking of the gas cost associated with executing EVM operations. This is a key part of ensuring that smart contracts and transactions adhere to the resource constraints of the Ethereum network, since overconsumption of resources could potentially lead to network congestion.
43 changes: 43 additions & 0 deletions documentation/src/crates/interpreter/host.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# The `host.rs` Module

The `host.rs` module in this Rust EVM implementation defines a crucial trait `Host`. The `Host` trait outlines an interface for the interaction of the EVM interpreter with its environment (or "host"), encompassing essential operations such as account and storage access, creating logs, and invoking transactions.

## `Host` Trait

The `Host` trait provides the definition for all the methods that any EVM host must implement. It's a crucial bridge between the EVM and its environment, allowing the EVM to interact with blockchain state.

```rust
pub trait Host {
fn step(&mut self, interpreter: &mut Interpreter) -> InstructionResult;
fn step_end(
&mut self,
interpreter: &mut Interpreter,
ret: InstructionResult,
) -> InstructionResult;
// ... (other methods omitted for brevity)
}
```

## Key Methods of the `Host` Trait

- `step` & `step_end`: These methods manage the execution of EVM opcodes. The `step` method is invoked before executing an opcode, while `step_end` is invoked after. These methods can modify the EVM state or halt execution based on certain conditions.

- `env`: This method provides access to the EVM environment, including information about the current block and transaction.

- `load_account`: Retrieves information about a given Ethereum account.

- `block_hash`: Retrieves the block hash for a given block number.

- `balance`, `code`, `code_hash`, `sload`: These methods retrieve specific information (balance, code, code hash, and specific storage value) for a given Ethereum account.

- `sstore`: This method sets the value of a specific storage slot in a given Ethereum account.

- `log`: Creates a log entry with the specified address, topics, and data. Log entries are used by smart contracts to emit events.

- `selfdestruct`: Marks an Ethereum account to be self-destructed, transferring its funds to a target account.

- `create` & `call`: These methods handle the creation of new smart contracts and the invocation of smart contract functions, respectively.

## Importance of the `Host` Trait

The `Host` trait provides a standard interface that any host environment for the EVM must implement. This abstraction allows the EVM code to interact with the state of the Ethereum network in a generic way, thereby enhancing modularity and interoperability. Different implementations of the `Host` trait can be used to simulate different environments for testing or for connecting to different Ethereum-like networks.
94 changes: 94 additions & 0 deletions documentation/src/crates/interpreter/inner_models.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# The `inner_models.rs` Module in the Rust Ethereum Virtual Machine (EVM)

The `inner_models.rs` module within this Rust EVM implementation encompasses a collection of structs and enums that are used as internal models within the EVM. These models represent various aspects of EVM operations such as call and create inputs, call context, value transfers, and the result of self-destruction operations.

## `CallInputs` Struct

The `CallInputs` struct is used to encapsulate the inputs to a smart contract call in the EVM.

```rust
pub struct CallInputs {
pub contract: B160,
pub transfer: Transfer,
pub input: Bytes,
pub gas_limit: u64,
pub context: CallContext,
pub is_static: bool,
}
```

This struct includes the target contract address, the value to be transferred (if any), the input data, the gas limit for the call, the call context, and a boolean indicating if the call is a static call (a read-only operation).

## `CreateInputs` Struct

The `CreateInputs` struct encapsulates the inputs for creating a new smart contract.

```rust
pub struct CreateInputs {
pub caller: B160,
pub scheme: CreateScheme,
pub value: U256,
pub init_code: Bytes,
pub gas_limit: u64,
}
```

This includes the address of the creator, the creation scheme, the value to be transferred, the initialization code for the new contract, and the gas limit for the creation operation.

## `CallScheme` Enum

The `CallScheme` enum represents the type of call being made to a smart contract.

```rust
pub enum CallScheme {
Call,
CallCode,
DelegateCall,
StaticCall,
}
```

The different types of calls (`CALL`, `CALLCODE`, `DELEGATECALL`, `STATICCALL`) represent different modes of interaction with a smart contract, each with its own semantics concerning the treatment of the message sender, value transfer, and the context in which the called code executes.

## `CallContext` Struct

The `CallContext` struct encapsulates the context of a smart contract call.

```rust
pub struct CallContext {
pub address: B160,
pub caller: B160,
pub code_address: B160,
pub apparent_value: U256,
pub scheme: CallScheme,
}
```

This includes the executing contract's address, the caller's address, the address from which the contract code was loaded, the apparent value of the call (for `DELEGATECALL` and `CALLCODE`), and the call scheme.

## `Transfer` Struct

The `Transfer` struct represents a value transfer between two accounts.

```rust
pub struct Transfer {
pub source: B160,
pub target: B160,
pub value: U256,
}
```

## `SelfDestructResult` Struct

Finally, the `SelfDestructResult` struct captures the result of a self-destruction operation on a contract.

```rust
pub struct SelfDestructResult {
pub had_value: bool,
pub target_exists: bool,
pub is_cold: bool,
pub previously_destroyed: bool,
}
```

In summary, the `inner_models.rs` module provides several crucial data structures that facilitate the representation and handling of various EVM operations and their associated data within this Rust EVM implementation.
80 changes: 80 additions & 0 deletions documentation/src/crates/interpreter/instruction_result.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# The `instruction_result.rs` Module

The `instruction_result.rs` module of this Rust EVM implementation includes the definitions of the enumerations `InstructionResult` and `SuccessOrHalt`, which represent the possible outcomes of EVM instruction execution, and functions to work with these types.

## `InstructionResult` Enum

The `InstructionResult` enum categorizes the different types of results that can arise from executing an EVM instruction. This enumeration uses the `#[repr(u8)]` attribute, meaning its variants have an explicit storage representation of an 8-bit unsigned integer.

```rust
pub enum InstructionResult {
Continue = 0x00,
Stop = 0x01,
Return = 0x02,
SelfDestruct = 0x03,
Revert = 0x20,
CallTooDeep = 0x21,
OutOfFund = 0x22,
OutOfGas = 0x50,
// more variants...
}
```

The different instruction results represent outcomes such as successful continuation, stop, return, self-destruction, reversion, deep call, out of funds, out of gas, and various error conditions.

## `SuccessOrHalt` Enum

The `SuccessOrHalt` enum represents the outcome of a transaction execution, distinguishing successful operations, reversion, halting conditions, fatal external errors, and internal continuation.

```rust
pub enum SuccessOrHalt {
Success(Eval),
Revert,
Halt(Halt),
FatalExternalError,
InternalContinue,
}
```

It also provides several methods to check the kind of result and to extract the value of the successful evaluation or halt.

## `From<InstructionResult> for SuccessOrHalt` Implementation

This implementation provides a way to convert an `InstructionResult` into a `SuccessOrHalt`. It maps each instruction result to the corresponding `SuccessOrHalt` variant.

```rust
impl From<InstructionResult> for SuccessOrHalt {
fn from(result: InstructionResult) -> Self {
match result {
InstructionResult::Continue => Self::InternalContinue,
InstructionResult::Stop => Self::Success(Eval::Stop),
// more match arms...
}
}
}
```

## Macros for returning instruction results

Finally, the module provides two macros, `return_ok!` and `return_revert!`, which simplify returning some common sets of instruction results.

```rust
#[macro_export]
macro_rules! return_ok {
() => {
InstructionResult::Continue
| InstructionResult::Stop
| InstructionResult::Return
| InstructionResult::SelfDestruct
};
}

#[macro_export]
macro_rules! return_revert {
() => {
InstructionResult::Revert | InstructionResult::CallTooDeep | InstructionResult::OutOfFund
};
}
```

In summary, the `instruction_result.rs` module is essential to the interpretation of EVM instructions, as it outlines the possible outcomes and provides means to handle these outcomes within the Rust EVM implementation.
Loading

0 comments on commit 5ca4741

Please sign in to comment.