Repository: paradigmxyz/reth (Rust)

Issue:
Add provider function to return a list of all stages and their progress
### Describe the feature

with https://github.com/alloy-rs/alloy/pull/1079 we can now emit an list of stages and their processed blocks

which can be obtained from the 

https://github.com/paradigmxyz/reth/blob/9e685163deb57b2a2e1661195c093071d1e85647/crates/storage/storage-api/src/stage_checkpoint.rs#L5-L9

we need a new function here that returns a list of all checkpoints in that table:

we need to iterate over this table and decode its keys to string and the checkpoint

https://github.com/paradigmxyz/reth/blob/9e685163deb57b2a2e1661195c093071d1e85647/crates/storage/provider/src/providers/database/provider.rs#L2507-L2509

## TODO
* add get_all_checkpoints function to trait

this can be done via

https://github.com/paradigmxyz/reth/blob/9e685163deb57b2a2e1661195c093071d1e85647/crates/storage/db-api/src/transaction.rs#L22-L22

and then walk 

https://github.com/paradigmxyz/reth/blob/9e685163deb57b2a2e1661195c093071d1e85647/crates/storage/db-api/src/cursor.rs#L40-L40

FYI @loocapro 

### Additional context

_No response_


Discussion:
Happy to get it!



Patch:
diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs
index bfd0a39bcbb..05c332508f1 100644
--- a/crates/storage/provider/src/providers/database/mod.rs
+++ b/crates/storage/provider/src/providers/database/mod.rs
@@ -512,6 +512,9 @@ impl<DB: Database> StageCheckpointReader for ProviderFactory<DB> {
     fn get_stage_checkpoint_progress(&self, id: StageId) -> ProviderResult<Option<Vec<u8>>> {
         self.provider()?.get_stage_checkpoint_progress(id)
     }
+    fn get_all_checkpoints(&self) -> ProviderResult<Vec<(String, StageCheckpoint)>> {
+        self.provider()?.get_all_checkpoints()
+    }
 }
 
 impl<DB: Database> EvmEnvProvider for ProviderFactory<DB> {
diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs
index 88803b844e4..7a7f80dc50d 100644
--- a/crates/storage/provider/src/providers/database/provider.rs
+++ b/crates/storage/provider/src/providers/database/provider.rs
@@ -2508,6 +2508,14 @@ impl<TX: DbTx> StageCheckpointReader for DatabaseProvider<TX> {
         Ok(self.tx.get::<tables::StageCheckpoints>(id.to_string())?)
     }
 
+    fn get_all_checkpoints(&self) -> ProviderResult<Vec<(String, StageCheckpoint)>> {
+        self.tx
+            .cursor_read::<tables::StageCheckpoints>()?
+            .walk(None)?
+            .collect::<Result<Vec<(String, StageCheckpoint)>, _>>()
+            .map_err(ProviderError::Database)
+    }
+
     /// Get stage checkpoint progress.
     fn get_stage_checkpoint_progress(&self, id: StageId) -> ProviderResult<Option<Vec<u8>>> {
         Ok(self.tx.get::<tables::StageCheckpointProgresses>(id.to_string())?)
diff --git a/crates/storage/provider/src/providers/mod.rs b/crates/storage/provider/src/providers/mod.rs
index 54738035f0c..1381624f5d9 100644
--- a/crates/storage/provider/src/providers/mod.rs
+++ b/crates/storage/provider/src/providers/mod.rs
@@ -526,6 +526,10 @@ where
     fn get_stage_checkpoint_progress(&self, id: StageId) -> ProviderResult<Option<Vec<u8>>> {
         self.database.provider()?.get_stage_checkpoint_progress(id)
     }
+
+    fn get_all_checkpoints(&self) -> ProviderResult<Vec<(String, StageCheckpoint)>> {
+        self.database.provider()?.get_all_checkpoints()
+    }
 }
 
 impl<DB> EvmEnvProvider for BlockchainProvider<DB>
diff --git a/crates/storage/storage-api/src/stage_checkpoint.rs b/crates/storage/storage-api/src/stage_checkpoint.rs
index 3815239be2c..d59f3dfb255 100644
--- a/crates/storage/storage-api/src/stage_checkpoint.rs
+++ b/crates/storage/storage-api/src/stage_checkpoint.rs
@@ -10,6 +10,10 @@ pub trait StageCheckpointReader: Send + Sync {
 
     /// Get stage checkpoint progress.
     fn get_stage_checkpoint_progress(&self, id: StageId) -> ProviderResult<Option<Vec<u8>>>;
+
+    /// Reads all stage checkpoints and returns a list with the name of the stage and the checkpoint
+    /// data.
+    fn get_all_checkpoints(&self) -> ProviderResult<Vec<(String, StageCheckpoint)>>;
 }
 
 /// The trait for updating stage checkpoint related data.


Test patch:
diff --git a/crates/storage/provider/src/test_utils/noop.rs b/crates/storage/provider/src/test_utils/noop.rs
index 877c4d7afca..8032a093920 100644
--- a/crates/storage/provider/src/test_utils/noop.rs
+++ b/crates/storage/provider/src/test_utils/noop.rs
@@ -442,6 +442,10 @@ impl StageCheckpointReader for NoopProvider {
     fn get_stage_checkpoint_progress(&self, _id: StageId) -> ProviderResult<Option<Vec<u8>>> {
         Ok(None)
     }
+
+    fn get_all_checkpoints(&self) -> ProviderResult<Vec<(String, StageCheckpoint)>> {
+        Ok(Vec::new())
+    }
 }
 
 impl WithdrawalsProvider for NoopProvider {