Transaction lanes: reserved blockspace with custom lane support
- Dominant language
- Rust
- Stars
- 8
- Forks
- 9
- Avg merge
- 2d 13h
- Merged PRs (30d)
- 6
Description
## Summary
Implement a lane-based block construction system in the payload builder that reserves blockspace for different transaction categories, with built-in payment lanes and a pluggable interface for custom lanes.
## Motivation
At 100ms block times with sequencer-controlled ordering, the scarce resource isn't confirmation speed -- it's guaranteed throughput under congestion. When block gas is fully utilized, high-value payment transactions compete with arbitrary EVM workloads (DeFi, NFT mints, contract deployments). Payment lanes guarantee that stablecoin transfers and payment-critical transactions always have access to blockspace, regardless of what else is happening on-chain.
Custom lanes extend this to any transaction category a chain operator cares about: system transactions, oracle updates, bridge operations, or domain-specific workloads.
## Design
### Lane model
A lane defines:
- **Name / ID**: identifier for the lane (e.g., `payment`, `system`, `general`)
- **Gas reservation**: minimum gas guaranteed for this lane per block
- **Gas cap**: maximum gas this lane can consume (optional -- lanes can overflow into general capacity)
- **Matcher**: predicate that routes a transaction to a lane (by tx type, destination address, calldata selector, or custom logic)
- **Priority**: ordering within the lane (FIFO, fee-based, or custom)
### Block structure
```
Block gas_limit: 30M
├── system lane: 2M reserved (system txs, L1 info, oracle updates)
├── payment lane: 15M reserved (stablecoin transfers, 0x76 payment calls)
├── general lane: 13M remainder (everything else)
└── overflow: unused lane capacity redistributed to general
```
### Chainspec configuration
```json
{
"evolve": {
"lanes": [
{
"id": "system",
"gas_reserved": 2000000,
"matcher": { "type": "tx_type", "values": ["system"] },
"priority": "fifo"
},
{
"id": "payment",
"gas_reserved": 15000000,
"gas_cap": 20000000,
"matcher": {
"type": "any_of",
"rules": [
{ "type": "to_address", "addresses": ["0x...USDC", "0x...USDT"] },
{ "type": "selector", "selectors": ["0xa9059cbb", "0x23b872dd"] }
]
},
"priority": "fee"
}
],
"lanes_activation_height": 0
}
}
```
### Custom lane interface
Chain operators can define lanes via chainspec (static) or register them programmatically via a trait:
```rust
pub trait LaneMatcher: Send + Sync {
/// Returns the lane ID this transaction belongs to, or None for general lane.
fn match_tx(&self, tx: &EvTxEnvelope, state: &dyn StateProvider) -> Option;
}
pub trait LanePolicy: Send + Sync {
/// Orders transactions within a lane. Returns sorted transaction list.
fn order(&self, txs: Vec<&EvTxEnvelope>) -> Vec<&EvTxEnvelope>;
}
```
This allows customers to:
- Define lanes by contract address, function selector, tx type, sender allowlist, or arbitrary state-dependent logic
- Implement custom ordering within lanes (auction-based, priority fee, FIFO, round-robin)
- Compose matchers (`any_of`, `all_of`, `not`)
### Payload builder integration
`EvolvePayloadBuilder` in `crates/node/src/builder.rs` changes:
1. **Classify**: Route each incoming transaction to a lane via matchers
2. **Reserve**: Allocate gas budget per lane from block gas limit
3. **Fill**: Execute transactions lane-by-lane, respecting per-lane gas reservations
4. **Overflow**: Redistribute unused lane capacity to general lane
5. **Metrics**: Emit per-lane utilization metrics (gas used, tx count, overflow)
### Receipt / RPC extensions
- `eth_getTransactionReceipt` includes `lane` field indicating which lane the tx was routed to
- New RPC: `evolve_getLaneStatus` returns current lane utilization and available capacity
- Useful for clients to estimate inclusion probability and fee dynamics per lane
## Scope
- [ ] Define `Lane`, `LaneMatcher`, `LanePolicy` traits in `crates/common/` or `crates/evolve/`
- [ ] Implement built-in matchers: `tx_type`, `to_address`, `selector`, `sender`, `any_of`, `all_of`
- [ ] Add lane configuration to `EvolveConfig` chainspec extras
- [ ] Modify `EvolvePayloadBuilder` to classify, reserve, fill, and overflow
- [ ] Add per-lane metrics (gas used, tx count, overflow events)
- [ ] Extend RPC with lane status endpoint
- [ ] Extend receipts with lane metadata
- [ ] Integration tests: congested blocks with lane guarantees, overflow behavior, custom matcher registration
- [ ] Documentation: how to define custom lanes for a chain deployment
## Prior art
- [Tempo: payment lanes with dual gas limits](https://docs.tempo.xyz/learn/tempo/performance) -- `general_gas_limit` caps non-payment gas, remaining reserved for payments
- [Ethereum EIP-7766: Priority lanes proposal](https://eips.ethereum.org/EIPS/eip-7766) -- similar concept for L1
- #94 (closed) -- ToB auction research; auction-based ordering becomes a `LanePolicy` implementation
- #127 (closed) -- pre-confirmations; moot at 100ms blocks, lane guarantees are the actual need
Contributor guide
Assessment
This issue has not been assessed yet.