Skip to content

Commit

Permalink
jsonrpc: introduce a meta column family for tracking index initializa…
Browse files Browse the repository at this point in the history
…tion

Introduce a meta column family that is used to track initialization of
the Index DB itself as well as the status of the various column families
themsevles.
  • Loading branch information
bmwill committed Oct 16, 2024
1 parent 814af2a commit 71f9203
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 4 deletions.
65 changes: 61 additions & 4 deletions crates/sui-core/src/jsonrpc_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! The main user of this data is the explorer.

use std::cmp::{max, min};
use std::collections::{HashMap, HashSet};
use std::collections::{BTreeMap, HashMap, HashSet};
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
Expand Down Expand Up @@ -86,6 +86,25 @@ impl CoinIndexKey2 {
}
}

const CURRENT_DB_VERSION: u64 = 0;
const CURRENT_COIN_INDEX_VERSION: u64 = 0;

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
struct MetadataInfo {
/// Version of the Database
version: u64,
/// Version of each of the column families
///
/// This is used to version individual column families to determine if a CF needs to be
/// (re)initialized on startup.
column_families: BTreeMap<String, ColumnFamilyInfo>,
}

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
struct ColumnFamilyInfo {
version: u64,
}

pub const MAX_TX_RANGE_SIZE: u64 = 4096;

pub const MAX_GET_OWNED_OBJECT_SIZE: usize = 256;
Expand Down Expand Up @@ -179,6 +198,14 @@ pub struct IndexStoreCacheUpdates {

#[derive(DBMapUtils)]
pub struct IndexStoreTables {
/// A singleton that store metadata information on the DB.
///
/// A few uses for this singleton:
/// - determining if the DB has been initialized (as some tables could still be empty post
/// initialization)
/// - version of each column family and their respective initialization status
meta: DBMap<(), MetadataInfo>,

/// Index from sui address to transactions initiated by that address.
#[default_options_override_fn = "transactions_from_addr_table_default_config"]
transactions_from_addr: DBMap<(SuiAddress, TxSequenceNumber), TransactionDigest>,
Expand Down Expand Up @@ -269,10 +296,28 @@ impl IndexStoreTables {

#[allow(deprecated)]
fn init(&mut self, authority_store: &AuthorityStore) -> Result<(), StorageError> {
// If the new coin index is empty, populate it
if self.coin_index_2.is_empty() {
let mut metadata = {
match self.meta.get(&()) {
Ok(Some(metadata)) => metadata,
Ok(None) | Err(_) => MetadataInfo {
version: CURRENT_DB_VERSION,
column_families: BTreeMap::new(),
},
}
};

// If the new coin index hasn't already been initialized, populate it
if !metadata
.column_families
.get(self.coin_index_2.cf_name())
.is_some_and(|cf_info| cf_info.version == CURRENT_COIN_INDEX_VERSION)
|| self.coin_index_2.is_empty()
{
info!("Initializing JSON-RPC coin index");

// clear the index so we're starting with a fresh table
self.coin_index_2.unsafe_clear()?;

let make_live_object_indexer = CoinParLiveObjectSetIndexer { tables: self };

crate::par_index_live_object_set::par_index_live_object_set(
Expand All @@ -281,9 +326,21 @@ impl IndexStoreTables {
)?;

info!("Finished initializing JSON-RPC coin index");

// Once the coin_index_2 table has been finished, update the metadata indicating that
// its been initialized
metadata.column_families.insert(
self.coin_index_2.cf_name().to_owned(),
ColumnFamilyInfo {
version: CURRENT_COIN_INDEX_VERSION,
},
);
}

// Clear old, deprecated column families
// Commit to the DB that the indexes have been initialized
self.meta.insert(&(), &metadata)?;

// Clear old, deprecated and unused column families
if !self.coin_index.is_empty() {
self.coin_index.unsafe_clear()?;
}
Expand Down
4 changes: 4 additions & 0 deletions crates/typed-store/src/rocks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,10 @@ impl<K, V> DBMap<K, V> {
Ok(DBMap::new(db.clone(), rw_options, &cf_key, is_deprecated))
}

pub fn cf_name(&self) -> &str {
&self.cf
}

pub fn batch(&self) -> DBBatch {
let batch = match *self.rocksdb {
RocksDB::DBWithThreadMode(_) => RocksDBBatch::Regular(WriteBatch::default()),
Expand Down

0 comments on commit 71f9203

Please sign in to comment.