Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Setting RocksDB as default database, making db configurable, and removing redis from deps #211

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

distractedm1nd
Copy link
Contributor

@distractedm1nd distractedm1nd commented Jan 16, 2025

Usage: prism-cli prover [OPTIONS]

Options:
  -l, --log-level <LOG_LEVEL>
          Log level

          [default: INFO]

  -n, --network-name <NETWORK_NAME>
          [default: local]

      --verifying-key <VERIFYING_KEY>


      --verifying-key-algorithm <VERIFYING_KEY_ALGORITHM>
          The algorithm used for the verifying key.

          Can be one of: `ed25519`, `secp256k1`, `secp256r1`.

          [default: ed25519]

      --home-path <HOME_PATH>


      --db-type <DB_TYPE>
          [possible values: rocks-db, in-memory, redis]

      --rocksdb-path <ROCKSDB_PATH>
          Path to the RocksDB database, used when `db_type` is `rocks-db`

      --redis-url <REDIS_URL>
          Connection string to Redis, used when `db_type` is `redis`

  -c, --celestia-client <CELESTIA_CLIENT>
          Celestia Client websocket URL

      --snark-namespace-id <SNARK_NAMESPACE_ID>
          Celestia Snark Namespace ID

      --operation-namespace-id <OPERATION_NAMESPACE_ID>
          Celestia Transaction Namespace ID

  -s, --celestia-start-height <CELESTIA_START_HEIGHT>
          Height to start searching the DA layer for SNARKs on

      --webserver-active <WEBSERVER_ACTIVE>
          [possible values: true, false]

      --host <HOST>
          IP address for the webserver to listen on

          [default: 127.0.0.1]

  -p, --port <PORT>
          Port number for the webserver to listen on

  -h, --help
          Print help (see a summary with '-h')
  • Adds --network-name (default: local). Default prism home is now {HOME}/.prism/{NETWORK_NAME}
  • Adds --db-type (possible values: rocks-db, in-memory, redis). rocks-db requires --rocksdb-path, redis requires --redis-url
  • Removes redis from the dependencies in justfile. RocksDB is now the default.

Closes #196

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced database configuration with support for multiple storage backends (RocksDB, Redis, In-Memory)
    • Improved configuration management with more flexible database selection
  • Changes

    • Replaced Redis-specific configuration with a more generic storage backend approach
    • Updated configuration path handling to use a more intuitive home directory structure
    • Added support for network-specific configurations
  • Improvements

    • Simplified database initialization process
    • More modular and extensible configuration management

@distractedm1nd distractedm1nd requested review from jns-ps and smuu January 16, 2025 10:27
Copy link
Contributor

coderabbitai bot commented Jan 16, 2025

Walkthrough

The pull request introduces a comprehensive refactoring of the database configuration system in the Prism project. The primary change is shifting from Redis to RocksDB as the default storage backend, with added flexibility to support multiple database types. A new StorageBackend enum has been created to manage different database configurations, and the configuration management in cfg.rs has been updated to support this more modular approach. The changes simplify database initialization and provide a more structured way to handle storage configurations.

Changes

File Changes
crates/cli/src/cfg.rs - Added DatabaseArgs struct
- Updated CommandArgs with network_name and home_path
- Modified Config to use StorageBackend
- Added initialize_db function
- Renamed get_config_path to get_prism_home
crates/cli/src/main.rs - Updated database initialization to use new initialize_db function
crates/storage/src/database.rs - Added StorageBackend enum with RocksDB, InMemory, and Redis variants
crates/storage/src/redis.rs - Added PartialEq and Eq traits to RedisConfig
crates/storage/src/rocksdb.rs - Added RocksDBConfig struct
- Updated RocksDBConnection::new to use RocksDBConfig
crates/tests/src/lib.rs - Updated import to include RocksDBConfig
- Modified setup_db to use RocksDBConfig
justfile - Removed Redis installation block

Assessment against linked issues

Objective Addressed Explanation
Use RocksDB as default
Remove Redis dependencies

Possibly related PRs

Suggested reviewers

  • sebasti810

Poem

🐰 In the realm of data's dance,
RocksDB takes its rightful stance
Redis fades, a memory light
Configuration now shines so bright
A rabbit's code, both swift and neat! 🚀


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (9)
crates/cli/src/cfg.rs (4)

39-40: Consider changing network_name to a String instead of Option<String>.

Since network_name has a default value of "local", making it an Option<String> is unnecessary. Changing it to a String simplifies the code and ensures that the value is always present.

Apply this diff to update the type:

-    network_name: Option<String>,
+    network_name: String,

And adjust the argument attribute:

-    #[arg(short = 'n', long, default_value = "local")]
+    #[arg(short = 'n', long, default_value = "local")]

52-52: Consider changing home_path to a String instead of Option<String>.

