Skip to content

Commit

Permalink
Make the FinalizedState cloneable
Browse files Browse the repository at this point in the history
  • Loading branch information
teor2345 committed Sep 15, 2022
1 parent 4d3cfd6 commit 56e36f4
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 12 deletions.
5 changes: 5 additions & 0 deletions zebra-state/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,14 @@ pub(crate) struct StateService {
// Exclusively Writeable State
//
/// The non-finalized chain state, including its in-memory chain forks.
//
// TODO: get rid of this struct member, and just let the block write task own the NonFinalizedState.
mem: NonFinalizedState,

/// The finalized chain state, including its on-disk database.
//
// TODO: get rid of this struct member, and just let the ReadStateService
// and block write task share ownership of the database.
pub(crate) disk: FinalizedState,

// Pending UTXO Request Tracking
Expand Down
14 changes: 10 additions & 4 deletions zebra-state/src/service/finalized_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,17 @@ pub use disk_format::{OutputIndex, OutputLocation, TransactionLocation};
pub(super) use zebra_db::ZebraDb;

/// The finalized part of the chain state, stored in the db.
#[derive(Debug)]
///
/// `rocksdb` allows concurrent writes through a shared reference,
/// so finalized state instances are cloneable. When the final clone is dropped,
/// the database is closed.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct FinalizedState {
// Configuration
//
// This configuration cannot be modified after the database is initialized,
// because some clones would have different values.
//
/// The configured network.
network: Network,

Expand All @@ -58,14 +65,13 @@ pub struct FinalizedState {

// Owned State
//
// Everything contained in this state must be shared by all clones, or read-only.
//
/// The underlying database.
///
/// `rocksdb` allows reads and writes via a shared reference,
/// so this database object can be freely cloned.
/// The last instance that is dropped will close the underlying database.
//
// TODO: get rid of this struct member, and just let the [`ReadStateService`]
// and block write task share ownership of the database.
db: ZebraDb,
}

Expand Down
25 changes: 19 additions & 6 deletions zebra-state/src/service/finalized_state/disk_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ pub type DB = rocksdb::DBWithThreadMode<DBThreadMode>;

/// Wrapper struct to ensure low-level database access goes through the correct API.
///
/// `rocksdb` allows concurrent writes through a shared reference,
/// so database instances are cloneable. When the final clone is dropped,
/// the database is closed.
///
/// # Correctness
///
/// Reading transactions from the database using RocksDB iterators causes hangs.
Expand All @@ -48,6 +52,20 @@ pub type DB = rocksdb::DBWithThreadMode<DBThreadMode>;
/// (Or it might be fixed by future RocksDB upgrades.)
#[derive(Clone, Debug)]
pub struct DiskDb {
// Configuration
//
// This configuration cannot be modified after the database is initialized,
// because some clones would have different values.
//
/// The configured temporary database setting.
///
/// If true, the database files are deleted on drop.
ephemeral: bool,

// Owned State
//
// Everything contained in this state must be shared by all clones, or read-only.
//
/// The shared inner RocksDB database.
///
/// RocksDB allows reads and writes via a shared reference.
Expand All @@ -58,11 +76,6 @@ pub struct DiskDb {
/// In [`MultiThreaded`](rocksdb::MultiThreaded) mode,
/// only [`Drop`] requires exclusive access.
db: Arc<DB>,

/// The configured temporary database setting.
///
/// If true, the database files are deleted on drop.
ephemeral: bool,
}

/// Wrapper struct to ensure low-level database writes go through the correct API.
Expand Down Expand Up @@ -434,8 +447,8 @@ impl DiskDb {
info!("Opened Zebra state cache at {}", path.display());

let db = DiskDb {
db: Arc::new(db),
ephemeral: config.ephemeral,
db: Arc::new(db),
};

db.assert_default_cf_is_empty();
Expand Down
11 changes: 9 additions & 2 deletions zebra-state/src/service/finalized_state/zebra_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,17 @@ pub mod transparent;
pub mod arbitrary;

/// Wrapper struct to ensure high-level typed database access goes through the correct API.
#[derive(Clone, Debug)]
///
/// `rocksdb` allows concurrent writes through a shared reference,
/// so database instances are cloneable. When the final clone is dropped,
/// the database is closed.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ZebraDb {
// Owned State
//
// Everything contained in this state must be shared by all clones, or read-only.
//
/// The inner low-level database wrapper for the RocksDB database.
/// This wrapper can be cloned and shared.
db: DiskDb,
}

Expand Down

0 comments on commit 56e36f4

Please sign in to comment.