Overview
Theank-replay module provides utilities to feed protocol implementations with historical or exogenous events (e.g., chain logs, price updates) during backtests.
Key features:
- CSV-based event ingestion
- Protocol routing (target-based dispatch)
- Timestamp-filtered replay
- Historical event application to protocol registries
Types
ChainEvent
A single chain/exogenous event delivered to a protocol. Thepayload schema is protocol-specific and typically decoded inside the protocol’s Protocol::apply_historical implementation.
Fields
Event timestamp (seconds or milliseconds).
Optional market-routing hint (e.g.,
"WETH/USDC:500").Opaque JSON payload (protocol-defined schema).
RoutedCsvRow
Routed event row for CSV I/O, including the protocoltarget.
Fields
Timestamp.
Destination protocol id (must match
Protocol::id() of a registered instance).Optional market hint for the protocol.
JSON string payload (e.g.,
{"kind":"swap_exact_in", ...}).EventIngestor
Minimal helper to apply aChainEvent to a protocol.
Methods
Calls
Protocol::apply_historical with the event fields.Functions
load_routed_csv
Load a routed CSV into a vector of(target, ChainEvent) pairs.
Signature:
ts,target,market_hint,payload_json
Timestamp (seconds or milliseconds)
Protocol id (must exist in the registry)
Optional market identifier (may be empty)
JSON-encoded payload (protocol-specific schema)
apply_to_registry
Apply a batch of routed events to a protocol registry. Signature:(target, ChainEvent) is looked up by target in registry and dispatched to Protocol::apply_historical.
Parameters:
Protocol registry (protocol id → protocol instance)
Events to apply (target, event) pairs
apply_rows_at_ts
Apply only those events whosets equals at_ts.
Signature:
Timestamp filter (only events at this timestamp will be applied)
dump_routed_csv
Write routed CSV rows to a file (with headers). Signature:to_routed_csv_rows
Convert(target, ChainEvent) pairs to CSV rows (stringifying payloads).
Signature:
Usage Examples
Loading and replaying events
Tick-by-tick replay
Creating an events CSV
Create a CSV file with the following format:- Escape inner quotes in
payload_jsoncolumn - Leave
market_hintempty if not needed - Use consistent protocol
targetids
Exporting events to CSV
Advanced: Custom event filtering
CSV Format Details
Headers
Required:ts,target,market_hint,payload_json
Field Specifications
ts (required):
- Type:
u64 - Format: Unix timestamp (seconds or milliseconds)
- Example:
1640000000
target (required):
- Type:
String - Format: Protocol identifier matching
Protocol::id() - Example:
uniswap-v3,aave-v3,compound-v2
market_hint (optional):
- Type:
Stringor empty - Format: Protocol-specific market identifier
- Examples:
- Uniswap V3:
WETH/USDC:500(pair + fee tier) - Aave: (typically empty or asset symbol)
- Compound:
cETH,cDAI
- Uniswap V3:
payload_json (required):
- Type: JSON string
- Format: Protocol-specific event payload
- Must be valid JSON
- Inner quotes must be escaped when embedding in CSV
Example Payloads
Uniswap V3 Swap:Implementation Notes
Protocol Dispatch
The replay system uses theProtocol trait’s apply_historical method:
- Parsing the
payloadJSON - Validating the event schema
- Applying state changes
- Handling errors gracefully
Timestamp Normalization
Timestamps in milliseconds (> 100 billion) are automatically converted to seconds for consistency.Error Handling
If an event cannot be applied:apply_to_registryreturns an error immediately (fail-fast)- Protocol implementations should return descriptive errors
- Use
anyhow::Contextto add event context
Performance Considerations
- Events are loaded entirely into memory
- For large event logs (> 1M events), consider chunked processing
- Pre-sort events by timestamp for sequential replay
- Use
apply_rows_at_tsfor memory-efficient tick-by-tick processing