Similar to network_name, since home_path can have a default value, changing it to a String ensures that the value is always present, reducing the need to handle Option.

Apply this diff:

-    home_path: Option<String>,
+    home_path: String,

259-278: Implement initialize_db returning a consistent type without boxing twice.

Currently, the function returns Arc<Box<dyn Database>>>, which includes unnecessary boxing. Simplify the return type to Arc<dyn Database>.

Apply this diff:

-pub fn initialize_db(cfg: &Config) -> Result<Arc<Box<dyn Database>>> {
+pub fn initialize_db(cfg: &Config) -> Result<Arc<dyn Database>> {

     match &cfg.db {
         StorageBackend::RocksDB(cfg) => {
             let db = RocksDBConnection::new(cfg)
                 .map_err(|e| GeneralError::InitializationError(e.to_string()))
                 .context("Failed to initialize RocksDB")?;

-            Ok(Arc::new(Box::new(db) as Box<dyn Database>))
+            Ok(Arc::new(db) as Arc<dyn Database>)
         }
         StorageBackend::InMemory => Ok(Arc::new(
-            Box::new(InMemoryDatabase::new()) as Box<dyn Database>
+            InMemoryDatabase::new()
         )),
         StorageBackend::Redis(cfg) => {
             let db = RedisConnection::new(cfg)
                 .map_err(|e| GeneralError::InitializationError(e.to_string()))
                 .context("Failed to initialize Redis")?;
-            Ok(Arc::new(Box::new(db) as Box<dyn Database>))
+            Ok(Arc::new(db) as Arc<dyn Database>)
         }
     }
 }

86-86: Include default value for celestia_start_height.

Consider setting a default value for celestia_start_height to ensure consistent behavior when the argument is not provided.

Apply this diff:

     /// Height to start searching the DA layer for SNARKs on
     #[arg(short = 's', long)]
+    #[arg(default_value_t = 0)]
     celestia_start_height: Option<u64>,
crates/storage/src/database.rs (1)

8-13: Document the StorageBackend enum and its variants.

Adding documentation comments to the StorageBackend enum and its variants improves code readability and maintainability.

Apply this diff:

 /// Enum representing the different storage backends available.
 #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
 pub enum StorageBackend {
+    /// Uses RocksDB for persistent storage.
     RocksDB(crate::rocksdb::RocksDBConfig),
+    /// Uses an in-memory database, data is lost on shutdown.
     InMemory,
+    /// Uses Redis for storage.
     Redis(crate::redis::RedisConfig),
 }
crates/tests/src/lib.rs (1)

15-18: Avoid redundant boxing of the database object.

In the setup_db function, the database object is being boxed and then wrapped in an Arc. This double boxing is unnecessary.

Apply this diff:

 use prism_storage::{
     rocksdb::{RocksDBConfig, RocksDBConnection},
     Database,
 };
 use rand::{rngs::StdRng, Rng, SeedableRng};

 fn setup_db() -> Arc<dyn Database> {
     let temp_dir = TempDir::new().unwrap();
     let cfg = RocksDBConfig::new(temp_dir.path().to_str().unwrap());
-    let db = RocksDBConnection::new(&cfg).unwrap();
-    Arc::new(Box::new(db) as Box<dyn Database>)
+    let db: Arc<dyn Database> = Arc::new(RocksDBConnection::new(&cfg).unwrap());
+    db
 }
crates/storage/src/rocksdb.rs (2)

29-35: Consider adding path validation.

The constructor accepts any string as a path without validation. Consider adding basic path validation to ensure the path is valid and accessible.

 impl RocksDBConfig {
     pub fn new(path: &str) -> Self {
+        // Validate path
+        let path = std::path::Path::new(path);
+        if !path.parent().map_or(true, |p| p.exists()) {
+            std::fs::create_dir_all(path.parent().unwrap()).expect("Failed to create directory");
+        }
         Self {
-            path: path.to_string(),
+            path: path.to_str().unwrap().to_string(),
         }
     }
 }

44-45: Consider adding database options configuration.

The implementation uses default RocksDB options. Consider allowing customization of database options through the config struct for better performance tuning.

crates/cli/src/main.rs (1)

104-107: Consider structured logging for errors.

The error logging could be enhanced with structured fields to provide more context about the failure.

-                error!("error initializing prover: {}", e);
+                error!(error = %e, component = "prover", "Failed to initialize prover");

Also applies to: 159-162

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2666b43 and 0b52e15.

📒 Files selected for processing (7)
  • crates/cli/src/cfg.rs (9 hunks)
  • crates/cli/src/main.rs (5 hunks)
  • crates/storage/src/database.rs (1 hunks)
  • crates/storage/src/redis.rs (1 hunks)
  • crates/storage/src/rocksdb.rs (2 hunks)
  • crates/tests/src/lib.rs (2 hunks)
  • justfile (0 hunks)
💤 Files with no reviewable changes (1)
  • justfile
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: integration-test
  • GitHub Check: unused dependencies
  • GitHub Check: clippy
  • GitHub Check: unit-test
  • GitHub Check: build-and-push-image
🔇 Additional comments (9)
crates/cli/src/cfg.rs (3)

124-124: Ensure default configuration aligns with user expectations.

When creating a default Config with with_home, confirm that setting RocksDB as the default StorageBackend is appropriate, especially if the user hasn't explicitly configured it.

Consider whether InMemory might be a safer default to prevent unexpected disk usage.


225-232: Handle missing database configuration parameters gracefully.

When db_type is Redis or RocksDB, ensure that redis_url or rocksdb_path are provided. Currently, missing parameters might lead to defaults that could cause unexpected behavior.

Run the following script to check if appropriate error handling is in place:


185-191: Simplify path construction and handle potential errors.

Ensure that the constructed home path is valid and handle cases where the home directory might not be available.

Modify the code as follows:

 fn get_prism_home(args: &CommandArgs) -> Result<String> {
-    let network_name = args.network_name.clone().unwrap_or_else(|| "custom".to_string());
-    args.home_path
-        .clone()
-        .or_else(|| {
-            home_dir().map(|path| format!("{}/.prism/{}/", path.to_string_lossy(), network_name))
-        })
+    let network_name = args.network_name.clone();
+    let home = args.home_path.clone().or_else(|| {
+        home_dir().map(|path| path.to_string_lossy().to_string())
+    });
+    let prism_home = format!("{}/.prism/{}/", home.unwrap_or_default(), network_name);
     .ok_or_else(|| {
         GeneralError::MissingArgumentError("could not determine config path".to_string()).into()
     })
 }

Confirm that the application handles cases where the home directory is not available.

crates/storage/src/database.rs (1)

8-13: Consider consistent naming for storage backends.

Ensure that the naming of storage backends is consistent across the codebase. For example, use RocksDb instead of RocksDB for consistency.

Apply this diff:

 pub enum StorageBackend {
-    RocksDB(crate::rocksdb::RocksDBConfig),
+    RocksDb(crate::rocksdb::RocksDBConfig),
     InMemory,
-    Redis(crate::redis::RedisConfig),
+    RedisDb(crate::redis::RedisConfig),
 }

Confirm that renaming does not break any references elsewhere in the codebase.

crates/tests/src/lib.rs (1)

30-31: ⚠️ Potential issue

Handle potential None value from temp_dir.path().to_str().

The to_str() method can return None if the path is not valid UTF-8. Handle this case to prevent potential errors.

Apply this diff:

 let temp_dir = TempDir::new().unwrap();
-let cfg = RocksDBConfig::new(temp_dir.path().to_str().unwrap());
+let temp_path = temp_dir.path().to_str().expect("Temp path is not valid UTF-8");
+let cfg = RocksDBConfig::new(temp_path);

Ensure that the test fails gracefully if the path is invalid.

crates/storage/src/redis.rs (2)

26-26: LGTM! Adding PartialEq and Eq traits.

The addition of these traits allows for equality comparisons of RedisConfig instances, which is good practice for configuration types.


Line range hint 1-200: Verify if this file should be removed.

According to the PR objectives, Redis is being removed from dependencies and RocksDB is being set as the default database. However, this file still contains the Redis implementation.

crates/storage/src/rocksdb.rs (1)

24-27: LGTM! Well-structured config type.

The RocksDBConfig struct is properly defined with appropriate derive attributes for serialization, comparison, and debugging.

crates/cli/src/main.rs (1)

69-70: LGTM! Consistent database initialization.

The database initialization is implemented consistently across both Prover and FullNode commands with proper error handling.

Also applies to: 117-118

crates/cli/src/cfg.rs Show resolved Hide resolved
crates/cli/src/cfg.rs Show resolved Hide resolved
Copy link
Contributor

@smuu smuu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work, this is great!
Only a few small things

#[derive(Args, Deserialize, Clone, Debug)]
pub struct DatabaseArgs {
#[arg(long, value_enum)]
db_type: Option<DBValues>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document what the default is


/// Path to the RocksDB database, used when `db_type` is `rocks-db`
#[arg(long)]
rocksdb_path: Option<String>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I propose to have the default path <homePath>/data instead of <homePath>.
Currently, all the data files and config are in the same folder.


/// Connection string to Redis, used when `db_type` is `redis`
#[arg(long)]
redis_url: Option<String>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve error handling:
If db_type is redis throw an error saying the user needs to set redis_url.

@@ -43,7 +49,10 @@ pub struct CommandArgs {
verifying_key_algorithm: Option<String>,

#[arg(long)]
config_path: Option<String>,
home_path: Option<String>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

improvement(prism-prover): Use RocksDB as default
2 participants