Expand description
Runtime executor using smoldot to execute Substrate runtime calls.
This module provides RuntimeExecutor, a wrapper around smoldot’s executor that
runs Substrate runtime calls (like Core_version, BlockBuilder_apply_extrinsic, etc.)
against storage provided by a LocalStorageLayer.
§Design Decision: Why smoldot?
smoldot already implements all ~50 Substrate host functions required for runtime execution:
- Storage operations: get, set, clear, exists, next_key
- Cryptographic operations: sr25519, ed25519, ecdsa signature verification
- Hashing: blake2, keccak, sha2, twox
- Memory allocation: heap management for the WASM runtime
- Logging and debugging: runtime log emission
By using smoldot’s runtime_call API, we avoid reimplementing these host functions
while gaining full control over storage access. Storage reads are routed through the
LocalStorageLayer, which checks local modifications first,
then deleted prefixes, and finally falls back to the parent layer (typically a
RemoteStorageLayer that lazily fetches from RPC).
§Executor Architecture
┌─────────────────────────────────────────────────────────────────────┐
│ RuntimeExecutor │
│ │
│ call(method, args) ──► Create VM Prototype │
│ │ │
│ ▼ │
│ Start runtime_call │
│ │ │
│ ▼ │
│ ┌────── Event Loop ──────┐ │
│ │ │ │
│ ▼ ▼ │
│ StorageGet? SignatureVerify? │
│ │ │ │
│ ▼ ▼ │
│ Query LocalStorageLayer Verify or mock │
│ │ │ │
│ └──────────┬─────────────┘ │
│ ▼ │
│ Finished? │
│ │ │
│ ▼ │
│ Return RuntimeCallResult │
│ (output + storage_diff) │
└─────────────────────────────────────────────────────────────────────┘§Example
ⓘ
use pop_fork::{RuntimeExecutor, LocalStorageLayer, RemoteStorageLayer};
// Create the storage layers
let remote = RemoteStorageLayer::new(rpc, cache, block_hash);
let local = LocalStorageLayer::new(remote);
// Create executor with runtime WASM code fetched from chain
let runtime_code = rpc.runtime_code(block_hash).await?;
let executor = RuntimeExecutor::new(runtime_code, None)?;
// Execute a runtime call against the local storage layer
let result = executor.call("Core_version", &[], &local).await?;
println!("Output: {:?}", result.output);
println!("Storage changes: {:?}", result.storage_diff.len());Structs§
- Executor
Config - Configuration for runtime execution.
- Runtime
Call Result - Result of a runtime call execution.
- Runtime
Executor - Runtime executor for executing Substrate runtime calls.
- Runtime
Log - A log message emitted by the runtime.
- Runtime
Version - Runtime version information.
Enums§
- Signature
Mock Mode - Signature mock mode for testing.