Checkpoints were initially designed as minimal, immutable representations of atomic progress (a single transaction or bundle application). While this ensures cheap cloning and linear memory allocation, it introduces significant performance bottlenecks as the chain deepens:
Checkpoint only stores the state diff (mutation) of its specific execution. To resolve database reads the system must traverse the linked list backwards, checking every checkpoint until it hits the BlockContext (base state).BuiltPayload, the current implementation requires re-executing transactions to aggregate receipts, logs, state roots, as intermediate checkpoints do not track cumulative context.Goal: Optimize state access time and payload building without sacrificing the flexibility of the checkpointing system.
These initial profiles were run on a standard slow laptop (so performance/timing is relative, not absolute) to try identify bottlenecks in the current checkpoint architecture and give a rough intuition of where we should focus first.
Test Case: Application of 1,000 simple transfer transactions (same sender, same value, random to address).
Logic Profiled:
We targets CheckpointInner mutations. Specifically the execute_transaction flow where BundleState is produced (as our test case only produces transaction executables).
Timeline between “Apply Transactions” and “Build Payload”

Timeline of apply()
