Overview
Firedancer’s pack system:- Maintains a pool of pending transactions
- Prioritizes transactions by fee/compute unit ratio
- Schedules transactions into microblocks
- Respects consensus-critical limits (cost, data size)
- Handles account conflicts and write locks
- Supports atomic transaction bundles
- Tracks per-account write costs
Core Concepts
Transaction Ordering
Transactions are prioritized by:- rewards: Transaction fee in lamports
- compute_est: Estimated compute units
Consensus-Critical Limits
These limits are either consensus-critical (agreed cluster-wide) or implementation-specific (Firedancer memory bounds). A block exceeding consensus limits is invalid.
Microblock Overhead
Data Structures
Transaction Ordering Structure
The structure is carefully designed with no padding between the union and other fields, allowing pointer casting between
fd_txn_p_t and the full structure.Account Address Usage
- Track which accounts are in use by executing microblocks
- Track total write cost per account (consensus limit)
- Track bundle-specific account usage
Transaction Trees
Pack maintains multiple treaps (randomized binary search trees) for different transaction categories:Root Types
Penalty Treaps
When a transaction can’t be scheduled due to account conflicts:- Moved to penalty treap for the conflicting account
- Checked again when that account becomes available
- Avoids repeatedly checking transactions that can’t execute
Bitset Optimization
Pack uses bitsets to quickly check account conflicts:Bitset Assignment
FD_PACK_BITSET_FIRST_INSTANCE: Account referenced by only one transactionFD_PACK_BITSET_SLOWPATH: Too many accounts, use slow path
Accounts referenced by only one transaction don’t need a bit allocated. This optimization is important as most accounts are only touched by a single transaction.
Bundle Support
Bundles are sequences of 1-5 transactions that execute atomically:Bundle Flags
Initializer Bundle State Machine
- NOT_INITIALIZED: Block starts, no initializer bundle
- PENDING: Initializer bundle scheduled, awaiting result
- FAILED: Initializer bundle failed (bug, insufficient balance, expired blockhash)
- READY: Initializer bundle succeeded, normal bundles can proceed
Scheduling Algorithm
Account Conflict Detection
Before scheduling a transaction:Scheduling Steps
- Select highest priority transaction from appropriate treap
- Check resource limits: cost, data bytes, microblock capacity
- Check account conflicts: read/write locks, write cost limits
- Reserve accounts: mark as in-use by this microblock
- Update resource usage: cost, data bytes, write costs
- Add to microblock: append transaction to current microblock
- Repeat until microblock full or no schedulable transactions
Skip Counter Optimization
- Increment skip counter
- Skip quickly without full conflict checking
- Compressed slot number stored when threshold reached
- Re-evaluated when slot changes
Write Cost Tracking
Per-account write costs are tracked to enforce consensus limits:- Clear entire writer cost map instead of individual entries
- Avoids overhead of tracking too many individual accounts
Top Writers Heap
Fee Model
Fee Per Signature
Fee Burn Percentage
Resource Limits
Data Size Limit
Cost Limits
Pack doesn’t know exactly how the block will be shredded (separation of concerns), so it uses conservative data size limits that guarantee the shred tile won’t exceed shred counts.
Expiration Handling
Expiration Priority Queue
- Ordered by expiration time
- Periodically checked for expired transactions
- Expired transactions removed from all data structures
Invariants
Bank Tile Integration
Pack can schedule to multiple bank tiles:Account Usage Bitmask
- Bit set: account in use by that bank
- Allows parallel execution on different banks
- Account can’t be used by same bank until microblock completes
Performance Considerations
Memory Layout
Non-Temporal Memcpy
Address Sanitizer Workaround
Smallest Transaction Tracking
- If remaining space < smallest transaction, skip entire treap
- Avoids checking transactions that can’t possibly fit
- Conservative estimate maintained as transactions are deleted