Execution
Ashen executes smart contracts in a deterministic RISC-V virtual machine with tiered execution (interpreter, JIT, AOT) and metered gas accounting.
Overview
Section titled “Overview”The execution layer provides:
- Deterministic RISC-V VM - RV64IMC + Zba/Zbb, no floating-point
- Tiered Execution - Interpreter → Baseline JIT → Optimizing JIT/AOT
- Metered Gas - Per-instruction accounting with identical costs across tiers
- Sandboxed Isolation - Memory safety, no shared state between contracts
Transaction Flow
Section titled “Transaction Flow”┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐│ Validate │ → │ Gas Debit │ → │ Execute │ → │ Commit ││ sig/nonce │ │ reserve │ │ RISC-V VM │ │ or revert │└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘- Validation - Check ed25519 signature, nonce, gas limit, balance
- Gas Debit - Reserve
gas_limitfrom payer account - Execution - Run contract in RISC-V VM (tier selected automatically)
- Gas Refund - Return unused gas to payer
- Fee Distribution - Credit consumed gas to block proposer
RISC-V Instruction Set
Section titled “RISC-V Instruction Set”Contracts target a deterministic RISC-V profile:
| Extension | Status | Purpose |
|---|---|---|
| RV64I | ✅ Enabled | Base 64-bit integer instructions |
| M | ✅ Enabled | Multiply/divide |
| C | ✅ Enabled | Compressed instructions (smaller code) |
| Zba/Zbb | ✅ Enabled | Bit manipulation |
| F/D/Q | ❌ Disabled | Floating-point (use fixed-point instead) |
| A | ❌ Disabled | Atomics (no threads in contracts) |
| V | ❌ Disabled | Vector operations |
Target triple: riscv64-unknown-elf with +m,+c,+zba,+zbb,-a,-f,-d
Execution Tiers
Section titled “Execution Tiers”The VM uses tiered execution to balance startup latency with steady-state performance:
┌─────────────────┐ │ Interpreter │ ← All contracts start here │ (reference) │ └────────┬────────┘ │ hot (>10M gas or >20 calls) ▼ ┌─────────────────┐ │ Baseline JIT │ ← Fast compile, 5x speedup │ (Tier 1) │ └────────┬────────┘ │ hotter (>200M gas or >200 calls) ▼ ┌─────────────────┐ │ Optimizing JIT │ ← Slower compile, 10-20x speedup │ (Tier 2) │ └─────────────────┘ ▲ │ failure/eviction → demote to interpreterTier 0: Interpreter (Reference)
Section titled “Tier 0: Interpreter (Reference)”The interpreter is the canonical implementation for semantics and gas costs:
- Always available - No compilation required
- Exact gas accounting - Per-instruction metering
- Fallback tier - Used when JIT fails or is unavailable
All other tiers must produce identical results and gas usage.
Tier 1: Baseline JIT
Section titled “Tier 1: Baseline JIT”Fast compilation with modest speedup:
- Compile time: ≤5ms for 10k instructions
- Speedup: ~5x vs interpreter
- Promotion: After 10M gas executed or 20 calls
The baseline JIT performs minimal optimization—primarily translating RISC-V to native code with bounds checks.
Tier 2: Optimizing JIT
Section titled “Tier 2: Optimizing JIT”Slower compilation with higher speedup:
- Compile time: ≤50ms for 10k instructions
- Speedup: 10-20x vs interpreter
- Promotion: After 200M gas executed or 200 calls
Performs optimizations like:
- Register allocation
- Dead code elimination
- Basic block reordering
- Constant folding
AOT (Ahead-of-Time)
Section titled “AOT (Ahead-of-Time)”For frequently-used system contracts, AOT compilation provides:
- Zero runtime compilation - Pre-compiled at deploy time
- Maximum optimization - Full optimization passes
- Verified equivalence - Differential tested against interpreter
Determinism Guarantees
Section titled “Determinism Guarantees”All tiers must be bit-for-bit deterministic:
| Property | Requirement |
|---|---|
| Return values | Identical across tiers |
| State writes | Same keys, same values |
| Event logs | Same topics, same data |
| Gas consumed | Exact match to interpreter |
Verification Strategy
Section titled “Verification Strategy”- Differential fuzzing - Random programs tested across all tiers
- Replay tests - Recorded traces replayed in each tier
- Conformance corpus - CI requires 0 mismatches
If any tier produces a mismatch, it falls back to interpreter.
Gas Metering
Section titled “Gas Metering”Gas is metered identically across all tiers:
Interpreter
Section titled “Interpreter”- Per-instruction gas deduction
- Checks after every instruction
JIT/AOT
Section titled “JIT/AOT”- Basic block metering - Precompute gas per block
- Block entry check -
if gas_left < block_cost → trap - Loop back-edges - Gas check on every iteration
┌─────────────────────────────────────┐│ Basic Block Entry ││ ───────────────── ││ if gas_left < 150: ││ trap(OUT_OF_GAS) ││ gas_left -= 150 ││ ││ ... execute instructions ... ││ ││ branch to next block │└─────────────────────────────────────┘Code Cache
Section titled “Code Cache”Compiled code is cached to avoid recompilation:
Cache Key
Section titled “Cache Key”(code_hash, gas_schedule_version, vm_config_hash, tier)Eviction
Section titled “Eviction”- Policy: LRU by total code size
- Hard cap: 512 MiB (configurable)
- Per-contract cap: 64 MiB
Code changes (new code_hash) automatically invalidate cache entries.
Sandboxing
Section titled “Sandboxing”Contracts run in isolated sandboxes:
Memory Isolation
Section titled “Memory Isolation”- Linear address space - Flat 64-bit virtual memory
- Guard pages - Stack/heap overflow protection
- W^X enforcement - Pages are writable OR executable, never both
Syscall Boundary
Section titled “Syscall Boundary”- ecall instruction - Only way to interact with host
- Stable ABI - Arguments in
a0-a5, syscall number ina7 - No direct I/O - All external access through syscalls
Cross-Contract Calls
Section titled “Cross-Contract Calls”- Route through runtime dispatcher
- Automatic tier selection for callee
- Copy-on-write memory snapshots for rollback
Smart Contracts
Section titled “Smart Contracts”Contracts compile to RISC-V ELF binaries:
| Language | Toolchain | Guide |
|---|---|---|
| Zig | zig build | Ashen SDK |
| Rust | cargo + riscv64 target | Examples |
| C/C++ | clang/gcc cross-compiler | Any RISC-V toolchain |
Binary Requirements
Section titled “Binary Requirements”- Format: Static ELF64, no dynamic linking
- Relocations: None (position-independent or fixed address)
- Deterministic: Built with
SOURCE_DATE_EPOCH, no build IDs
Memory Model
Section titled “Memory Model”Each contract instance has isolated memory:
┌──────────────────────────────────┐ High addresses│ Guard Page │├──────────────────────────────────┤│ Stack │ ↓ grows down│ ↓ │├──────────────────────────────────┤│ (unmapped) │├──────────────────────────────────┤│ ↑ ││ Heap │ ↑ grows up├──────────────────────────────────┤│ Data / BSS │├──────────────────────────────────┤│ Code (read-only) │├──────────────────────────────────┤│ Guard Page │└──────────────────────────────────┘ Low addresses- Page size: 4 KiB
- Max memory: Configurable per transaction
- Cleared between txs: No information leaks
State Integration
Section titled “State Integration”The VM integrates with on-chain state through:
- Storage syscalls - Read/write contract storage
- Dirty page tracking - Efficient delta computation
- Journaling - Ordered log for crash recovery
- Merkle proofs - State provable to light clients
See Storage for details.
Related
Section titled “Related”- Gas & Fees - Fee model and pricing
- Ashen SDK - Contract development
- Example Contracts - Reference implementations
- Storage - State storage architecture