use std::path::Path;
use semver::Version;
use zebra_chain::parameters::Network;
use crate::Config;
use super::Storage;
pub use zebra_state::{
SaplingScannedDatabaseEntry, SaplingScannedDatabaseIndex, SaplingScannedResult,
SaplingScanningKey, ZebraDb as ScannerDb,
};
pub mod sapling;
#[cfg(any(test, feature = "proptest-impl"))]
pub mod tests;
pub const SCANNER_DATABASE_KIND: &str = "private-scan";
pub const SCANNER_COLUMN_FAMILIES_IN_CODE: &[&str] = &[
sapling::SAPLING_TX_IDS,
];
const SCANNER_DATABASE_FORMAT_MAJOR_VERSION: u64 = 1;
impl Storage {
pub(crate) fn new_db(config: &Config, network: &Network, read_only: bool) -> Self {
Self::new_with_debug(
config, network,
true, read_only,
)
}
pub(crate) fn new_with_debug(
config: &Config,
network: &Network,
debug_skip_format_upgrades: bool,
read_only: bool,
) -> Self {
let db = ScannerDb::new(
config.db_config(),
SCANNER_DATABASE_KIND,
&Self::database_format_version_in_code(),
network,
debug_skip_format_upgrades,
SCANNER_COLUMN_FAMILIES_IN_CODE
.iter()
.map(ToString::to_string),
read_only,
);
let new_storage = Self { db };
let keys = new_storage.sapling_keys_last_heights();
for (key_num, (_key, height)) in keys.iter().enumerate() {
info!(
"Last scanned height for key number {} is {}, resuming at {}",
key_num,
height.as_usize(),
height.next().expect("height is not maximum").as_usize(),
);
}
info!("loaded Zebra scanner cache");
new_storage
}
pub fn network(&self) -> Network {
self.db.network()
}
pub fn path(&self) -> &Path {
self.db.path()
}
pub fn database_format_version_in_code() -> Version {
Version::new(SCANNER_DATABASE_FORMAT_MAJOR_VERSION, 0, 0)
}
pub fn check_for_panics(&mut self) {
self.db.check_for_panics()
}
pub fn is_empty(&self) -> bool {
self.sapling_tx_ids_cf().zs_is_empty()
}
}