guillotine-rs

Crates.ioguillotine-rs
lib.rsguillotine-rs
version0.1.3
created_at2025-09-09 12:02:49.74115+00
updated_at2025-10-24 23:54:10.14102+00
descriptionHigh-performance REVM-compatible EVM execution backed by Zig's guillotine-mini engine with FFI integration
homepagehttps://github.com/evmts/guillotine-rs
repositoryhttps://github.com/evmts/guillotine-rs
max_upload_size
id1830687
size200,855
Will Cory (roninjin10)

documentation

https://docs.rs/guillotine-rs

README

REVM integration for guillotine

image

rust version build status tests

Requirements

  • Rust 1.75+ (Cargo)
  • Zig 0.15.1+ (Required for building guillotine-mini)
  • git (Required for submodule initialization)

Installing Zig

Zig is required to build the underlying EVM engine. Install it before building:

macOS:

brew install zig

Linux / Windows: Download from https://ziglang.org/download/

Verify installation:

zig version  # Should show 0.15.1 or later

Installation

WARNING: This repo is currently vibes and hasn't been reviewed by a human yet

Recommended: Build from source with git submodules

git clone --recursive https://github.com/evmts/guillotine-rs.git
cd guillotine-rs
cargo build --release

Alternative: Add to your Cargo.toml

[dependencies]
guillotine-rs = { git = "https://github.com/evmts/guillotine-rs", submodules = true }

Note: Installing directly from crates.io (cargo add guillotine-rs) is not currently supported due to git submodule dependencies. You must clone the repository with --recursive to include the guillotine-mini submodule.


Documentation

tests/ — Example code and usage

LLMS.txt — For LLMs

Overview

High-performance REVM execution backed by the Zig-based guillotine-mini engine. Thin Rust wrapper with FFI to Zig for execution, state sync, logs, refunds, and storage changes.

Architecture

  • Zig (lib/guillotine-mini) — core EVM, opcode handlers, storage manager
  • FFI layer (root_c.zig in guillotine-mini) — stable C ABI to create/destroy EVM, set contexts, execute, and extract results
  • Rust wrapper (src/guillotine_mini) — REVM adapter, type conversions, and state bridge

Key Features

  • REVM-compatible — Drop-in transaction execution with REVM's Context and TxEnv
  • Pre-state sync — Automatically syncs balances, nonces, code, and storage to guillotine-mini
  • Post-state extraction — Storage changes grouped by address/slot
  • Gas refunds — Direct exposure from guillotine-mini's runtime counter
  • Log emission — LOG0–LOG4 captured in Zig and returned as REVM logs
  • Typed errors — Proper error handling with EvmAdapterError<DbErr>

API

Legend: All FFI calls are wrapped with safe Rust interfaces

Error Handling

  • Reverts — Mapped to ExecutionResult::Revert { gas_used, output } (no panic)
  • Success — Returns ExecutionResult::Success { reason: Return, gas_used, gas_refunded, logs, output }
  • FFI failures — Properly propagated via EvmAdapterError::Ffi(&'static str)
  • Database errors — Wrapped in EvmAdapterError::Db(DbErr) and propagated
  • Catastrophic failures — Zig panic/unreachable causes process abort (by design)

Fallible constructor available: GuillotineMiniEvm::try_new(ctx) returns Result<Self, EvmAdapterError>. The new(ctx) constructor retains an assert on fatal creation failure for convenience.

Usage

use guillotine_rs::guillotine_mini::evm::GuillotineMiniEvm;
use revm::{
    context::Context,
    context_interface::result::ExecutionResult,
    database_interface::EmptyDB,
    primitives::{address, TxEnv, TxKind, U256},
};

// Create REVM context
let ctx = Context::mainnet().with_db(EmptyDB::default());
let mut evm = GuillotineMiniEvm::new(ctx);

// Build transaction
let tx = TxEnv::builder()
    .caller(address!("a94f5374fce5edbc8e2a8697c15331677e6ebf0b"))
    .kind(TxKind::Call(address!("0000000000000000000000000000000000000001")))
    .gas_limit(100_000)
    .build()
    .unwrap();

// Execute and get results
let result = evm.transact(tx).unwrap();
match result.result {
    ExecutionResult::Success { gas_used, gas_refunded, logs, output, .. } => {
        println!("Success! Gas used: {}, refunded: {}", gas_used, gas_refunded);
        println!("Logs: {}, Output: {:?}", logs.len(), output);
    }
    ExecutionResult::Revert { gas_used, output } => {
        println!("Reverted! Gas used: {}, Output: {:?}", gas_used, output);
    }
    _ => unreachable!(),
}

Testing

# Run all tests
cargo test

# Run specific test
cargo test test_simple_add

# Run with output
cargo test -- --nocapture

Test coverage:

Troubleshooting

Build Errors

"Zig compiler not found!"

# Install Zig 0.15.1 or later
brew install zig  # macOS
# or download from https://ziglang.org/download/

# Verify installation
zig version

"Zig version too old!"

# Upgrade to Zig 0.15.1+
brew upgrade zig  # macOS
# or download latest from https://ziglang.org/download/

"git submodule init failed"

# If you installed via cargo, clone manually instead:
git clone --recursive https://github.com/evmts/guillotine-rs
cd guillotine-rs
cargo build

"Failed to initialize submodules"

# Initialize submodules manually:
git submodule update --init --recursive
cargo build

"zig build failed"

Notes and Limits

  • Storage extraction enumerates final non-zero slots; zeroed slots are not emitted
  • Logs are emitted by Zig's LOG handlers and included in results
  • All hardforks from Frontier to Osaka are supported via REVM's SpecId mapping
  • Submodules required: This package uses git submodules and cannot be installed directly from crates.io. Use git installation method above.

More

Guillotine Mini — Minimal Zig EVM implementation

Primitives — Ethereum primitives and cryptography for Zig

REVM — Rust Ethereum Virtual Machine

Commit count: 0

cargo fmt