From b9969c5b1c7483f009620403c1d3ebc9869964df Mon Sep 17 00:00:00 2001 From: Derek Cofausper <256792747+decofe@users.noreply.github.com> Date: Thu, 12 Mar 2026 09:59:18 -0700 Subject: [PATCH] chore: remove rocksdb and edge feature gates, default to storage v2 (#22954) Co-authored-by: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com> --- .github/workflows/docker-test.yml | 2 +- .github/workflows/e2e.yml | 2 +- .github/workflows/hive.yml | 21 +- .github/workflows/integration.yml | 5 +- .github/workflows/unit.yml | 6 +- bin/reth/Cargo.toml | 3 - crates/cli/commands/Cargo.toml | 4 - crates/cli/commands/src/db/checksum/mod.rs | 3 - crates/cli/commands/src/import_core.rs | 17 +- crates/cli/commands/src/prune.rs | 2 - crates/e2e-test-utils/Cargo.toml | 5 - crates/e2e-test-utils/tests/rocksdb/main.rs | 2 - crates/engine/tree/Cargo.toml | 7 - crates/ethereum/cli/Cargo.toml | 5 - crates/exex/exex/Cargo.toml | 2 - crates/node/core/Cargo.toml | 6 - crates/prune/prune/Cargo.toml | 5 +- .../src/segments/user/account_history.rs | 153 ----------- .../src/segments/user/storage_history.rs | 156 ------------ .../src/segments/user/transaction_lookup.rs | 4 - crates/stages/stages/Cargo.toml | 2 - .../src/stages/index_account_history.rs | 6 +- .../src/stages/index_storage_history.rs | 5 +- crates/stages/stages/src/stages/tx_lookup.rs | 5 +- crates/static-file/static-file/Cargo.toml | 3 - crates/storage/db-api/Cargo.toml | 2 - crates/storage/db-api/src/models/metadata.rs | 14 +- crates/storage/db-common/Cargo.toml | 4 - crates/storage/db-common/src/init.rs | 8 - crates/storage/provider/Cargo.toml | 6 +- crates/storage/provider/src/either_writer.rs | 79 +----- .../src/providers/blockchain_provider.rs | 2 - .../provider/src/providers/database/mod.rs | 2 - .../src/providers/database/provider.rs | 90 ++----- crates/storage/provider/src/providers/mod.rs | 4 - .../provider/src/providers/rocksdb_stub.rs | 239 ------------------ .../src/providers/state/historical.rs | 1 - .../storage/provider/src/test_utils/noop.rs | 2 - .../provider/src/traits/rocksdb_provider.rs | 59 ++--- crates/storage/storage-api/Cargo.toml | 2 - docker-bake.hcl | 26 +- 41 files changed, 84 insertions(+), 887 deletions(-) delete mode 100644 crates/storage/provider/src/providers/rocksdb_stub.rs diff --git a/.github/workflows/docker-test.yml b/.github/workflows/docker-test.yml index 05208bc523..7bdf3397b8 100644 --- a/.github/workflows/docker-test.yml +++ b/.github/workflows/docker-test.yml @@ -6,7 +6,7 @@ on: hive_target: required: true type: string - description: "Docker bake target to build (e.g. hive-stable, hive-edge)" + description: "Docker bake target to build (e.g. hive)" artifact_name: required: false type: string diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 291e7c28aa..cbb52f21eb 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -63,6 +63,6 @@ jobs: run: | cargo nextest run \ --no-fail-fast \ - --locked --features "edge" \ + --locked \ -p reth-e2e-test-utils \ -E 'binary(rocksdb)' diff --git a/.github/workflows/hive.yml b/.github/workflows/hive.yml index f2d10bc9bb..ecb2496660 100644 --- a/.github/workflows/hive.yml +++ b/.github/workflows/hive.yml @@ -15,18 +15,11 @@ concurrency: cancel-in-progress: true jobs: - build-reth-stable: + build-reth: uses: ./.github/workflows/docker-test.yml with: - hive_target: hive-stable - artifact_name: "reth-stable" - secrets: inherit - - build-reth-edge: - uses: ./.github/workflows/docker-test.yml - with: - hive_target: hive-edge - artifact_name: "reth-edge" + hive_target: hive + artifact_name: "reth" secrets: inherit prepare-hive: @@ -84,7 +77,6 @@ jobs: strategy: fail-fast: false matrix: - storage: [stable, edge] # ethereum/rpc to be deprecated: # https://github.com/ethereum/hive/pull/1117 scenario: @@ -184,10 +176,9 @@ jobs: - sim: ethereum/eels/consume-rlp limit: .*tests/paris.* needs: - - build-reth-stable - - build-reth-edge + - build-reth - prepare-hive - name: ${{ matrix.storage }} / ${{ matrix.scenario.sim }}${{ matrix.scenario.limit && format(' - {0}', matrix.scenario.limit) }} + name: ${{ matrix.scenario.sim }}${{ matrix.scenario.limit && format(' - {0}', matrix.scenario.limit) }} # Use larger runners for eels tests to avoid OOM runner crashes runs-on: ${{ github.repository == 'paradigmxyz/reth' && (contains(matrix.scenario.sim, 'eels') && 'depot-ubuntu-latest-8' || 'depot-ubuntu-latest-4') || 'ubuntu-latest' }} permissions: @@ -206,7 +197,7 @@ jobs: - name: Download reth image uses: actions/download-artifact@v8 with: - name: reth-${{ matrix.storage }} + name: reth path: /tmp - name: Load Docker images diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index c5d2ea7315..1dee15f09d 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -22,7 +22,7 @@ concurrency: jobs: test: - name: test / ${{ matrix.network }} / ${{ matrix.storage }} + name: test / ${{ matrix.network }} if: github.event_name != 'schedule' runs-on: ${{ github.repository == 'paradigmxyz/reth' && 'depot-ubuntu-latest-4' || 'ubuntu-latest' }} env: @@ -30,7 +30,6 @@ jobs: strategy: matrix: network: ["ethereum"] - storage: ["stable", "edge"] timeout-minutes: 60 steps: - uses: actions/checkout@v6 @@ -47,7 +46,7 @@ jobs: run: | cargo nextest run \ --no-fail-fast \ - --locked --features "asm-keccak ${{ matrix.network }} ${{ matrix.storage == 'edge' && 'edge' || '' }}" \ + --locked --features "asm-keccak ${{ matrix.network }}" \ --workspace --exclude ef-tests \ -E "kind(test) and not binary(e2e_testsuite)" diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml index 3afee812b6..05ed80a2ba 100644 --- a/.github/workflows/unit.yml +++ b/.github/workflows/unit.yml @@ -19,15 +19,13 @@ concurrency: jobs: test: - name: test / ${{ matrix.type }} / ${{ matrix.storage }} + name: test / ${{ matrix.type }} runs-on: ${{ github.repository == 'paradigmxyz/reth' && 'depot-ubuntu-latest-4' || 'ubuntu-latest' }} env: RUST_BACKTRACE: 1 - EDGE_FEATURES: ${{ matrix.storage == 'edge' && 'edge' || '' }} strategy: matrix: type: [ethereum] - storage: [stable, edge] include: - type: ethereum features: asm-keccak ethereum @@ -50,7 +48,7 @@ jobs: run: | cargo nextest run \ --no-fail-fast \ - --features "${{ matrix.features }} $EDGE_FEATURES" --locked \ + --features "${{ matrix.features }}" --locked \ ${{ matrix.exclude_args }} --workspace \ --exclude ef-tests --no-tests=warn \ -E "!kind(test) and not binary(e2e_testsuite)" diff --git a/bin/reth/Cargo.toml b/bin/reth/Cargo.toml index 805733d747..cfb4146464 100644 --- a/bin/reth/Cargo.toml +++ b/bin/reth/Cargo.toml @@ -89,7 +89,6 @@ default = [ "keccak-cache-global", "asm-keccak", "min-debug-logs", - "rocksdb", ] otlp = [ @@ -191,8 +190,6 @@ min-trace-logs = [ ] trie-debug = ["reth-node-builder/trie-debug", "reth-node-core/trie-debug"] -rocksdb = ["reth-ethereum-cli/rocksdb", "reth-node-core/rocksdb"] -edge = ["rocksdb"] [[bin]] name = "reth" diff --git a/crates/cli/commands/Cargo.toml b/crates/cli/commands/Cargo.toml index a572ebbf9d..a78d19cfe4 100644 --- a/crates/cli/commands/Cargo.toml +++ b/crates/cli/commands/Cargo.toml @@ -110,7 +110,6 @@ reth-provider = { workspace = true, features = ["test-utils"] } tempfile.workspace = true [features] -default = [] arbitrary = [ "dep:proptest", "dep:arbitrary", @@ -135,6 +134,3 @@ arbitrary = [ "reth-primitives-traits/arbitrary", "reth-ethereum-primitives/arbitrary", ] - -rocksdb = ["reth-db-common/rocksdb", "reth-stages/rocksdb", "reth-provider/rocksdb", "reth-prune/rocksdb"] -edge = ["rocksdb"] diff --git a/crates/cli/commands/src/db/checksum/mod.rs b/crates/cli/commands/src/db/checksum/mod.rs index 9214c9987b..b5b4c79dac 100644 --- a/crates/cli/commands/src/db/checksum/mod.rs +++ b/crates/cli/commands/src/db/checksum/mod.rs @@ -21,7 +21,6 @@ use std::{ }; use tracing::{info, warn}; -#[cfg(all(unix, feature = "rocksdb"))] mod rocksdb; /// Interval for logging progress during checksum computation. @@ -73,7 +72,6 @@ enum Subcommand { limit: Option, }, /// Calculates the checksum of a RocksDB table - #[cfg(all(unix, feature = "rocksdb"))] Rocksdb { /// The RocksDB table #[arg(value_enum)] @@ -100,7 +98,6 @@ impl Command { Subcommand::StaticFile { segment, start_block, end_block, limit } => { checksum_static_file(tool, segment, start_block, end_block, limit)?; } - #[cfg(all(unix, feature = "rocksdb"))] Subcommand::Rocksdb { table, limit } => { rocksdb::checksum_rocksdb(tool, table, limit)?; } diff --git a/crates/cli/commands/src/import_core.rs b/crates/cli/commands/src/import_core.rs index 2bcf930a75..48f9e27738 100644 --- a/crates/cli/commands/src/import_core.rs +++ b/crates/cli/commands/src/import_core.rs @@ -19,11 +19,12 @@ use reth_node_api::BlockTy; use reth_node_events::node::NodeEvent; use reth_provider::{ providers::ProviderNodeTypes, BlockNumReader, HeaderProvider, ProviderError, ProviderFactory, - StageCheckpointReader, + RocksDBProviderFactory, StageCheckpointReader, }; use reth_prune::PruneModes; use reth_stages::{prelude::*, ControlFlow, Pipeline, StageId, StageSet}; use reth_static_file::StaticFileProducer; +use reth_storage_api::StorageSettingsCache; use std::{path::Path, sync::Arc}; use tokio::sync::watch; use tracing::{debug, error, info, warn}; @@ -108,7 +109,11 @@ where let provider = provider_factory.provider()?; let init_blocks = provider.tx_ref().entries::()?; - let init_txns = provider.tx_ref().entries::()?; + let init_txns = if provider_factory.cached_storage_settings().storage_v2 { + provider_factory.rocksdb_provider().iter::()?.count() + } else { + provider.tx_ref().entries::()? + }; drop(provider); let mut total_decoded_blocks = 0; @@ -215,8 +220,12 @@ where let provider = provider_factory.provider()?; let total_imported_blocks = provider.tx_ref().entries::()? - init_blocks; - let total_imported_txns = - provider.tx_ref().entries::()? - init_txns; + let current_txns = if provider_factory.cached_storage_settings().storage_v2 { + provider_factory.rocksdb_provider().iter::()?.count() + } else { + provider.tx_ref().entries::()? + }; + let total_imported_txns = current_txns - init_txns; let result = ImportResult { total_decoded_blocks, diff --git a/crates/cli/commands/src/prune.rs b/crates/cli/commands/src/prune.rs index 45837f72dd..a48847f751 100644 --- a/crates/cli/commands/src/prune.rs +++ b/crates/cli/commands/src/prune.rs @@ -12,7 +12,6 @@ use reth_node_metrics::{ server::{MetricServer, MetricServerConfig}, version::VersionInfo, }; -#[cfg(all(unix, feature = "rocksdb"))] use reth_provider::RocksDBProviderFactory; use reth_prune::PrunerBuilder; use reth_static_file::StaticFileProducer; @@ -122,7 +121,6 @@ impl> PruneComma } // Flush and compact RocksDB to reclaim disk space after pruning - #[cfg(all(unix, feature = "rocksdb"))] { info!(target: "reth::cli", "Flushing and compacting RocksDB..."); provider_factory.rocksdb_provider().flush_and_compact()?; diff --git a/crates/e2e-test-utils/Cargo.toml b/crates/e2e-test-utils/Cargo.toml index d9c62109c2..3998a54d93 100644 --- a/crates/e2e-test-utils/Cargo.toml +++ b/crates/e2e-test-utils/Cargo.toml @@ -75,8 +75,3 @@ path = "tests/e2e-testsuite/main.rs" [[test]] name = "rocksdb" path = "tests/rocksdb/main.rs" -required-features = ["rocksdb"] - -[features] -rocksdb = ["reth-node-core/rocksdb", "reth-provider/rocksdb", "reth-cli-commands/rocksdb"] -edge = ["rocksdb"] diff --git a/crates/e2e-test-utils/tests/rocksdb/main.rs b/crates/e2e-test-utils/tests/rocksdb/main.rs index 3e14426ab6..eb034257cf 100644 --- a/crates/e2e-test-utils/tests/rocksdb/main.rs +++ b/crates/e2e-test-utils/tests/rocksdb/main.rs @@ -1,7 +1,5 @@ //! E2E tests for `RocksDB` provider functionality. -#![cfg(all(feature = "rocksdb", unix))] - use alloy_consensus::BlockHeader; use alloy_primitives::B256; use alloy_rpc_types_eth::{Transaction, TransactionReceipt}; diff --git a/crates/engine/tree/Cargo.toml b/crates/engine/tree/Cargo.toml index 660dd179ea..a7ef47fd29 100644 --- a/crates/engine/tree/Cargo.toml +++ b/crates/engine/tree/Cargo.toml @@ -139,13 +139,6 @@ trie-debug = [ "reth-engine-primitives/trie-debug", "dep:serde_json", ] -rocksdb = [ - "reth-provider/rocksdb", - "reth-prune/rocksdb", - "reth-stages?/rocksdb", - "reth-e2e-test-utils/rocksdb", -] -edge = ["rocksdb"] [[test]] name = "e2e_testsuite" diff --git a/crates/ethereum/cli/Cargo.toml b/crates/ethereum/cli/Cargo.toml index bb31b0a70c..250317de0d 100644 --- a/crates/ethereum/cli/Cargo.toml +++ b/crates/ethereum/cli/Cargo.toml @@ -36,8 +36,6 @@ tracing.workspace = true tempfile.workspace = true [features] -default = [] - otlp = ["reth-tracing/otlp", "reth-node-core/otlp"] otlp-logs = ["reth-tracing/otlp-logs", "reth-node-core/otlp-logs"] @@ -89,6 +87,3 @@ min-trace-logs = [ "tracing/release_max_level_trace", "reth-node-core/min-trace-logs", ] - -rocksdb = ["reth-cli-commands/rocksdb"] -edge = ["rocksdb"] diff --git a/crates/exex/exex/Cargo.toml b/crates/exex/exex/Cargo.toml index 28712c576c..f89032b083 100644 --- a/crates/exex/exex/Cargo.toml +++ b/crates/exex/exex/Cargo.toml @@ -66,8 +66,6 @@ secp256k1.workspace = true tempfile.workspace = true [features] -default = [] -edge = ["reth-provider/edge"] serde = [ "reth-exex-types/serde", "reth-revm/serde", diff --git a/crates/node/core/Cargo.toml b/crates/node/core/Cargo.toml index dc7c6d2e16..780ec326c3 100644 --- a/crates/node/core/Cargo.toml +++ b/crates/node/core/Cargo.toml @@ -93,12 +93,6 @@ min-trace-logs = ["tracing/release_max_level_trace"] # Debug recording for sparse trie mutations trie-debug = ["reth-engine-primitives/trie-debug"] -# Route supported tables to RocksDB instead of MDBX -rocksdb = ["reth-storage-api/rocksdb"] - -# Marker feature for edge/unstable builds - enables rocksdb and sets v2 defaults -edge = ["rocksdb"] - [build-dependencies] vergen = { workspace = true, features = ["build", "cargo", "emit_and_set"] } vergen-git2.workspace = true diff --git a/crates/prune/prune/Cargo.toml b/crates/prune/prune/Cargo.toml index f40252282f..d86a35eaf1 100644 --- a/crates/prune/prune/Cargo.toml +++ b/crates/prune/prune/Cargo.toml @@ -42,13 +42,10 @@ rayon.workspace = true tokio.workspace = true rustc-hash.workspace = true -[features] -rocksdb = ["reth-provider/rocksdb"] - [dev-dependencies] # reth reth-db = { workspace = true, features = ["test-utils"] } -reth-stages = { workspace = true, features = ["test-utils", "rocksdb"] } +reth-stages = { workspace = true, features = ["test-utils"] } reth-primitives-traits = { workspace = true, features = ["arbitrary"] } reth-testing-utils.workspace = true reth-tracing.workspace = true diff --git a/crates/prune/prune/src/segments/user/account_history.rs b/crates/prune/prune/src/segments/user/account_history.rs index 4f98d5a3fa..af3acb774e 100644 --- a/crates/prune/prune/src/segments/user/account_history.rs +++ b/crates/prune/prune/src/segments/user/account_history.rs @@ -74,7 +74,6 @@ where let range_end = *range.end(); // Check where account history indices are stored - #[cfg(all(unix, feature = "rocksdb"))] if provider.cached_storage_settings().storage_v2 { return self.prune_rocksdb(provider, input, range, range_end); } @@ -232,7 +231,6 @@ impl AccountHistory { /// /// Reads account changesets from static files and prunes the corresponding /// `RocksDB` history shards. - #[cfg(all(unix, feature = "rocksdb"))] fn prune_rocksdb( &self, provider: &Provider, @@ -506,157 +504,6 @@ mod tests { test_prune(1400, 3, (PruneProgress::Finished, 804)); } - /// Tests the `prune_static_files` code path. On unix with rocksdb feature, v2 storage - /// routes to `prune_rocksdb` instead, so this test only runs without rocksdb (the - /// `prune_rocksdb_path` test covers that configuration). - #[test] - #[cfg(not(all(unix, feature = "rocksdb")))] - fn prune_static_file() { - let db = TestStageDB::default(); - let mut rng = generators::rng(); - - let blocks = random_block_range( - &mut rng, - 0..=5000, - BlockRangeParams { parent: Some(B256::ZERO), tx_count: 0..1, ..Default::default() }, - ); - db.insert_blocks(blocks.iter(), StorageKind::Database(None)).expect("insert blocks"); - - let accounts = random_eoa_accounts(&mut rng, 2).into_iter().collect::>(); - - let (changesets, _) = random_changeset_range( - &mut rng, - blocks.iter(), - accounts.into_iter().map(|(addr, acc)| (addr, (acc, Vec::new()))), - 0..0, - 0..0, - ); - - db.insert_changesets_to_static_files(changesets.clone(), None) - .expect("insert changesets to static files"); - db.insert_history(changesets.clone(), None).expect("insert history"); - - let account_occurrences = db.table::().unwrap().into_iter().fold( - BTreeMap::<_, usize>::new(), - |mut map, (key, _)| { - map.entry(key.key).or_default().add_assign(1); - map - }, - ); - assert!(account_occurrences.into_iter().any(|(_, occurrences)| occurrences > 1)); - - let original_shards = db.table::().unwrap(); - - let test_prune = - |to_block: BlockNumber, run: usize, expected_result: (PruneProgress, usize)| { - let prune_mode = PruneMode::Before(to_block); - let deleted_entries_limit = 2000; - let mut limiter = - PruneLimiter::default().set_deleted_entries_limit(deleted_entries_limit); - let input = PruneInput { - previous_checkpoint: db - .factory - .provider() - .unwrap() - .get_prune_checkpoint(PruneSegment::AccountHistory) - .unwrap(), - to_block, - limiter: limiter.clone(), - }; - let segment = AccountHistory::new(prune_mode); - - let provider = db.factory.database_provider_rw().unwrap(); - provider.set_storage_settings_cache(StorageSettings::v2()); - let result = segment.prune(&provider, input).unwrap(); - limiter.increment_deleted_entries_count_by(result.pruned); - - assert_matches!( - result, - SegmentOutput {progress, pruned, checkpoint: Some(_)} - if (progress, pruned) == expected_result - ); - - segment - .save_checkpoint( - &provider, - result.checkpoint.unwrap().as_prune_checkpoint(prune_mode), - ) - .unwrap(); - provider.commit().expect("commit"); - - let changesets = changesets - .iter() - .enumerate() - .flat_map(|(block_number, changeset)| { - changeset.iter().map(move |change| (block_number, change)) - }) - .collect::>(); - - #[expect(clippy::skip_while_next)] - let pruned = changesets - .iter() - .enumerate() - .skip_while(|(i, (block_number, _))| { - *i < deleted_entries_limit / ACCOUNT_HISTORY_TABLES_TO_PRUNE * run && - *block_number <= to_block as usize - }) - .next() - .map(|(i, _)| i) - .unwrap_or_default(); - - // Skip what we've pruned so far, subtracting one to get last pruned block number - // further down - let mut pruned_changesets = changesets.iter().skip(pruned.saturating_sub(1)); - - let last_pruned_block_number = pruned_changesets - .next() - .map(|(block_number, _)| { - (if result.progress.is_finished() { - *block_number - } else { - block_number.saturating_sub(1) - }) as BlockNumber - }) - .unwrap_or(to_block); - - let actual_shards = db.table::().unwrap(); - - let expected_shards = original_shards - .iter() - .filter(|(key, _)| key.highest_block_number > last_pruned_block_number) - .map(|(key, blocks)| { - let new_blocks = - blocks.iter().skip_while(|block| *block <= last_pruned_block_number); - (key.clone(), BlockNumberList::new_pre_sorted(new_blocks)) - }) - .collect::>(); - - assert_eq!(actual_shards, expected_shards); - - assert_eq!( - db.factory - .provider() - .unwrap() - .get_prune_checkpoint(PruneSegment::AccountHistory) - .unwrap(), - Some(PruneCheckpoint { - block_number: Some(last_pruned_block_number), - tx_number: None, - prune_mode - }) - ); - }; - - test_prune( - 998, - 1, - (PruneProgress::HasMoreData(PruneInterruptReason::DeletedEntriesLimitReached), 1000), - ); - test_prune(998, 2, (PruneProgress::Finished, 1000)); - test_prune(1400, 3, (PruneProgress::Finished, 804)); - } - - #[cfg(all(unix, feature = "rocksdb"))] #[test] fn prune_rocksdb_path() { use reth_db_api::models::ShardedKey; diff --git a/crates/prune/prune/src/segments/user/storage_history.rs b/crates/prune/prune/src/segments/user/storage_history.rs index fee49ff91e..c475b7e61d 100644 --- a/crates/prune/prune/src/segments/user/storage_history.rs +++ b/crates/prune/prune/src/segments/user/storage_history.rs @@ -75,7 +75,6 @@ where let range_end = *range.end(); // Check where storage history indices are stored - #[cfg(all(unix, feature = "rocksdb"))] if provider.cached_storage_settings().storage_v2 { return self.prune_rocksdb(provider, input, range, range_end); } @@ -236,7 +235,6 @@ impl StorageHistory { /// /// Reads storage changesets from static files and prunes the corresponding /// `RocksDB` history shards. - #[cfg(all(unix, feature = "rocksdb"))] fn prune_rocksdb( &self, provider: &Provider, @@ -518,159 +516,6 @@ mod tests { test_prune(1200, 3, (PruneProgress::Finished, 202)); } - /// Tests the `prune_static_files` code path. On unix with rocksdb feature, v2 storage - /// routes to `prune_rocksdb` instead, so this test only runs without rocksdb (the - /// `prune_rocksdb_path` test covers that configuration). - #[test] - #[cfg(not(all(unix, feature = "rocksdb")))] - fn prune_static_file() { - let db = TestStageDB::default(); - let mut rng = generators::rng(); - - let blocks = random_block_range( - &mut rng, - 0..=5000, - BlockRangeParams { parent: Some(B256::ZERO), tx_count: 0..1, ..Default::default() }, - ); - db.insert_blocks(blocks.iter(), StorageKind::Database(None)).expect("insert blocks"); - - let accounts = random_eoa_accounts(&mut rng, 2).into_iter().collect::>(); - - let (changesets, _) = random_changeset_range( - &mut rng, - blocks.iter(), - accounts.into_iter().map(|(addr, acc)| (addr, (acc, Vec::new()))), - 1..2, - 1..2, - ); - - db.insert_changesets_to_static_files(changesets.clone(), None) - .expect("insert changesets to static files"); - db.insert_history(changesets.clone(), None).expect("insert history"); - - let storage_occurrences = db.table::().unwrap().into_iter().fold( - BTreeMap::<_, usize>::new(), - |mut map, (key, _)| { - map.entry((key.address, key.sharded_key.key)).or_default().add_assign(1); - map - }, - ); - assert!(storage_occurrences.into_iter().any(|(_, occurrences)| occurrences > 1)); - - let original_shards = db.table::().unwrap(); - - let test_prune = |to_block: BlockNumber, - run: usize, - expected_result: (PruneProgress, usize)| { - let prune_mode = PruneMode::Before(to_block); - let deleted_entries_limit = 1000; - let mut limiter = - PruneLimiter::default().set_deleted_entries_limit(deleted_entries_limit); - let input = PruneInput { - previous_checkpoint: db - .factory - .provider() - .unwrap() - .get_prune_checkpoint(PruneSegment::StorageHistory) - .unwrap(), - to_block, - limiter: limiter.clone(), - }; - let segment = StorageHistory::new(prune_mode); - - let provider = db.factory.database_provider_rw().unwrap(); - provider.set_storage_settings_cache(StorageSettings::v2()); - let result = segment.prune(&provider, input).unwrap(); - limiter.increment_deleted_entries_count_by(result.pruned); - - assert_matches!( - result, - SegmentOutput {progress, pruned, checkpoint: Some(_)} - if (progress, pruned) == expected_result - ); - - segment - .save_checkpoint( - &provider, - result.checkpoint.unwrap().as_prune_checkpoint(prune_mode), - ) - .unwrap(); - provider.commit().expect("commit"); - - let changesets = changesets - .iter() - .enumerate() - .flat_map(|(block_number, changeset)| { - changeset.iter().flat_map(move |(address, _, entries)| { - entries.iter().map(move |entry| (block_number, address, entry)) - }) - }) - .collect::>(); - - #[expect(clippy::skip_while_next)] - let pruned = changesets - .iter() - .enumerate() - .skip_while(|(i, (block_number, _, _))| { - *i < deleted_entries_limit / STORAGE_HISTORY_TABLES_TO_PRUNE * run && - *block_number <= to_block as usize - }) - .next() - .map(|(i, _)| i) - .unwrap_or_default(); - - // Skip what we've pruned so far, subtracting one to get last pruned block number - // further down - let mut pruned_changesets = changesets.iter().skip(pruned.saturating_sub(1)); - - let last_pruned_block_number = pruned_changesets - .next() - .map(|(block_number, _, _)| { - (if result.progress.is_finished() { - *block_number - } else { - block_number.saturating_sub(1) - }) as BlockNumber - }) - .unwrap_or(to_block); - - let actual_shards = db.table::().unwrap(); - - let expected_shards = original_shards - .iter() - .filter(|(key, _)| key.sharded_key.highest_block_number > last_pruned_block_number) - .map(|(key, blocks)| { - let new_blocks = - blocks.iter().skip_while(|block| *block <= last_pruned_block_number); - (key.clone(), BlockNumberList::new_pre_sorted(new_blocks)) - }) - .collect::>(); - - assert_eq!(actual_shards, expected_shards); - - assert_eq!( - db.factory - .provider() - .unwrap() - .get_prune_checkpoint(PruneSegment::StorageHistory) - .unwrap(), - Some(PruneCheckpoint { - block_number: Some(last_pruned_block_number), - tx_number: None, - prune_mode - }) - ); - }; - - test_prune( - 998, - 1, - (PruneProgress::HasMoreData(PruneInterruptReason::DeletedEntriesLimitReached), 500), - ); - test_prune(998, 2, (PruneProgress::Finished, 500)); - test_prune(1200, 3, (PruneProgress::Finished, 202)); - } - /// Tests that when a limiter stops mid-block (with multiple storage changes for the same /// block), the checkpoint is set to `block_number - 1` to avoid dangling index entries. #[test] @@ -821,7 +666,6 @@ mod tests { assert!(final_changesets.is_empty(), "All changesets up to block 10 should be pruned"); } - #[cfg(all(unix, feature = "rocksdb"))] #[test] fn prune_rocksdb() { use reth_db_api::models::storage_sharded_key::StorageShardedKey; diff --git a/crates/prune/prune/src/segments/user/transaction_lookup.rs b/crates/prune/prune/src/segments/user/transaction_lookup.rs index deb02dbc9a..41d9ffae35 100644 --- a/crates/prune/prune/src/segments/user/transaction_lookup.rs +++ b/crates/prune/prune/src/segments/user/transaction_lookup.rs @@ -95,7 +95,6 @@ where .into_inner(); // Check where transaction hash numbers are stored - #[cfg(all(unix, feature = "rocksdb"))] if provider.cached_storage_settings().storage_v2 { return self.prune_rocksdb(provider, input, start, end); } @@ -196,7 +195,6 @@ impl TransactionLookup { /// /// Reads transactions from static files and deletes corresponding entries /// from the `RocksDB` `TransactionHashNumbers` table. - #[cfg(all(unix, feature = "rocksdb"))] fn prune_rocksdb( &self, provider: &Provider, @@ -438,7 +436,6 @@ mod tests { test_prune(10, (PruneProgress::Finished, 8)); } - #[cfg(all(unix, feature = "rocksdb"))] #[test] fn prune_rocksdb() { use reth_db_api::models::StorageSettings; @@ -539,7 +536,6 @@ mod tests { /// 1. Some transactions have already been pruned (checkpoint at tx 5) /// 2. The deleted entries limit is exhausted before any new deletions /// 3. The checkpoint should NOT advance to the next start position - #[cfg(all(unix, feature = "rocksdb"))] #[test] fn prune_rocksdb_zero_deleted_checkpoint() { use reth_db_api::models::StorageSettings; diff --git a/crates/stages/stages/Cargo.toml b/crates/stages/stages/Cargo.toml index aa77b5028c..877ec2709f 100644 --- a/crates/stages/stages/Cargo.toml +++ b/crates/stages/stages/Cargo.toml @@ -121,5 +121,3 @@ test-utils = [ "reth-evm-ethereum/test-utils", "reth-tasks/test-utils", ] -rocksdb = ["reth-provider/rocksdb", "reth-db-common/rocksdb"] -edge = ["rocksdb"] diff --git a/crates/stages/stages/src/stages/index_account_history.rs b/crates/stages/stages/src/stages/index_account_history.rs index 239dbae149..617be0a5ee 100644 --- a/crates/stages/stages/src/stages/index_account_history.rs +++ b/crates/stages/stages/src/stages/index_account_history.rs @@ -1,9 +1,7 @@ use super::collect_account_history_indices; use crate::stages::utils::{collect_history_indices, load_account_history}; use reth_config::config::{EtlConfig, IndexHistoryConfig}; -#[cfg(all(unix, feature = "rocksdb"))] -use reth_db_api::Tables; -use reth_db_api::{models::ShardedKey, tables, transaction::DbTxMut}; +use reth_db_api::{models::ShardedKey, tables, transaction::DbTxMut, Tables}; use reth_provider::{ DBProvider, EitherWriter, HistoryWriter, PruneCheckpointReader, PruneCheckpointWriter, RocksDBProviderFactory, StorageSettingsCache, @@ -144,7 +142,6 @@ where Ok(((), writer.into_raw_rocksdb_batch())) })?; - #[cfg(all(unix, feature = "rocksdb"))] if use_rocksdb { provider.commit_pending_rocksdb_batches()?; provider.rocksdb_provider().flush(&[Tables::AccountsHistory.name()])?; @@ -663,7 +660,6 @@ mod tests { } } - #[cfg(all(unix, feature = "rocksdb"))] mod rocksdb_tests { use super::*; use reth_provider::{ diff --git a/crates/stages/stages/src/stages/index_storage_history.rs b/crates/stages/stages/src/stages/index_storage_history.rs index 1f91aebb80..182bc1c96f 100644 --- a/crates/stages/stages/src/stages/index_storage_history.rs +++ b/crates/stages/stages/src/stages/index_storage_history.rs @@ -1,12 +1,11 @@ use super::{collect_history_indices, collect_storage_history_indices}; use crate::{stages::utils::load_storage_history, StageCheckpoint, StageId}; use reth_config::config::{EtlConfig, IndexHistoryConfig}; -#[cfg(all(unix, feature = "rocksdb"))] -use reth_db_api::Tables; use reth_db_api::{ models::{storage_sharded_key::StorageShardedKey, AddressStorageKey, BlockNumberAddress}, tables, transaction::DbTxMut, + Tables, }; use reth_provider::{ DBProvider, EitherWriter, HistoryWriter, PruneCheckpointReader, PruneCheckpointWriter, @@ -148,7 +147,6 @@ where Ok(((), writer.into_raw_rocksdb_batch())) })?; - #[cfg(all(unix, feature = "rocksdb"))] if use_rocksdb { provider.commit_pending_rocksdb_batches()?; provider.rocksdb_provider().flush(&[Tables::StoragesHistory.name()])?; @@ -691,7 +689,6 @@ mod tests { } } - #[cfg(all(unix, feature = "rocksdb"))] mod rocksdb_tests { use super::*; use reth_db_api::models::StorageBeforeTx; diff --git a/crates/stages/stages/src/stages/tx_lookup.rs b/crates/stages/stages/src/stages/tx_lookup.rs index e60355ae19..6940403976 100644 --- a/crates/stages/stages/src/stages/tx_lookup.rs +++ b/crates/stages/stages/src/stages/tx_lookup.rs @@ -2,12 +2,11 @@ use alloy_eips::eip2718::Encodable2718; use alloy_primitives::{TxHash, TxNumber}; use num_traits::Zero; use reth_config::config::{EtlConfig, TransactionLookupConfig}; -#[cfg(all(unix, feature = "rocksdb"))] -use reth_db_api::Tables; use reth_db_api::{ table::{Decode, Decompress, Value}, tables, transaction::DbTxMut, + Tables, }; use reth_etl::Collector; use reth_primitives_traits::{NodePrimitives, SignedTransaction}; @@ -199,7 +198,6 @@ where } } - #[cfg(all(unix, feature = "rocksdb"))] if provider.cached_storage_settings().storage_v2 { provider.commit_pending_rocksdb_batches()?; provider.rocksdb_provider().flush(&[Tables::TransactionHashNumbers.name()])?; @@ -601,7 +599,6 @@ mod tests { } } - #[cfg(all(unix, feature = "rocksdb"))] mod rocksdb_tests { use super::*; use reth_provider::RocksDBProviderFactory; diff --git a/crates/static-file/static-file/Cargo.toml b/crates/static-file/static-file/Cargo.toml index 0154fa8be7..d75151dfee 100644 --- a/crates/static-file/static-file/Cargo.toml +++ b/crates/static-file/static-file/Cargo.toml @@ -36,6 +36,3 @@ reth-testing-utils.workspace = true assert_matches.workspace = true tempfile.workspace = true - -[features] -edge = ["reth-stages/edge"] diff --git a/crates/storage/db-api/Cargo.toml b/crates/storage/db-api/Cargo.toml index 127d2d3efb..4248ed38a0 100644 --- a/crates/storage/db-api/Cargo.toml +++ b/crates/storage/db-api/Cargo.toml @@ -93,5 +93,3 @@ op = [ "reth-codecs/op", "reth-primitives-traits/op", ] -rocksdb = [] -edge = ["rocksdb"] diff --git a/crates/storage/db-api/src/models/metadata.rs b/crates/storage/db-api/src/models/metadata.rs index c8d1c5f8e3..67aa3ea2b6 100644 --- a/crates/storage/db-api/src/models/metadata.rs +++ b/crates/storage/db-api/src/models/metadata.rs @@ -28,20 +28,8 @@ pub struct StorageSettings { impl StorageSettings { /// Returns the default base `StorageSettings`. - /// - /// When the `edge` feature is enabled, returns [`Self::v2()`] so that CI and - /// edge builds automatically use v2 storage defaults. Otherwise returns - /// [`Self::v1()`]. The `--storage.v2` CLI flag can also opt into v2 at runtime - /// regardless of feature flags. pub const fn base() -> Self { - #[cfg(feature = "edge")] - { - Self::v2() - } - #[cfg(not(feature = "edge"))] - { - Self::v1() - } + Self::v2() } /// Creates `StorageSettings` for v2 nodes with all storage features enabled: diff --git a/crates/storage/db-common/Cargo.toml b/crates/storage/db-common/Cargo.toml index eb65423c6e..e023f2242a 100644 --- a/crates/storage/db-common/Cargo.toml +++ b/crates/storage/db-common/Cargo.toml @@ -46,9 +46,5 @@ reth-db = { workspace = true, features = ["mdbx"] } reth-provider = { workspace = true, features = ["test-utils"] } reth-tasks.workspace = true -[features] -rocksdb = ["reth-db-api/rocksdb", "reth-provider/rocksdb"] -edge = ["rocksdb"] - [lints] workspace = true diff --git a/crates/storage/db-common/src/init.rs b/crates/storage/db-common/src/init.rs index 07c6ca49b7..be78aa7238 100644 --- a/crates/storage/db-common/src/init.rs +++ b/crates/storage/db-common/src/init.rs @@ -1051,7 +1051,6 @@ mod tests { ) }; - #[cfg(feature = "rocksdb")] { let settings = factory.cached_storage_settings(); let rocksdb = factory.rocksdb_provider(); @@ -1079,13 +1078,6 @@ mod tests { assert_eq!(accounts, expected_accounts); assert_eq!(storages, expected_storages); } - - #[cfg(not(feature = "rocksdb"))] - { - let (accounts, storages) = collect_from_mdbx(&factory); - assert_eq!(accounts, expected_accounts); - assert_eq!(storages, expected_storages); - } } #[test] diff --git a/crates/storage/provider/Cargo.toml b/crates/storage/provider/Cargo.toml index f5e9663125..7abee13167 100644 --- a/crates/storage/provider/Cargo.toml +++ b/crates/storage/provider/Cargo.toml @@ -63,9 +63,7 @@ tokio = { workspace = true, features = ["sync"], optional = true } # parallel utils rayon.workspace = true -[target.'cfg(unix)'.dependencies] -# rocksdb: jemalloc is recommended production workload -rocksdb = { workspace = true, features = ["jemalloc"], optional = true } +rocksdb = { workspace = true, features = ["jemalloc"] } [dev-dependencies] reth-db = { workspace = true, features = ["test-utils"] } @@ -87,8 +85,6 @@ rand.workspace = true tokio = { workspace = true, features = ["sync", "macros", "rt-multi-thread"] } [features] -rocksdb = ["reth-storage-api/rocksdb", "dep:rocksdb"] -edge = ["rocksdb"] test-utils = [ "reth-db/test-utils", "reth-nippy-jar/test-utils", diff --git a/crates/storage/provider/src/either_writer.rs b/crates/storage/provider/src/either_writer.rs index f3eb48ac8b..5121b81913 100644 --- a/crates/storage/provider/src/either_writer.rs +++ b/crates/storage/provider/src/either_writer.rs @@ -7,10 +7,11 @@ use std::{ ops::{Range, RangeInclusive}, }; -#[cfg(all(unix, feature = "rocksdb"))] -use crate::providers::rocksdb::RocksDBBatch; use crate::{ - providers::{history_info, HistoryInfo, StaticFileProvider, StaticFileProviderRWRefMut}, + providers::{ + history_info, rocksdb::RocksDBBatch, HistoryInfo, StaticFileProvider, + StaticFileProviderRWRefMut, + }, StaticFileProviderFactory, }; use alloy_primitives::{map::HashMap, Address, BlockNumber, TxHash, TxNumber, B256}; @@ -62,40 +63,16 @@ type EitherWriterTy<'a, P, T> = EitherWriter< >; /// Helper type for `RocksDB` batch argument in writer constructors. -/// -/// When `rocksdb` feature is enabled, this is a real `RocksDB` batch. -/// Otherwise, it's `()` (unit type) to allow the same API without feature gates. -#[cfg(all(unix, feature = "rocksdb"))] pub type RocksBatchArg<'a> = crate::providers::rocksdb::RocksDBBatch<'a>; -/// Helper type for `RocksDB` batch argument in writer constructors. -/// -/// When `rocksdb` feature is enabled, this is a real `RocksDB` batch. -/// Otherwise, it's `()` (unit type) to allow the same API without feature gates. -#[cfg(not(all(unix, feature = "rocksdb")))] -pub type RocksBatchArg<'a> = (); /// The raw `RocksDB` batch type returned by [`EitherWriter::into_raw_rocksdb_batch`]. -#[cfg(all(unix, feature = "rocksdb"))] pub type RawRocksDBBatch = rocksdb::WriteBatchWithTransaction; -/// The raw `RocksDB` batch type returned by [`EitherWriter::into_raw_rocksdb_batch`]. -#[cfg(not(all(unix, feature = "rocksdb")))] -pub type RawRocksDBBatch = (); /// Helper type for `RocksDB` transaction reference argument in reader constructors. /// -/// When `rocksdb` feature is enabled, this is an optional reference to a `RocksDB` transaction. /// The `Option` allows callers to skip transaction creation when `RocksDB` isn't needed /// (e.g., on legacy MDBX-only nodes). -/// When `rocksdb` feature is disabled, it's `()` (unit type) to allow the same API without -/// feature gates. -#[cfg(all(unix, feature = "rocksdb"))] pub type RocksTxRefArg<'a> = Option<&'a crate::providers::rocksdb::RocksTx<'a>>; -/// Helper type for `RocksDB` transaction reference argument in reader constructors. -/// -/// When `rocksdb` feature is disabled, it's `()` (unit type) to allow the same API without -/// feature gates. -#[cfg(not(all(unix, feature = "rocksdb")))] -pub type RocksTxRefArg<'a> = (); /// Represents a destination for writing data, either to database, static files, or `RocksDB`. #[derive(Debug, Display)] @@ -105,7 +82,6 @@ pub enum EitherWriter<'a, CURSOR, N> { /// Write to static file StaticFile(StaticFileProviderRWRefMut<'a, N>), /// Write to `RocksDB` using a write-only batch (historical tables). - #[cfg(all(unix, feature = "rocksdb"))] RocksDB(RocksDBBatch<'a>), } @@ -254,7 +230,6 @@ impl<'a> EitherWriter<'a, (), ()> { P: DBProvider + NodePrimitivesProvider + StorageSettingsCache, P::Tx: DbTxMut, { - #[cfg(all(unix, feature = "rocksdb"))] if provider.cached_storage_settings().storage_v2 { return Ok(EitherWriter::RocksDB(_rocksdb_batch)); } @@ -271,7 +246,6 @@ impl<'a> EitherWriter<'a, (), ()> { P: DBProvider + NodePrimitivesProvider + StorageSettingsCache, P::Tx: DbTxMut, { - #[cfg(all(unix, feature = "rocksdb"))] if provider.cached_storage_settings().storage_v2 { return Ok(EitherWriter::RocksDB(_rocksdb_batch)); } @@ -290,7 +264,6 @@ impl<'a> EitherWriter<'a, (), ()> { P: DBProvider + NodePrimitivesProvider + StorageSettingsCache, P::Tx: DbTxMut, { - #[cfg(all(unix, feature = "rocksdb"))] if provider.cached_storage_settings().storage_v2 { return Ok(EitherWriter::RocksDB(_rocksdb_batch)); } @@ -307,7 +280,6 @@ impl<'a, CURSOR, N: NodePrimitives> EitherWriter<'a, CURSOR, N> { /// /// This is used to defer `RocksDB` commits to the provider level, ensuring all /// storage commits (MDBX, static files, `RocksDB`) happen atomically in a single place. - #[cfg(all(unix, feature = "rocksdb"))] pub fn into_raw_rocksdb_batch(self) -> Option> { match self { Self::Database(_) | Self::StaticFile(_) => None, @@ -315,16 +287,6 @@ impl<'a, CURSOR, N: NodePrimitives> EitherWriter<'a, CURSOR, N> { } } - /// Extracts the raw `RocksDB` write batch from this writer, if it contains one. - /// - /// Without the `rocksdb` feature, this always returns `None`. - #[cfg(not(all(unix, feature = "rocksdb")))] - pub fn into_raw_rocksdb_batch(self) -> Option { - match self { - Self::Database(_) | Self::StaticFile(_) => None, - } - } - /// Increment the block number. /// /// Relevant only for [`Self::StaticFile`]. It is a no-op for [`Self::Database`]. @@ -332,7 +294,6 @@ impl<'a, CURSOR, N: NodePrimitives> EitherWriter<'a, CURSOR, N> { match self { Self::Database(_) => Ok(()), Self::StaticFile(writer) => writer.increment_block(expected_block_number), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(_) => Err(ProviderError::UnsupportedProvider), } } @@ -347,7 +308,6 @@ impl<'a, CURSOR, N: NodePrimitives> EitherWriter<'a, CURSOR, N> { match self { Self::Database(_) => Ok(()), Self::StaticFile(writer) => writer.ensure_at_block(block_number), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(_) => Err(ProviderError::UnsupportedProvider), } } @@ -363,7 +323,6 @@ where match self { Self::Database(cursor) => Ok(cursor.append(tx_num, receipt)?), Self::StaticFile(writer) => writer.append_receipt(tx_num, receipt), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(_) => Err(ProviderError::UnsupportedProvider), } } @@ -378,7 +337,6 @@ where match self { Self::Database(cursor) => Ok(cursor.append(tx_num, sender)?), Self::StaticFile(writer) => writer.append_transaction_sender(tx_num, sender), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(_) => Err(ProviderError::UnsupportedProvider), } } @@ -396,7 +354,6 @@ where Ok(()) } Self::StaticFile(writer) => writer.append_transaction_senders(senders), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(_) => Err(ProviderError::UnsupportedProvider), } } @@ -429,7 +386,6 @@ where writer.prune_transaction_senders(to_delete, block)?; } - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(_) => return Err(ProviderError::UnsupportedProvider), } @@ -461,7 +417,6 @@ where } } Self::StaticFile(_) => Err(ProviderError::UnsupportedProvider), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(batch) => batch.put::(hash, &tx_num), } } @@ -491,7 +446,6 @@ where Ok(()) } Self::StaticFile(_) => Err(ProviderError::UnsupportedProvider), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(batch) => { for (hash, tx_num) in entries { batch.put::(hash, &tx_num)?; @@ -511,7 +465,6 @@ where Ok(()) } Self::StaticFile(_) => Err(ProviderError::UnsupportedProvider), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(batch) => batch.delete::(hash), } } @@ -530,7 +483,6 @@ where match self { Self::Database(cursor) => Ok(cursor.upsert(key, value)?), Self::StaticFile(_) => Err(ProviderError::UnsupportedProvider), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(batch) => batch.put::(key, value), } } @@ -545,7 +497,6 @@ where Ok(()) } Self::StaticFile(_) => Err(ProviderError::UnsupportedProvider), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(batch) => batch.delete::(key), } } @@ -559,7 +510,6 @@ where match self { Self::Database(cursor) => Ok(cursor.append(key, value)?), Self::StaticFile(_) => Err(ProviderError::UnsupportedProvider), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(batch) => batch.put::(key, value), } } @@ -573,7 +523,6 @@ where match self { Self::Database(cursor) => Ok(cursor.upsert(key, value)?), Self::StaticFile(_) => Err(ProviderError::UnsupportedProvider), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(batch) => batch.put::(key, value), } } @@ -588,7 +537,6 @@ where match self { Self::Database(cursor) => Ok(cursor.seek_exact(key)?.map(|(_, v)| v)), Self::StaticFile(_) => Err(ProviderError::UnsupportedProvider), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(batch) => batch.get::(key), } } @@ -607,7 +555,6 @@ where match self { Self::Database(cursor) => Ok(cursor.append(key, value)?), Self::StaticFile(_) => Err(ProviderError::UnsupportedProvider), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(batch) => batch.put::(key, value), } } @@ -621,7 +568,6 @@ where match self { Self::Database(cursor) => Ok(cursor.upsert(key, value)?), Self::StaticFile(_) => Err(ProviderError::UnsupportedProvider), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(batch) => batch.put::(key, value), } } @@ -636,7 +582,6 @@ where Ok(cursor.seek_exact(ShardedKey::last(address))?.map(|(_, v)| v)) } Self::StaticFile(_) => Err(ProviderError::UnsupportedProvider), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(batch) => batch.get::(ShardedKey::last(address)), } } @@ -651,7 +596,6 @@ where Ok(()) } Self::StaticFile(_) => Err(ProviderError::UnsupportedProvider), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(batch) => batch.delete::(key), } } @@ -680,7 +624,6 @@ where Self::StaticFile(writer) => { writer.append_account_changeset(changeset, block_number)?; } - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(_) => return Err(ProviderError::UnsupportedProvider), } @@ -715,7 +658,6 @@ where Self::StaticFile(writer) => { writer.append_storage_changeset(changeset, block_number)?; } - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(_) => return Err(ProviderError::UnsupportedProvider), } @@ -731,7 +673,6 @@ pub enum EitherReader<'a, CURSOR, N> { /// Read from static file StaticFile(StaticFileProvider, PhantomData<&'a ()>), /// Read from `RocksDB` transaction - #[cfg(all(unix, feature = "rocksdb"))] RocksDB(&'a crate::providers::rocksdb::RocksTx<'a>), } @@ -763,7 +704,6 @@ impl<'a> EitherReader<'a, (), ()> { P: DBProvider + NodePrimitivesProvider + StorageSettingsCache, P::Tx: DbTx, { - #[cfg(all(unix, feature = "rocksdb"))] if provider.cached_storage_settings().storage_v2 { return Ok(EitherReader::RocksDB( _rocksdb_tx.expect("storages_history_in_rocksdb requires rocksdb tx"), @@ -785,7 +725,6 @@ impl<'a> EitherReader<'a, (), ()> { P: DBProvider + NodePrimitivesProvider + StorageSettingsCache, P::Tx: DbTx, { - #[cfg(all(unix, feature = "rocksdb"))] if provider.cached_storage_settings().storage_v2 { return Ok(EitherReader::RocksDB( _rocksdb_tx.expect("transaction_hash_numbers_in_rocksdb requires rocksdb tx"), @@ -807,7 +746,6 @@ impl<'a> EitherReader<'a, (), ()> { P: DBProvider + NodePrimitivesProvider + StorageSettingsCache, P::Tx: DbTx, { - #[cfg(all(unix, feature = "rocksdb"))] if provider.cached_storage_settings().storage_v2 { return Ok(EitherReader::RocksDB( _rocksdb_tx.expect("account_history_in_rocksdb requires rocksdb tx"), @@ -865,7 +803,6 @@ where Some(result.map(|sender| (tx_num, sender))) }) .collect::>>(), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(_) => Err(ProviderError::UnsupportedProvider), } } @@ -883,7 +820,6 @@ where match self { Self::Database(cursor, _) => Ok(cursor.seek_exact(hash)?.map(|(_, v)| v)), Self::StaticFile(_, _) => Err(ProviderError::UnsupportedProvider), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(tx) => tx.get::(hash), } } @@ -901,7 +837,6 @@ where match self { Self::Database(cursor, _) => Ok(cursor.seek_exact(key)?.map(|(_, v)| v)), Self::StaticFile(_, _) => Err(ProviderError::UnsupportedProvider), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(tx) => tx.get::(key), } } @@ -926,7 +861,6 @@ where ) } Self::StaticFile(_, _) => Err(ProviderError::UnsupportedProvider), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(tx) => tx.storage_history_info( address, storage_key, @@ -949,7 +883,6 @@ where match self { Self::Database(cursor, _) => Ok(cursor.seek_exact(key)?.map(|(_, v)| v)), Self::StaticFile(_, _) => Err(ProviderError::UnsupportedProvider), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(tx) => tx.get::(key), } } @@ -973,7 +906,6 @@ where ) } Self::StaticFile(_, _) => Err(ProviderError::UnsupportedProvider), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(tx) => { tx.account_history_info(address, block_number, lowest_available_block_number) } @@ -1022,7 +954,6 @@ where entry.map(|(_, account_before)| account_before.address).map_err(Into::into) }) .collect(), - #[cfg(all(unix, feature = "rocksdb"))] Self::RocksDB(_) => Err(ProviderError::UnsupportedProvider), } } @@ -1195,7 +1126,7 @@ mod tests { } } -#[cfg(all(test, unix, feature = "rocksdb"))] +#[cfg(test)] mod rocksdb_tests { use super::*; use crate::{ diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index a9cf4c38f4..9426d1d778 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -182,12 +182,10 @@ impl RocksDBProviderFactory for BlockchainProvider { self.database.rocksdb_provider() } - #[cfg(all(unix, feature = "rocksdb"))] fn set_pending_rocksdb_batch(&self, _batch: rocksdb::WriteBatchWithTransaction) { unimplemented!("BlockchainProvider wraps ProviderFactory - use DatabaseProvider::set_pending_rocksdb_batch instead") } - #[cfg(all(unix, feature = "rocksdb"))] fn commit_pending_rocksdb_batches(&self) -> ProviderResult<()> { unimplemented!("BlockchainProvider wraps ProviderFactory - use DatabaseProvider::commit_pending_rocksdb_batches instead") } diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index a68064d5d2..a06015305a 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -195,12 +195,10 @@ impl RocksDBProviderFactory for ProviderFactory { self.rocksdb_provider.clone() } - #[cfg(all(unix, feature = "rocksdb"))] fn set_pending_rocksdb_batch(&self, _batch: rocksdb::WriteBatchWithTransaction) { unimplemented!("ProviderFactory is a factory, not a provider - use DatabaseProvider::set_pending_rocksdb_batch instead") } - #[cfg(all(unix, feature = "rocksdb"))] fn commit_pending_rocksdb_batches(&self) -> ProviderResult<()> { unimplemented!("ProviderFactory is a factory, not a provider - use DatabaseProvider::commit_pending_rocksdb_batches instead") } diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 772c2c67fc..5d779d21f0 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -205,7 +205,6 @@ pub struct DatabaseProvider { /// Path to the database directory. db_path: PathBuf, /// Pending `RocksDB` batches to be committed at provider commit time. - #[cfg_attr(not(all(unix, feature = "rocksdb")), allow(dead_code))] pending_rocksdb_batches: PendingRocksDBBatches, /// Commit order for database operations. commit_order: CommitOrder, @@ -323,12 +322,10 @@ impl RocksDBProviderFactory for DatabaseProvider { self.rocksdb_provider.clone() } - #[cfg(all(unix, feature = "rocksdb"))] fn set_pending_rocksdb_batch(&self, batch: rocksdb::WriteBatchWithTransaction) { self.pending_rocksdb_batches.lock().push(batch); } - #[cfg(all(unix, feature = "rocksdb"))] fn commit_pending_rocksdb_batches(&self) -> ProviderResult<()> { let batches = std::mem::take(&mut *self.pending_rocksdb_batches.lock()); for batch in batches { @@ -455,16 +452,11 @@ impl DatabaseProvider) -> ProviderResult<(R, Option)>, { - #[cfg(all(unix, feature = "rocksdb"))] let rocksdb = self.rocksdb_provider(); - #[cfg(all(unix, feature = "rocksdb"))] let rocksdb_batch = rocksdb.batch(); - #[cfg(not(all(unix, feature = "rocksdb")))] - let rocksdb_batch = (); let (result, raw_batch) = f(rocksdb_batch)?; - #[cfg(all(unix, feature = "rocksdb"))] if let Some(batch) = raw_batch { self.set_pending_rocksdb_batch(batch); } @@ -503,7 +495,6 @@ impl DatabaseProvider RocksDBWriteCtx { RocksDBWriteCtx { first_block_number: first_block, @@ -562,15 +553,11 @@ impl DatabaseProvider DatabaseProvider DatabaseProvider HistoryWriter for DatabaseProvi last_indices.sort_unstable_by_key(|(a, _)| *a); if self.cached_storage_settings().storage_v2 { - #[cfg(all(unix, feature = "rocksdb"))] - { - let batch = self.rocksdb_provider.unwind_account_history_indices(&last_indices)?; - self.pending_rocksdb_batches.lock().push(batch); - } + let batch = self.rocksdb_provider.unwind_account_history_indices(&last_indices)?; + self.pending_rocksdb_batches.lock().push(batch); } else { // Unwind the account history index in MDBX. let mut cursor = self.tx.cursor_write::()?; @@ -3331,12 +3313,9 @@ impl HistoryWriter for DatabaseProvi storage_changesets.sort_by_key(|(address, key, _)| (*address, *key)); if self.cached_storage_settings().storage_v2 { - #[cfg(all(unix, feature = "rocksdb"))] - { - let batch = - self.rocksdb_provider.unwind_storage_history_indices(&storage_changesets)?; - self.pending_rocksdb_batches.lock().push(batch); - } + let batch = + self.rocksdb_provider.unwind_storage_history_indices(&storage_changesets)?; + self.pending_rocksdb_batches.lock().push(batch); } else { // Unwind the storage history index in MDBX. let mut cursor = self.tx.cursor_write::()?; @@ -3693,7 +3672,6 @@ impl BlockWriter // append_*_history_shard which handles read-merge-write internally. let storage_settings = self.cached_storage_settings(); if storage_settings.storage_v2 { - #[cfg(all(unix, feature = "rocksdb"))] self.with_rocksdb_batch(|mut batch| { for (address, blocks) in account_transitions { batch.append_account_history_shard(address, blocks)?; @@ -3704,7 +3682,6 @@ impl BlockWriter self.insert_account_history_index(account_transitions)?; } if storage_settings.storage_v2 { - #[cfg(all(unix, feature = "rocksdb"))] self.with_rocksdb_batch(|mut batch| { for ((address, key), blocks) in storage_transitions { batch.append_storage_history_shard(address, key, blocks)?; @@ -3841,12 +3818,9 @@ impl DBProvider for DatabaseProvider if self.static_file_provider.has_unwind_queued() || self.commit_order.is_unwind() { self.tx.commit()?; - #[cfg(all(unix, feature = "rocksdb"))] - { - let batches = std::mem::take(&mut *self.pending_rocksdb_batches.lock()); - for batch in batches { - self.rocksdb_provider.commit_batch(batch)?; - } + let batches = std::mem::take(&mut *self.pending_rocksdb_batches.lock()); + for batch in batches { + self.rocksdb_provider.commit_batch(batch)?; } self.static_file_provider.commit()?; @@ -3858,15 +3832,12 @@ impl DBProvider for DatabaseProvider self.static_file_provider.finalize()?; timings.sf = start.elapsed(); - #[cfg(all(unix, feature = "rocksdb"))] - { - let start = Instant::now(); - let batches = std::mem::take(&mut *self.pending_rocksdb_batches.lock()); - for batch in batches { - self.rocksdb_provider.commit_batch(batch)?; - } - timings.rocksdb = start.elapsed(); + let start = Instant::now(); + let batches = std::mem::take(&mut *self.pending_rocksdb_batches.lock()); + for batch in batches { + self.rocksdb_provider.commit_batch(batch)?; } + timings.rocksdb = start.elapsed(); let start = Instant::now(); self.tx.commit()?; @@ -5135,28 +5106,24 @@ mod tests { } } - #[cfg(all(unix, feature = "rocksdb"))] - { - let rocksdb = factory.rocksdb_provider(); - for block_num in 1..=num_blocks { - for acct_idx in 0..accounts_per_block { - let address = - Address::with_last_byte((block_num * 10 + acct_idx as u64) as u8); - let shards = rocksdb.account_history_shards(address).unwrap(); + let rocksdb = factory.rocksdb_provider(); + for block_num in 1..=num_blocks { + for acct_idx in 0..accounts_per_block { + let address = Address::with_last_byte((block_num * 10 + acct_idx as u64) as u8); + let shards = rocksdb.account_history_shards(address).unwrap(); + assert!( + !shards.is_empty(), + "v2: RocksDB AccountsHistory missing for block {block_num} acct {acct_idx}" + ); + + for s in 1..=slots_per_account as u64 { + let slot = U256::from(s + acct_idx as u64 * 100); + let slot_key = B256::from(slot); + let shards = rocksdb.storage_history_shards(address, slot_key).unwrap(); assert!( !shards.is_empty(), - "v2: RocksDB AccountsHistory missing for block {block_num} acct {acct_idx}" + "v2: RocksDB StoragesHistory missing for block {block_num} acct {acct_idx} slot {s}" ); - - for s in 1..=slots_per_account as u64 { - let slot = U256::from(s + acct_idx as u64 * 100); - let slot_key = B256::from(slot); - let shards = rocksdb.storage_history_shards(address, slot_key).unwrap(); - assert!( - !shards.is_empty(), - "v2: RocksDB StoragesHistory missing for block {block_num} acct {acct_idx} slot {s}" - ); - } } } } @@ -5367,7 +5334,6 @@ mod tests { } #[test] - #[cfg(all(unix, feature = "rocksdb"))] fn test_unwind_storage_history_indices_v2() { let factory = create_test_provider_factory(); factory.set_storage_settings_cache(StorageSettings::v2()); diff --git a/crates/storage/provider/src/providers/mod.rs b/crates/storage/provider/src/providers/mod.rs index 9b8af6de66..fbec517967 100644 --- a/crates/storage/provider/src/providers/mod.rs +++ b/crates/storage/provider/src/providers/mod.rs @@ -32,10 +32,6 @@ pub use blockchain_provider::BlockchainProvider; mod consistent; pub use consistent::ConsistentProvider; -// RocksDB currently only supported on Unix platforms -// Windows support is planned for future releases -#[cfg_attr(all(unix, feature = "rocksdb"), path = "rocksdb/mod.rs")] -#[cfg_attr(not(all(unix, feature = "rocksdb")), path = "rocksdb_stub.rs")] pub(crate) mod rocksdb; pub use rocksdb::{ diff --git a/crates/storage/provider/src/providers/rocksdb_stub.rs b/crates/storage/provider/src/providers/rocksdb_stub.rs deleted file mode 100644 index 6b36404339..0000000000 --- a/crates/storage/provider/src/providers/rocksdb_stub.rs +++ /dev/null @@ -1,239 +0,0 @@ -//! Stub implementation of `RocksDB` provider. -//! -//! This module provides placeholder types that allow the code to compile when `RocksDB` is not -//! available (either on non-Unix platforms or when the `rocksdb` feature is not enabled). -//! All method calls are cfg-guarded in the calling code, so only type definitions are needed here. - -use alloy_primitives::BlockNumber; -use metrics::Label; -use parking_lot::Mutex; -use reth_db_api::{database_metrics::DatabaseMetrics, models::StorageSettings}; -use reth_prune_types::PruneMode; -use reth_storage_errors::{db::LogLevel, provider::ProviderResult}; -use std::{path::Path, sync::Arc}; - -/// Pending `RocksDB` batches type alias (stub - uses unit type). -pub(crate) type PendingRocksDBBatches = Arc>>; - -/// Statistics for a single `RocksDB` table (column family) - stub. -#[derive(Debug, Clone)] -pub struct RocksDBTableStats { - /// Size of SST files on disk in bytes. - pub sst_size_bytes: u64, - /// Size of memtables in memory in bytes. - pub memtable_size_bytes: u64, - /// Name of the table/column family. - pub name: String, - /// Estimated number of keys in the table. - pub estimated_num_keys: u64, - /// Estimated size of live data in bytes (SST files + memtables). - pub estimated_size_bytes: u64, - /// Estimated bytes pending compaction (reclaimable space). - pub pending_compaction_bytes: u64, -} - -/// Database-level statistics for `RocksDB` - stub. -#[derive(Debug, Clone)] -pub struct RocksDBStats { - /// Statistics for each table (column family). - pub tables: Vec, - /// Total size of WAL (Write-Ahead Log) files in bytes. - pub wal_size_bytes: u64, -} - -/// Context for `RocksDB` block writes (stub). -#[derive(Debug, Clone)] -#[allow(dead_code)] -pub(crate) struct RocksDBWriteCtx { - /// The first block number being written. - pub first_block_number: BlockNumber, - /// The prune mode for transaction lookup, if any. - pub prune_tx_lookup: Option, - /// Storage settings determining what goes to `RocksDB`. - pub storage_settings: StorageSettings, - /// Pending batches (stub - unused). - pub pending_batches: PendingRocksDBBatches, -} - -/// A stub `RocksDB` provider. -/// -/// This type exists to allow code to compile when `RocksDB` is not available (either on non-Unix -/// platforms or when the `rocksdb` feature is not enabled). All method calls on `RocksDBProvider` -/// are cfg-guarded in the calling code, so this stub only provides type definitions. -#[derive(Debug, Clone)] -pub struct RocksDBProvider; - -impl RocksDBProvider { - /// Creates a new stub `RocksDB` provider. - pub fn new(_path: impl AsRef) -> ProviderResult { - Ok(Self) - } - - /// Creates a new stub `RocksDB` provider builder. - pub fn builder(path: impl AsRef) -> RocksDBBuilder { - RocksDBBuilder::new(path) - } - - /// Returns `true` if a `RocksDB` database exists at the given path (stub implementation). - /// - /// Always returns `false` since `RocksDB` is not available. - pub fn exists(_path: impl AsRef) -> bool { - false - } - - /// Check consistency of `RocksDB` tables (stub implementation). - /// - /// Returns `None` since there is no `RocksDB` data to check when the feature is disabled. - pub const fn check_consistency( - &self, - _provider: &Provider, - ) -> ProviderResult> { - Ok(None) - } - - /// Returns statistics for all column families in the database (stub implementation). - /// - /// Returns an empty vector since there is no `RocksDB` when the feature is disabled. - pub const fn table_stats(&self) -> Vec { - Vec::new() - } - - /// Clears all entries from the specified table (stub implementation). - /// - /// This is a no-op since there is no `RocksDB` when the feature is disabled. - pub const fn clear(&self) -> ProviderResult<()> { - Ok(()) - } - - /// Returns the total size of WAL (Write-Ahead Log) files in bytes (stub implementation). - /// - /// Returns 0 since there is no `RocksDB` when the feature is disabled. - pub const fn wal_size_bytes(&self) -> u64 { - 0 - } - - /// Returns database-level statistics including per-table stats and WAL size (stub - /// implementation). - /// - /// Returns empty stats since there is no `RocksDB` when the feature is disabled. - pub const fn db_stats(&self) -> RocksDBStats { - RocksDBStats { tables: Vec::new(), wal_size_bytes: 0 } - } - - /// Flushes all pending writes to disk (stub implementation). - /// - /// This is a no-op since there is no `RocksDB` when the feature is disabled. - pub const fn flush(&self, _tables: &[&'static str]) -> ProviderResult<()> { - Ok(()) - } - - /// Creates an iterator over all entries in the specified table (stub implementation). - /// - /// Returns an empty iterator since there is no `RocksDB` when the feature is disabled. - pub const fn iter(&self) -> ProviderResult> { - Ok(RocksDBIter(std::marker::PhantomData)) - } -} - -impl DatabaseMetrics for RocksDBProvider { - fn gauge_metrics(&self) -> Vec<(&'static str, f64, Vec