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

change(state): Allow opening the database in a read-only mode #8079

Merged
merged 12 commits into from
Dec 13, 2023
2 changes: 1 addition & 1 deletion zebra-scan/src/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub async fn init(
state: scan::State,
chain_tip_change: ChainTipChange,
) -> Result<(), Report> {
let storage = tokio::task::spawn_blocking(move || Storage::new(&config, network))
let storage = tokio::task::spawn_blocking(move || Storage::new(&config, network, false))
.wait_for_panics()
.await;

Expand Down
4 changes: 2 additions & 2 deletions zebra-scan/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ impl Storage {
///
/// This method can block while creating or reading database files, so it must be inside
/// spawn_blocking() in async code.
pub fn new(config: &Config, network: Network) -> Self {
let mut storage = Self::new_db(config, network);
pub fn new(config: &Config, network: Network, read_only: bool) -> Self {
let mut storage = Self::new_db(config, network, read_only);

for (sapling_key, birthday) in config.sapling_keys_to_scan.iter() {
storage.add_sapling_key(sapling_key, Some(zebra_chain::block::Height(*birthday)));
Expand Down
8 changes: 5 additions & 3 deletions zebra-scan/src/storage/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ impl Storage {
/// If there is no existing database, creates a new database on disk.
///
/// New keys in `config` are not inserted into the database.
pub(crate) fn new_db(config: &Config, network: Network) -> Self {
pub(crate) fn new_db(config: &Config, network: Network, read_only: bool) -> Self {
Self::new_with_debug(
config, network,
// TODO: make format upgrades work with any database, then change this to `false`
true,
// TODO: make format upgrades work with any database, then change debug_skip_format_upgrades to `false`
true, read_only,
)
}

Expand All @@ -67,6 +67,7 @@ impl Storage {
config: &Config,
network: Network,
debug_skip_format_upgrades: bool,
read_only: bool,
) -> Self {
let db = ScannerDb::new(
config.db_config(),
Expand All @@ -77,6 +78,7 @@ impl Storage {
SCANNER_COLUMN_FAMILIES_IN_CODE
.iter()
.map(ToString::to_string),
read_only,
);

let new_storage = Self { db };
Expand Down
2 changes: 1 addition & 1 deletion zebra-scan/src/storage/db/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ mod snapshot;

/// Returns an empty `Storage` suitable for testing.
pub fn new_test_storage(network: Network) -> Storage {
Storage::new(&Config::ephemeral(), network)
Storage::new(&Config::ephemeral(), network, false)
}

/// Add fake keys to `storage` for testing purposes.
Expand Down
2 changes: 1 addition & 1 deletion zebra-scan/src/tests/vectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
use zebra_state::{SaplingScannedResult, TransactionIndex};

use crate::{
config::Config,

Check warning on line 25 in zebra-scan/src/tests/vectors.rs

View workflow job for this annotation

GitHub Actions / Check Cargo.lock is up to date

unused import: `config::Config`

Check warning on line 25 in zebra-scan/src/tests/vectors.rs

View workflow job for this annotation

GitHub Actions / Test stable on ubuntu-latest

unused import: `config::Config`

Check warning on line 25 in zebra-scan/src/tests/vectors.rs

View workflow job for this annotation

GitHub Actions / Test beta on ubuntu-latest

unused import: `config::Config`

Check warning on line 25 in zebra-scan/src/tests/vectors.rs

View workflow job for this annotation

GitHub Actions / Test stable on macos-latest

unused import: `config::Config`

Check failure on line 25 in zebra-scan/src/tests/vectors.rs

View workflow job for this annotation

GitHub Actions / Build zebra-scan crate

unused import: `config::Config`

Check failure on line 25 in zebra-scan/src/tests/vectors.rs

View workflow job for this annotation

GitHub Actions / Clippy (stable) Results

unused import: `config::Config`

error: unused import: `config::Config` --> zebra-scan/src/tests/vectors.rs:25:5 | 25 | config::Config, | ^^^^^^^^^^^^^^ | = note: `-D unused-imports` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(unused_imports)]`
scan::{block_to_compact, scan_block},
tests::{fake_block, ZECPAGES_SAPLING_VIEWING_KEY},
};
Expand Down Expand Up @@ -157,7 +157,7 @@
zcash_client_backend::encoding::encode_extended_full_viewing_key("zxviews", &extfvk);

// Create a database
let mut s = crate::storage::Storage::new(&Config::ephemeral(), Network::Mainnet);
let mut s = crate::storage::tests::new_test_storage(Network::Mainnet);

Check failure on line 160 in zebra-scan/src/tests/vectors.rs

View workflow job for this annotation

GitHub Actions / Check Cargo.lock is up to date

failed to resolve: could not find `tests` in `storage`

Check failure on line 160 in zebra-scan/src/tests/vectors.rs

View workflow job for this annotation

GitHub Actions / Test stable on ubuntu-latest

failed to resolve: could not find `tests` in `storage`

Check failure on line 160 in zebra-scan/src/tests/vectors.rs

View workflow job for this annotation

GitHub Actions / Test beta on ubuntu-latest

failed to resolve: could not find `tests` in `storage`

Check failure on line 160 in zebra-scan/src/tests/vectors.rs

View workflow job for this annotation

GitHub Actions / Test stable on macos-latest

failed to resolve: could not find `tests` in `storage`

Check failure on line 160 in zebra-scan/src/tests/vectors.rs

View workflow job for this annotation

GitHub Actions / Build zebra-scan crate

failed to resolve: could not find `tests` in `storage`

Check failure on line 160 in zebra-scan/src/tests/vectors.rs

View workflow job for this annotation

GitHub Actions / Clippy (stable) Results

failed to resolve: could not find `tests` in `storage`

error[E0433]: failed to resolve: could not find `tests` in `storage` --> zebra-scan/src/tests/vectors.rs:160:33 | 160 | let mut s = crate::storage::tests::new_test_storage(Network::Mainnet); | ^^^^^ could not find `tests` in `storage` | help: consider importing this module | 3 + use crate::storage::db::tests; | help: if you import `tests`, refer to it directly | 160 - let mut s = crate::storage::tests::new_test_storage(Network::Mainnet); 160 + let mut s = tests::new_test_storage(Network::Mainnet); |

// Insert the generated key to the database
s.add_sapling_key(&key_to_be_stored, None);
Expand Down
3 changes: 3 additions & 0 deletions zebra-state/src/service/finalized_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ impl FinalizedState {
false,
#[cfg(feature = "elasticsearch")]
elastic_db,
false,
)
}

Expand All @@ -158,6 +159,7 @@ impl FinalizedState {
network: Network,
debug_skip_format_upgrades: bool,
#[cfg(feature = "elasticsearch")] elastic_db: Option<elasticsearch::Elasticsearch>,
read_only: bool,
) -> Self {
let db = ZebraDb::new(
config,
Expand All @@ -168,6 +170,7 @@ impl FinalizedState {
STATE_COLUMN_FAMILIES_IN_CODE
.iter()
.map(ToString::to_string),
read_only,
);

#[cfg(feature = "elasticsearch")]
Expand Down
7 changes: 6 additions & 1 deletion zebra-state/src/service/finalized_state/disk_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,7 @@ impl DiskDb {
format_version_in_code: &Version,
network: Network,
column_families_in_code: impl IntoIterator<Item = String>,
read_only: bool,
) -> DiskDb {
let db_kind = db_kind.as_ref();
let path = config.db_path(db_kind, format_version_in_code.major, network);
Expand All @@ -644,7 +645,11 @@ impl DiskDb {
.unique()
.map(|cf_name| rocksdb::ColumnFamilyDescriptor::new(cf_name, db_options.clone()));

let db_result = DB::open_cf_descriptors(&db_options, &path, column_families);
let db_result = if read_only {
DB::open_cf_descriptors_read_only(&db_options, &path, column_families, false)
} else {
DB::open_cf_descriptors(&db_options, &path, column_families)
};

match db_result {
Ok(db) => {
Expand Down
14 changes: 10 additions & 4 deletions zebra-state/src/service/finalized_state/zebra_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ impl ZebraDb {
network: Network,
debug_skip_format_upgrades: bool,
column_families_in_code: impl IntoIterator<Item = String>,
read_only: bool,
teor2345 marked this conversation as resolved.
Show resolved Hide resolved
) -> ZebraDb {
let disk_version = database_format_version_on_disk(
config,
Expand All @@ -108,16 +109,20 @@ impl ZebraDb {
// Log any format changes before opening the database, in case opening fails.
let format_change = DbFormatChange::open_database(format_version_in_code, disk_version);

// Always do format upgrades in production, but allow them to be skipped by the scanner
// (because it doesn't support them yet).
// Format upgrades try to write to the database, so we always skip them if `read_only` is
// `true`.
//
// We allow skipping the upgrades by the scanner because it doesn't support them yet and we
// also allow skipping them when we are running tests.
//
// TODO: Make scanner support format upgrades, then remove `shielded-scan` here.
let can_skip_format_upgrades = cfg!(test) || cfg!(feature = "shielded-scan");
let debug_skip_format_upgrades = read_only
|| ((cfg!(test) || cfg!(feature = "shielded-scan")) && debug_skip_format_upgrades);

// Open the database and do initial checks.
let mut db = ZebraDb {
config: Arc::new(config.clone()),
debug_skip_format_upgrades: can_skip_format_upgrades && debug_skip_format_upgrades,
debug_skip_format_upgrades,
format_change_handle: None,
// After the database directory is created, a newly created database temporarily
// changes to the default database version. Then we set the correct version in the
Expand All @@ -129,6 +134,7 @@ impl ZebraDb {
format_version_in_code,
network,
column_families_in_code,
read_only,
),
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ fn test_block_db_round_trip_with(
STATE_COLUMN_FAMILIES_IN_CODE
.iter()
.map(ToString::to_string),
false,
);

// Check that each block round-trips to the database
Expand Down
1 change: 1 addition & 0 deletions zebra-state/src/service/read/tests/vectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,5 +377,6 @@ fn new_ephemeral_db() -> ZebraDb {
STATE_COLUMN_FAMILIES_IN_CODE
.iter()
.map(ToString::to_string),
false,
)
}
1 change: 1 addition & 0 deletions zebra-state/src/tests/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ pub(crate) fn new_state_with_mainnet_genesis(
true,
#[cfg(feature = "elasticsearch")]
None,
false,
);
let non_finalized_state = NonFinalizedState::new(network);

Expand Down
Loading