paradigmxyz / reth

Modular, contributor-friendly and blazing-fast implementation of the Ethereum protocol, in Rust
https://reth.rs/
Apache License 2.0
3.96k stars 1.19k forks source link

Validate pruning configuration on startup #5420

Open shekhirin opened 1 year ago

shekhirin commented 1 year ago

Describe the feature

Reth doesn't support switching the pruning configuration and turning the full node into archive (or vice-versa) mid-sync.

To prevent such user errors, on node startup we should compare the current pruning configuration to the PruneCheckpoints we have in the database with the respective prune modes. If any of them doesn't match, we should exit with an error.

Additional context

No response

DoTheBestToGetTheBest commented 1 year ago

oesn't match, we

Hey this issue looks interesting to me, i wrote the get_current_pruning_mode function, can you just tell me if i'm in the good way or not ? (if you have time for it of course) otherwise if i'm totally out, i would just abandon this issue

use reth_primitives::{BlockNumber, PruneMode};
use serde_json::Value;
use std::fs;

/// Retrieves the current pruning mode configuration.
///
/// This function reads the node's configuration settings to determine the current pruning mode.
/// The pruning mode dictates how the blockchain data is pruned and stored in the node's database.
pub fn get_current_pruning_mode() -> Result<PruneMode, String> {
    let config_data = fs::read_to_string("file_to_config_data.json")
        .map_err(|e| format!("Failed to read config file: {}", e))?;

    let config: Value = serde_json::from_str(&config_data)
        .map_err(|e| format!("Failed to parse config JSON: {}", e))?;

    match config["pruning_mode"].as_str() {
        Some("Full") => Ok(PruneMode::Full),
        Some(s) if s.starts_with("Distance") => {
            let distance = s
                .trim_start_matches("Distance(")
                .trim_end_matches(")")
                .parse::<u64>()
                .map_err(|e| format!("Failed to parse Distance: {}", e))?;
            Ok(PruneMode::Distance(distance))
        }
        Some(s) if s.starts_with("Before") => {
            let block_number = s
                .trim_start_matches("Before(")
                .trim_end_matches(")")
                .parse::<BlockNumber>()
                .map_err(|e| format!("Failed to parse Before: {}", e))?;
            Ok(PruneMode::Before(block_number))
        }
        _ => Err("Invalid pruning mode in configuration".to_string()),
    }
}
shekhirin commented 1 year ago

hey @DoTheBestToGetTheBest! Currently, pruning configuration is already parsed from the file into corresponding Rust struct https://github.com/paradigmxyz/reth/blob/2bd8c7e7e62594fc82fcf1fa50bc56601d3489f6/crates/config/src/config.rs#L288-L297 https://github.com/paradigmxyz/reth/blob/80be039c774ec41b15286ea068f90e4ce2339fa4/bin/reth/src/node/mod.rs#L278-L279

So what we want here is to query all checkpoints from the PruneCheckpoints table, and compare prune modes from them to the pruning configuration we already have.

github-actions[bot] commented 8 months ago

This issue is stale because it has been open for 21 days with no activity.

github-actions[bot] commented 8 months ago

This issue was closed because it has been inactive for 7 days since being marked as stale.