Skip to content

Commit d6aff66

Browse files
committed
documentation
1 parent 10fd265 commit d6aff66

18 files changed

+411
-14
lines changed

crates/config/src/error.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
1+
//! Error types for the configuration module
2+
13
use mesc::MescError;
24

5+
/// Errors that can occur during configuration operations
36
#[derive(Debug, thiserror::Error)]
47
pub enum Error {
8+
/// A generic error with a message
59
#[error("Error: {0}")]
610
Generic(String),
11+
12+
/// An error that occurred during parsing
713
#[error("Parse error: {0}")]
814
ParseError(String),
15+
16+
/// An error from the MESC (Modular Ethereum Signing Client) system
917
#[error("MESC error: {0}")]
1018
MescError(#[from] MescError),
1119
}

crates/config/src/lib.rs

+16
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
//! Configuration management for Heimdall
2+
//!
3+
//! This crate provides functionality for managing the Heimdall configuration,
4+
//! including loading, saving, updating, and deleting configuration settings.
5+
6+
/// Error types for the configuration module
17
pub mod error;
28

39
use crate::error::Error;
@@ -8,6 +14,7 @@ use serde::{Deserialize, Serialize};
814
use std::env::home_dir;
915
use tracing::{debug, error, info};
1016

17+
/// Command line arguments for the configuration command
1118
#[derive(Debug, Clone, Parser)]
1219
#[clap(
1320
about = "Display and edit the current configuration",
@@ -28,10 +35,19 @@ pub struct ConfigArgs {
2835
/// will attempt to read from this configuration when possible.
2936
#[derive(Deserialize, Serialize, Debug)]
3037
pub struct Configuration {
38+
/// The URL for the Ethereum RPC endpoint
3139
pub rpc_url: String,
40+
41+
/// The URL for a local Ethereum RPC endpoint
3242
pub local_rpc_url: String,
43+
44+
/// The API key for Etherscan services
3345
pub etherscan_api_key: String,
46+
47+
/// The API key for Transpose services
3448
pub transpose_api_key: String,
49+
50+
/// The API key for OpenAI services
3551
pub openai_api_key: String,
3652
}
3753

crates/vm/src/core/constants.rs

+15
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,27 @@ use std::str::FromStr;
44
use lazy_static::lazy_static;
55

66
lazy_static! {
7+
/// The address used for the coinbase in EVM execution.
8+
///
9+
/// In the Ethereum context, this would typically be the address of the miner/validator
10+
/// who receives the block reward. In Heimdall, this is a constant value used for
11+
/// consistency in simulation.
712
pub static ref COINBASE_ADDRESS: U256 =
813
U256::from_str("0x6865696d64616c6c00000000636f696e62617365")
914
.expect("failed to parse coinbase address");
15+
16+
/// The address used for standard contract creation (CREATE opcode).
17+
///
18+
/// This is a constant used when simulating the CREATE opcode's behavior
19+
/// in contract deployment scenarios.
1020
pub static ref CREATE_ADDRESS: U256 =
1121
U256::from_str("0x6865696d64616c6c000000000000637265617465")
1222
.expect("failed to parse create address");
23+
24+
/// The address used for CREATE2 contract creation.
25+
///
26+
/// This is a constant used when simulating the CREATE2 opcode's behavior,
27+
/// which allows for deterministic contract addresses based on deployment parameters.
1328
pub static ref CREATE2_ADDRESS: U256 =
1429
U256::from_str("0x6865696d64616c6c000000000063726561746532")
1530
.expect("failed to parse create2 address");

crates/vm/src/core/log.rs

+5
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@ use alloy::primitives::U256;
33
/// The [`Log`] struct represents a log emitted by a `LOG0-LOG4` opcode.
44
#[derive(Clone, Debug)]
55
pub struct Log {
6+
/// The index position of the log in the transaction
67
pub index: u128,
8+
9+
/// The log topics (up to 4 for LOG0-LOG4)
710
pub topics: Vec<U256>,
11+
12+
/// The raw data contained in the log
813
pub data: Vec<u8>,
914
}
1015

crates/vm/src/core/memory.rs

+12
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,18 @@ impl Memory {
107107
self.memory.splice(offset..offset.saturating_add(size), value);
108108
}
109109

110+
/// Stores a value in memory and records the opcode that performed the store operation
111+
///
112+
/// This method is similar to `store()` but additionally records which opcode
113+
/// was responsible for the memory store operation when the experimental feature
114+
/// is enabled.
115+
///
116+
/// # Arguments
117+
/// * `offset` - The byte offset in memory where the value will be stored
118+
/// * `size` - The size of the value in bytes
119+
/// * `value` - The value to store in memory
120+
/// * `opcode` - The opcode that performed the store operation (only used with experimental
121+
/// feature)
110122
pub fn store_with_opcode(
111123
&mut self,
112124
offset: usize,

crates/vm/src/core/mod.rs

+15
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
1+
/// Constants used throughout the VM implementation
12
pub mod constants;
3+
4+
/// Log implementation for event handling
25
pub mod log;
6+
7+
/// Memory implementation for VM memory management
38
pub mod memory;
9+
10+
/// Opcode definitions and implementations
411
pub mod opcodes;
12+
13+
/// Stack implementation for the VM
514
pub mod stack;
15+
16+
/// Storage implementation for contract storage
617
pub mod storage;
18+
19+
/// Common types and utilities for the VM
720
pub mod types;
21+
22+
/// Core virtual machine implementation
823
pub mod vm;

crates/vm/src/core/opcodes/mod.rs

+27-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
1-
//! Mostly adapted from https://github.com/bluealloy/revm
2-
3-
mod wrapped;
1+
//! EVM opcodes and related utilities.
2+
//!
3+
//! This module provides functionality for working with EVM opcodes, including:
4+
//! - Opcode information (names, gas costs, stack effects)
5+
//! - Wrapped opcode structures for tracking data flow
6+
//! - Various utility functions for working with opcodes
7+
//!
8+
//! The implementation is partially adapted from https://github.com/bluealloy/revm
9+
10+
/// Re-export wrapped opcode module that provides structures for tracking opcode operations
11+
/// and their relationships in data flow analysis.
12+
pub mod wrapped;
413
use paste::paste;
514
pub use wrapped::*;
615

@@ -136,6 +145,21 @@ macro_rules! opcodes {
136145
// each input MUST implement the `Into<WrappedOpcode>` trait
137146
$(
138147
paste!{
148+
/// A macro that creates a wrapped opcode with the given inputs.
149+
///
150+
/// This macro provides a convenient way to construct a `WrappedOpcode` for a specific
151+
/// opcode (`$name`), supporting between 0 and 8 input arguments that implement
152+
/// `Into<WrappedInput>`.
153+
///
154+
/// # Examples
155+
///
156+
/// ```
157+
/// // Create an ADD opcode with two inputs
158+
/// let add_op = w_add!(value1, value2);
159+
///
160+
/// // Create a MSTORE opcode with memory offset and value
161+
/// let mstore_op = w_mstore!(offset, value);
162+
/// ```
139163
#[macro_export]
140164
macro_rules! [<w_$name:lower>] {
141165
// zero inputs

crates/vm/src/core/opcodes/wrapped.rs

+133-7
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,85 @@ use alloy::primitives::U256;
22

33
use crate::core::opcodes::opcode_name;
44

5-
/// A WrappedInput can contain either a raw U256 value or a WrappedOpcode
5+
/// A [`WrappedInput`] can contain either a raw [`U256`] value or a [`WrappedOpcode`].
6+
///
7+
/// This enum is used to represent inputs to EVM opcodes, allowing inputs to be
8+
/// either constant values or the results of previous operations in the execution flow.
69
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
710
pub enum WrappedInput {
8-
/// A raw value input
11+
/// A raw value input (typically from a PUSH instruction)
912
Raw(U256),
10-
/// An opcode input
13+
/// An opcode result as input (indicating data dependency)
1114
Opcode(WrappedOpcode),
1215
}
1316

14-
/// A WrappedOpcode is an Opcode with its inputs wrapped in a WrappedInput
17+
/// A [`WrappedOpcode`] is an EVM opcode with its inputs wrapped in a [`WrappedInput`].
18+
///
19+
/// This structure is used to represent opcodes and their arguments in a way
20+
/// that can capture the relationships between operations, allowing for analysis
21+
/// of execution flow and dependencies.
1522
#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)]
1623
pub struct WrappedOpcode {
24+
/// The opcode value as a byte.
25+
///
26+
/// This corresponds to the actual EVM opcode (e.g., 0x01 for ADD).
1727
pub opcode: u8,
28+
29+
/// The inputs for this opcode, wrapped to preserve their source context.
30+
///
31+
/// For example, an ADD opcode would typically have two inputs, which could be
32+
/// either raw values or the results of other operations.
1833
pub inputs: Vec<WrappedInput>,
1934
}
2035

2136
impl WrappedOpcode {
22-
/// Returns the maximum recursion depth of its inputs
37+
/// Returns the maximum recursion depth of its inputs.
38+
///
39+
/// The depth is calculated as the maximum depth of any input plus 1.
40+
/// A depth of 1 means the opcode has only raw inputs (or no inputs).
41+
/// Greater depths indicate a chain of operations.
42+
///
43+
/// ```
44+
/// use heimdall_vm::core::opcodes::wrapped::{WrappedOpcode, WrappedInput};
45+
/// use alloy::primitives::U256;
46+
/// use heimdall_vm::ext::lexers::solidity::WrappedOpcode;
47+
///
48+
/// // Create a PUSH1 0x01 operation
49+
/// let push1 = WrappedOpcode::new(0x60, vec![WrappedInput::Raw(U256::from(1))]);
50+
/// assert_eq!(push1.depth(), 1); // Depth is 1 because it has only raw inputs
51+
///
52+
/// // Create an ADD operation that takes the result of two PUSH operations
53+
/// let add = WrappedOpcode::new(0x01, vec![
54+
/// WrappedInput::Opcode(push1.clone()),
55+
/// WrappedInput::Opcode(push1.clone())
56+
/// ]);
57+
/// assert_eq!(add.depth(), 2); // Depth is 2 because it contains operations with depth 1
58+
/// ```
2359
pub fn depth(&self) -> u32 {
2460
self.inputs.iter().map(|x| x.depth()).max().unwrap_or(0) + 1
2561
}
2662
}
2763

2864
impl std::fmt::Display for WrappedOpcode {
65+
/// Formats the [`WrappedOpcode`] as a string.
66+
///
67+
/// The format is: `OPCODENAME(input1, input2, ...)` where each input is
68+
/// formatted according to its own [`Display`] implementation.
69+
///
70+
/// ```
71+
/// use heimdall_vm::core::opcodes::wrapped::{WrappedOpcode, WrappedInput};
72+
/// use heimdall_vm::ext::lexers::solidity::WrappedOpcode;
73+
/// use alloy::primitives::U256;
74+
///
75+
/// let push1 = WrappedOpcode::new(0x60, vec![WrappedInput::Raw(U256::from(1))]);
76+
/// assert_eq!(push1.to_string(), "PUSH1(1)");
77+
///
78+
/// let add = WrappedOpcode::new(0x01, vec![
79+
/// WrappedInput::Opcode(push1.clone()),
80+
/// WrappedInput::Opcode(push1.clone())
81+
/// ]);
82+
/// assert_eq!(add.to_string(), "ADD(PUSH1(1), PUSH1(1))");
83+
/// ```
2984
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3085
write!(
3186
f,
@@ -37,9 +92,28 @@ impl std::fmt::Display for WrappedOpcode {
3792
}
3893

3994
impl WrappedInput {
40-
/// Returns the depth of the input \
95+
/// Returns the depth of the input.
96+
///
97+
/// - 0 for a raw [`U256`] value
98+
/// - The depth of the contained [`WrappedOpcode`] for an opcode input
99+
///
100+
/// This method is used to calculate the recursive depth of operations
101+
/// for analysis and optimization purposes.
102+
///
103+
/// ```
104+
/// use heimdall_vm::core::opcodes::wrapped::WrappedInput;
105+
/// use heimdall_vm::ext::lexers::solidity::WrappedOpcode;
106+
/// use alloy::primitives::U256;
41107
///
42-
/// i.e. 0 for a raw U256 and the maximum recursion depth for a WrappedOpcode
108+
/// // Raw inputs have depth 0
109+
/// let raw = WrappedInput::Raw(U256::from(42));
110+
/// assert_eq!(raw.depth(), 0);
111+
///
112+
/// // Opcode inputs have the depth of the operation they contain
113+
/// let push1 = WrappedOpcode::new(0x60, vec![WrappedInput::Raw(U256::from(1))]);
114+
/// let op_input = WrappedInput::Opcode(push1);
115+
/// assert_eq!(op_input.depth(), 1);
116+
/// ```
43117
pub fn depth(&self) -> u32 {
44118
match self {
45119
WrappedInput::Raw(_) => 0,
@@ -49,6 +123,23 @@ impl WrappedInput {
49123
}
50124

51125
impl std::fmt::Display for WrappedInput {
126+
/// Formats the [`WrappedInput`] as a string.
127+
///
128+
/// - For [`Raw`] inputs, displays the contained [`U256`] value.
129+
/// - For [`Opcode`] inputs, recursively formats the contained [`WrappedOpcode`].
130+
///
131+
/// ```
132+
/// use heimdall_vm::core::opcodes::wrapped::WrappedInput;
133+
/// use heimdall_vm::ext::lexers::solidity::WrappedOpcode;
134+
/// use alloy::primitives::U256;
135+
///
136+
/// let raw = WrappedInput::Raw(U256::from(42));
137+
/// assert_eq!(raw.to_string(), "42");
138+
///
139+
/// let push1 = WrappedOpcode::new(0x60, vec![WrappedInput::Raw(U256::from(1))]);
140+
/// let op_input = WrappedInput::Opcode(push1);
141+
/// assert_eq!(op_input.to_string(), "PUSH1(1)");
142+
/// ```
52143
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53144
match self {
54145
WrappedInput::Raw(u256) => write!(f, "{u256}"),
@@ -58,12 +149,47 @@ impl std::fmt::Display for WrappedInput {
58149
}
59150

60151
impl From<U256> for WrappedInput {
152+
/// Converts a [`U256`] value into a [`WrappedInput::Raw`].
153+
///
154+
/// This implementation allows for more ergonomic code when creating
155+
/// [`WrappedInput`]s from raw values.
156+
///
157+
/// ```
158+
/// use heimdall_vm::core::opcodes::wrapped::WrappedInput;
159+
/// use alloy::primitives::U256;
160+
///
161+
/// let u256_val = U256::from(42);
162+
/// let input: WrappedInput = u256_val.into();
163+
///
164+
/// match input {
165+
/// WrappedInput::Raw(val) => assert_eq!(val, U256::from(42)),
166+
/// _ => panic!("Expected Raw variant"),
167+
/// }
168+
/// ```
61169
fn from(val: U256) -> Self {
62170
WrappedInput::Raw(val)
63171
}
64172
}
65173

66174
impl From<WrappedOpcode> for WrappedInput {
175+
/// Converts a [`WrappedOpcode`] into a [`WrappedInput::Opcode`].
176+
///
177+
/// This implementation allows for more ergonomic code when creating
178+
/// [`WrappedInput`]s from operations.
179+
///
180+
/// ```
181+
/// use heimdall_vm::core::opcodes::wrapped::WrappedInput;
182+
/// use heimdall_vm::ext::lexers::solidity::WrappedOpcode;
183+
/// use alloy::primitives::U256;
184+
///
185+
/// let push1 = WrappedOpcode::new(0x60, vec![WrappedInput::Raw(U256::from(1))]);
186+
/// let input: WrappedInput = push1.clone().into();
187+
///
188+
/// match input {
189+
/// WrappedInput::Opcode(op) => assert_eq!(op, push1),
190+
/// _ => panic!("Expected Opcode variant"),
191+
/// }
192+
/// ```
67193
fn from(val: WrappedOpcode) -> Self {
68194
WrappedInput::Opcode(val)
69195
}

0 commit comments

Comments
 (0)