Overview
Erst is a Soroban debugging and error decoding tool for the Stellar network. It bridges the gap between opaque XDR error codes and developer-friendly transaction analysis through transaction replay and local simulation. The architecture consists of three core components:- Go CLI (
erst): Command-line interface for user interaction - RPC Client: Stellar network data fetching via Horizon API and JSON-RPC
- Rust Simulator (
erst-sim): Soroban transaction execution and diagnostics
System architecture
Data flow
The transaction debugging workflow follows this sequence:Fetch transaction envelope
The Go CLI requests transaction data from the Stellar network via Horizon API using the transaction hash.
Retrieve ledger state
The RPC client fetches the complete ledger state including
TransactionEnvelope, ResultMetaXDR, and LedgerEntries at the transaction execution point.Create simulation request
The CLI constructs a
SimulationRequest containing the envelope XDR, result metadata, and ledger entries as a JSON payload.Execute simulator
The Runner spawns the Rust simulator process and passes the JSON request via stdin.
Replay transaction
The simulator decodes XDR structures, initializes the Soroban Host VM with ledger state, and executes the transaction.
Collect diagnostics
During execution, the simulator captures diagnostic events, execution logs, and error traces.
Return results
The simulator outputs a JSON response via stdout containing status, events, logs, and error information.
IPC protocol
The Go CLI and Rust simulator communicate through JSON serialization over stdin/stdout.Request format
| Field | Type | Purpose |
|---|---|---|
envelope_xdr | String (Base64) | Complete signed transaction envelope ready for execution |
result_meta_xdr | String (Base64) | Transaction result metadata from the blockchain (optional) |
ledger_entries | Map (Base64 → Base64) | Read/write set of ledger entries at transaction time |
Response format
| Field | Type | Purpose |
|---|---|---|
status | String | Execution status: “success” or “error” |
error | String | Null | Error message if status is “error” |
events | Array | Diagnostic events emitted during execution |
logs | Array | Detailed execution logs for debugging |
Component details
Go RPC client
Location:internal/rpc/client.go
Responsibilities:
- Establish connections to Stellar Horizon API
- Fetch transaction envelopes and metadata
- Query ledger state at specific transaction points
- Support multiple networks (Mainnet, Testnet, Futurenet)
- Standardized middleware for custom request/response interceptors
- Mainnet:
https://horizon.stellar.org - Testnet:
https://horizon-testnet.stellar.org - Futurenet:
https://horizon-futurenet.stellar.org
TypeScript RPC client (Protocol V2)
Location:src/rpc/
The TypeScript RPC client provides Protocol V2 enhancements for the Stellar SDK.
Key features:
- Fallback support: Automatic failover across multiple RPC endpoints
- Circuit breaker: Prevents cascading failures with configurable threshold and timeout
- Batch requests: Execute multiple RPC calls in a single request (Protocol V2)
- Type-safe methods: Full TypeScript support for all RPC methods
- Request/response validation: Built-in validation for RPC requests and responses
- Performance metrics: Real-time endpoint health monitoring
Simulator runner
Location:internal/simulator/runner.go
Responsibilities:
- Locate and execute the
erst-simRust binary - Validate simulation requests before processing
- Manage subprocess lifecycle
- Handle IPC communication via stdin/stdout
- Deserialize simulation results
The Runner includes a
Validator that performs comprehensive schema validation before processing, including base64 encoding checks, required field validation, and ledger entry validation.Rust simulator
Location:simulator/src/main.rs
Responsibilities:
- Decode XDR structures from Base64
- Initialize Soroban Host VM with ledger state
- Execute transaction and capture diagnostics
- Generate execution trace and error information
- Read JSON from stdin and deserialize to
SimulationRequest - Extract and Base64-decode
envelope_xdr,result_meta_xdr, andledger_entries - Initialize Soroban Host VM with ledger state
- Set diagnostic level to Debug mode
- Execute transaction in VM
- Capture diagnostic events and execution logs
- Build execution trace with status and errors
- Serialize to JSON and write to stdout
State management
When debugging a transaction, Erst must capture the exact ledger state at the point of execution.State consistency requirements
| State element | Source | Purpose |
|---|---|---|
| Account balance | Horizon API | Verify sender has funds |
| Contract state | Ledger entries | Execute contract logic |
| Sequence numbers | Account query | Validate transaction ordering |
| Fee pool | Ledger query | Calculate fee impacts |
Event correlation and error tracing
The Soroban Host emits structured diagnostic events during execution. Erst correlates these with transaction failures to provide meaningful error messages.Error classification
Execution errors
Execution errors
- Trap/Panic
- Assertion failure
- Out of bounds
Logic errors
Logic errors
- Invalid state transition
- Permission denied
- Contract violation
Resource errors
Resource errors
- Out of gas
- Memory exceeded
- Instruction limit
Network errors
Network errors
- Invalid signature
- Bad sequence
- Insufficient balance
Performance considerations
Optimization strategies
- Minimize state transfer: Only fetch read/write set using JSON-RPC pagination
- Fast local execution: Pre-compile WASM if needed and cache Host state
- Efficient data format: Use Base64 encoding for portability and compressed XDR for large states
Benchmarking metrics
- State fetch time: Horizon latency + payload size
- Simulation time: WASM execution + event collection
- Memory usage: Host VM state + ledger cache
- End-to-end: User request → result display
Integration points
The system integrates with multiple external services and libraries:- Horizon Client: Stellar Horizon API
- spf13/cobra: Command framework
- zap: Logging system
- serde_json: JSON serialization
- soroban-env-host: Soroban Host VM
- base64: XDR encoding
Future integration points
Planned integrations include:
- JSON-RPC Client for direct ledger queries
- WebAssembly Inspector for WASM-level debugging
- Source Map Integration to map to Rust source
- Event Database for persistent event logging
- Dashboard/Web UI for visual debugging interface
Development setup
Building the project
Environment variables
Testing architecture
Unit testing
- RPC client tests: Mock Horizon API responses
- Runner tests: Test subprocess execution and IPC
- Serialization tests: Validate JSON encoding/decoding
Integration testing
Integration tests use both live network data and test fixtures:- Live network: Testnet transactions with real Horizon data
- Test fixtures: Mocked data for deterministic testing
CI/CD pipeline
CI and automation are treated as part of the architecture:- General CI:
.github/workflows/ci.yml - Strict linting:
.github/workflows/strict-lint.yml - CI robustness:
.github/workflows/ci-standardization.yml
scripts/validate-ci.sh— validates CI configuration and versionsscripts/test-ci-locally.sh— mirrors CI checks locallyscripts/lint-strict.sh— strict linting and verification
All scripts compute the repository root from their own location instead of assuming they are invoked from the project root, removing implicit global state dependencies.