Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
- [BREAKING] Renamed `SubmitProvenBatch` RPC endpoint to `SubmitProvenTxBatch` ([#2094](https://github.com/0xMiden/node/pull/2094)).
- Fixed block producer mempool panic when selecting transactions that depend on notes created by pruned committed transactions ([#2097](https://github.com/0xMiden/node/pull/2097)).
- Implemented filtering based on the network account note script root allowlist in ntx-builder ([#2042](https://github.com/0xMiden/node/issues/2042)).
- Fixed RocksDB SMT subtree helpers to return storage errors for unsupported depths instead of panicking ([#1730](https://github.com/0xMiden/node/issues/1730)).

- [BREAKING] Renamed `ExplorerStatusDetails` fields in the network monitor's `/status` payload from `number_of_*` to `total_*` (`total_transactions`, `total_nullifiers`, `total_notes`, `total_account_updates`). The values now represent network-wide cumulative totals from the explorer's `overviewStats` query instead of last-block counts.
- [BREAKING] Removed `--wallet-filepath` / `--counter-filepath` flags and the `MIDEN_MONITOR_WALLET_FILEPATH` / `MIDEN_MONITOR_COUNTER_FILEPATH` env vars from the network monitor. The monitor now keeps wallet and counter accounts fully in memory and regenerates them on every startup; the dashboard's counter value resets to zero on restart.
Expand Down
51 changes: 26 additions & 25 deletions crates/large-smt-backend-rocksdb/src/rocksdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,16 +306,16 @@ impl RocksDbStorage {
/// Converts a `NodeIndex` (for a subtree root) into a `KeyBytes` for use as a `RocksDB` key.
/// The `KeyBytes` is a wrapper around a 8-byte value with a variable-length prefix.
#[inline(always)]
fn subtree_db_key(index: NodeIndex) -> KeyBytes {
fn subtree_db_key(index: NodeIndex) -> Result<KeyBytes, StorageError> {
let keep = match index.depth() {
24 => 3,
32 => 4,
40 => 5,
48 => 6,
56 => 7,
d => panic!("unsupported depth {d}"),
d => return Err(StorageError::Unsupported(format!("unsupported subtree depth {d}"))),
};
KeyBytes::new(index.position(), keep)
Ok(KeyBytes::new(index.position(), keep))
}

/// Retrieves a handle to a `RocksDB` column family by its name.
Expand All @@ -331,9 +331,9 @@ impl RocksDbStorage {

/* helper: CF handle from NodeIndex ------------------------------------- */
#[inline(always)]
fn subtree_cf(&self, index: NodeIndex) -> &rocksdb::ColumnFamily {
let name = cf_for_depth(index.depth());
self.cf_handle(name).expect("CF handle missing")
fn subtree_cf(&self, index: NodeIndex) -> Result<&rocksdb::ColumnFamily, StorageError> {
let name = cf_for_depth(index.depth())?;
self.cf_handle(name)
}
}

Expand Down Expand Up @@ -624,8 +624,8 @@ impl SmtStorage for RocksDbStorage {
/// - `Ok(...)` if all fetches succeed.
/// - `Err(StorageError)` if any RocksDB access or deserialization fails.
fn get_subtree(&self, index: NodeIndex) -> Result<Option<Subtree>, StorageError> {
let cf = self.subtree_cf(index);
let key = Self::subtree_db_key(index);
let cf = self.subtree_cf(index)?;
let key = Self::subtree_db_key(index)?;
match self.db.get_cf(cf, key).map_err(map_rocksdb_err)? {
Some(bytes) => {
let subtree = Subtree::from_vec(index, &bytes)?;
Expand Down Expand Up @@ -680,9 +680,10 @@ impl SmtStorage for RocksDbStorage {
.map(
|(bucket_index, bucket)| -> Result<Vec<(usize, Option<Subtree>)>, StorageError> {
let depth = SUBTREE_DEPTHS[bucket_index];
let cf = self.cf_handle(cf_for_depth(depth))?;
let keys: Vec<_> =
let cf = self.cf_handle(cf_for_depth(depth)?)?;
let keys: Result<Vec<_>, _> =
bucket.iter().map(|(_, idx)| Self::subtree_db_key(*idx)).collect();
let keys = keys?;

let db_results = self.db.multi_get_cf(keys.iter().map(|k| (cf, k.as_ref())));

Expand Down Expand Up @@ -726,10 +727,10 @@ impl SmtStorage for RocksDbStorage {
/// - Returns `StorageError` if column family lookup, serialization, or the write operation
/// fails.
fn set_subtree(&mut self, subtree: &Subtree) -> Result<(), StorageError> {
let subtrees_cf = self.subtree_cf(subtree.root_index());
let subtrees_cf = self.subtree_cf(subtree.root_index())?;
let mut batch = WriteBatch::default();

let key = Self::subtree_db_key(subtree.root_index());
let key = Self::subtree_db_key(subtree.root_index())?;
let value = subtree.to_vec();
batch.put_cf(subtrees_cf, key, value);

Expand Down Expand Up @@ -768,8 +769,8 @@ impl SmtStorage for RocksDbStorage {
let mut batch = WriteBatch::default();

for subtree in subtrees {
let subtrees_cf = self.subtree_cf(subtree.root_index());
let key = Self::subtree_db_key(subtree.root_index());
let subtrees_cf = self.subtree_cf(subtree.root_index())?;
let key = Self::subtree_db_key(subtree.root_index())?;
let value = subtree.to_vec();
batch.put_cf(subtrees_cf, key, value);

Expand All @@ -791,10 +792,10 @@ impl SmtStorage for RocksDbStorage {
/// - `StorageError::Backend`: If the subtrees column family is missing or a RocksDB error
/// occurs.
fn remove_subtree(&mut self, index: NodeIndex) -> Result<(), StorageError> {
let subtrees_cf = self.subtree_cf(index);
let subtrees_cf = self.subtree_cf(index)?;
let mut batch = WriteBatch::default();

let key = Self::subtree_db_key(index);
let key = Self::subtree_db_key(index)?;
batch.delete_cf(subtrees_cf, key);

// Also remove level 24 hash cache if this is a level 24 subtree
Expand Down Expand Up @@ -958,8 +959,8 @@ impl SmtStorage for RocksDbStorage {
},
};

let key = Self::subtree_db_key(index);
let subtrees_cf = self.subtree_cf(index);
let key = Self::subtree_db_key(index)?;
let subtrees_cf = self.subtree_cf(index)?;

Ok((subtrees_cf, key, maybe_bytes, depth24_op))
})
Expand Down Expand Up @@ -1586,13 +1587,13 @@ fn subtree_root_from_key_bytes(key_bytes: &[u8], depth: u8) -> Result<NodeIndex,

/// Helper that maps an SMT depth to its column family.
#[inline(always)]
fn cf_for_depth(depth: u8) -> &'static str {
fn cf_for_depth(depth: u8) -> Result<&'static str, StorageError> {
match depth {
24 => SUBTREE_24_CF,
32 => SUBTREE_32_CF,
40 => SUBTREE_40_CF,
48 => SUBTREE_48_CF,
56 => SUBTREE_56_CF,
_ => panic!("unsupported subtree depth: {depth}"),
24 => Ok(SUBTREE_24_CF),
32 => Ok(SUBTREE_32_CF),
40 => Ok(SUBTREE_40_CF),
48 => Ok(SUBTREE_48_CF),
56 => Ok(SUBTREE_56_CF),
_ => Err(StorageError::Unsupported(format!("unsupported subtree depth {depth}"))),
}
}
Loading