reth_cli_commands/db/
settings.rs

1//! `reth db settings` command for managing storage settings
2
3use clap::{ArgAction, Parser, Subcommand};
4use reth_db_common::DbTool;
5use reth_provider::{
6    providers::ProviderNodeTypes, DBProvider, DatabaseProviderFactory, MetadataProvider,
7    MetadataWriter, StorageSettings,
8};
9
10use crate::common::AccessRights;
11
12/// `reth db settings` subcommand
13#[derive(Debug, Parser)]
14pub struct Command {
15    #[command(subcommand)]
16    command: Subcommands,
17}
18
19impl Command {
20    /// Returns database access rights required for the command.
21    pub fn access_rights(&self) -> AccessRights {
22        match self.command {
23            Subcommands::Get => AccessRights::RO,
24            Subcommands::Set(_) => AccessRights::RW,
25        }
26    }
27}
28
29#[derive(Debug, Clone, Copy, Subcommand)]
30enum Subcommands {
31    /// Get current storage settings from database
32    Get,
33    /// Set storage settings in database
34    #[clap(subcommand)]
35    Set(SetCommand),
36}
37
38/// Set storage settings
39#[derive(Debug, Clone, Copy, Subcommand)]
40#[clap(rename_all = "snake_case")]
41pub enum SetCommand {
42    /// Store receipts in static files instead of the database
43    ReceiptsInStaticFiles {
44        #[clap(action(ArgAction::Set))]
45        value: bool,
46    },
47    /// Store transaction senders in static files instead of the database
48    TransactionSendersInStaticFiles {
49        #[clap(action(ArgAction::Set))]
50        value: bool,
51    },
52}
53
54impl Command {
55    /// Execute the command
56    pub fn execute<N: ProviderNodeTypes>(self, tool: &DbTool<N>) -> eyre::Result<()> {
57        match self.command {
58            Subcommands::Get => self.get(tool),
59            Subcommands::Set(cmd) => self.set(cmd, tool),
60        }
61    }
62
63    fn get<N: ProviderNodeTypes>(&self, tool: &DbTool<N>) -> eyre::Result<()> {
64        // Read storage settings
65        let provider = tool.provider_factory.provider()?;
66        let storage_settings = provider.storage_settings()?;
67
68        // Display settings
69        match storage_settings {
70            Some(settings) => {
71                println!("Current storage settings:");
72                println!("{settings:#?}");
73            }
74            None => {
75                println!("No storage settings found.");
76            }
77        }
78
79        Ok(())
80    }
81
82    fn set<N: ProviderNodeTypes>(&self, cmd: SetCommand, tool: &DbTool<N>) -> eyre::Result<()> {
83        // Read storage settings
84        let provider_rw = tool.provider_factory.database_provider_rw()?;
85        // Destruct settings struct to not miss adding support for new fields
86        let settings = provider_rw.storage_settings()?;
87        if settings.is_none() {
88            println!("No storage settings found, creating new settings.");
89        }
90
91        let mut settings @ StorageSettings {
92            receipts_in_static_files: _,
93            transaction_senders_in_static_files: _,
94            storages_history_in_rocksdb: _,
95            transaction_hash_numbers_in_rocksdb: _,
96            account_history_in_rocksdb: _,
97        } = settings.unwrap_or_else(StorageSettings::legacy);
98
99        // Update the setting based on the key
100        match cmd {
101            SetCommand::ReceiptsInStaticFiles { value } => {
102                if settings.receipts_in_static_files == value {
103                    println!("receipts_in_static_files is already set to {}", value);
104                    return Ok(());
105                }
106                settings.receipts_in_static_files = value;
107                println!("Set receipts_in_static_files = {}", value);
108            }
109            SetCommand::TransactionSendersInStaticFiles { value } => {
110                if settings.transaction_senders_in_static_files == value {
111                    println!("transaction_senders_in_static_files is already set to {}", value);
112                    return Ok(());
113                }
114                settings.transaction_senders_in_static_files = value;
115                println!("Set transaction_senders_in_static_files = {}", value);
116            }
117        }
118
119        // Write updated settings
120        provider_rw.write_storage_settings(settings)?;
121        provider_rw.commit()?;
122
123        println!("Storage settings updated successfully.");
124
125        Ok(())
126    }
127}