diff --git a/storage/src/indexer/mod.rs b/storage/src/indexer/mod.rs index 9fa5ebde..f91c40d8 100644 --- a/storage/src/indexer/mod.rs +++ b/storage/src/indexer/mod.rs @@ -8,8 +8,9 @@ use rocksdb::{ use crate::{ BREAKPOINT_INTERVAL, CF_ACC_META, CF_ACC_TO_TX, CF_BLOCK_NAME, CF_BREAKPOINT_NAME, - CF_HASH_TO_ID, CF_META_NAME, CF_TX_TO_ID, DbResult, error::DbError, - storable_cell::SimpleStorableCell, + CF_HASH_TO_ID, CF_META_NAME, CF_TX_TO_ID, DbResult, + error::DbError, + storable_cell::{SimpleReadableCell, SimpleWritableCell}, }; pub mod read_multiple; @@ -120,25 +121,25 @@ impl RocksDBIO { // Generics - fn get(&self) -> DbResult { - T::get(&self.db) + fn get(&self, params: T::KeyParams) -> DbResult { + T::get(&self.db, params) } - #[expect(unused, reason = "Unused")] - fn get_opt(&self) -> DbResult> { - T::get_opt(&self.db) + fn get_opt(&self, params: T::KeyParams) -> DbResult> { + T::get_opt(&self.db, params) } - fn put(&self, cell: &T) -> DbResult<()> { - cell.put(&self.db) + fn put(&self, cell: &T, params: T::KeyParams) -> DbResult<()> { + cell.put(&self.db, params) } - fn put_batch( + fn put_batch( &self, cell: &T, + params: T::KeyParams, write_batch: &mut WriteBatch, ) -> DbResult<()> { - cell.put_batch(&self.db, write_batch) + cell.put_batch(&self.db, params, write_batch) } // State diff --git a/storage/src/indexer/read_once.rs b/storage/src/indexer/read_once.rs index a4ff5877..a7cedd58 100644 --- a/storage/src/indexer/read_once.rs +++ b/storage/src/indexer/read_once.rs @@ -1,8 +1,10 @@ -use super::{Block, DbError, DbResult, RocksDBIO, V03State}; -use crate::{ - DB_META_FIRST_BLOCK_IN_DB_KEY, DB_META_FIRST_BLOCK_SET_KEY, DB_META_LAST_BREAKPOINT_ID, - DB_META_LAST_OBSERVED_L1_LIB_HEADER_ID_IN_DB_KEY, - storable_cell::cells::meta_shared::LastBlockCell, +use super::{Block, DbResult, RocksDBIO, V03State}; +use crate::storable_cell::cells::{ + meta_indexer::{ + AccNumTxCell, BlockHashToBlockIdMapCell, BreakpointCellOwned, LastBreakpointIdCell, + LastObservedL1LibHeaderCell, TxHashToBlockIdMapCell, + }, + meta_shared::{BlockCell, FirstBlockCell, FirstBlockSetCell, LastBlockCell}, }; #[expect(clippy::multiple_inherent_impl, reason = "Readability")] @@ -10,239 +12,55 @@ impl RocksDBIO { // Meta pub fn get_meta_first_block_in_db(&self) -> DbResult { - let cf_meta = self.meta_column(); - let res = self - .db - .get_cf( - &cf_meta, - borsh::to_vec(&DB_META_FIRST_BLOCK_IN_DB_KEY).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize DB_META_FIRST_BLOCK_IN_DB_KEY".to_owned()), - ) - })?, - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; - - if let Some(data) = res { - Ok(borsh::from_slice::(&data).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to deserialize first block".to_owned()), - ) - })?) - } else { - Err(DbError::db_interaction_error( - "First block not found".to_owned(), - )) - } + self.get::(()).map(|cell| cell.0) } pub fn get_meta_last_block_in_db(&self) -> DbResult { - self.get::().map(|cell| cell.0) + self.get::(()).map(|cell| cell.0) } pub fn get_meta_last_observed_l1_lib_header_in_db(&self) -> DbResult> { - let cf_meta = self.meta_column(); - let res = self - .db - .get_cf( - &cf_meta, - borsh::to_vec(&DB_META_LAST_OBSERVED_L1_LIB_HEADER_ID_IN_DB_KEY).map_err( - |err| { - DbError::borsh_cast_message( - err, - Some( - "Failed to serialize DB_META_LAST_OBSERVED_L1_LIB_HEADER_ID_IN_DB_KEY" - .to_owned(), - ), - ) - }, - )?, - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; - - res.map(|data| { - borsh::from_slice::<[u8; 32]>(&data).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to deserialize last l1 lib header".to_owned()), - ) - }) - }) - .transpose() + self.get_opt::(()) + .map(|opt| opt.map(|val| val.0)) } pub fn get_meta_is_first_block_set(&self) -> DbResult { - let cf_meta = self.meta_column(); - let res = self - .db - .get_cf( - &cf_meta, - borsh::to_vec(&DB_META_FIRST_BLOCK_SET_KEY).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize DB_META_FIRST_BLOCK_SET_KEY".to_owned()), - ) - })?, - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; - - Ok(res.is_some()) + Ok(self.get_opt::(())?.is_some()) } pub fn get_meta_last_breakpoint_id(&self) -> DbResult { - let cf_meta = self.meta_column(); - let res = self - .db - .get_cf( - &cf_meta, - borsh::to_vec(&DB_META_LAST_BREAKPOINT_ID).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize DB_META_LAST_BREAKPOINT_ID".to_owned()), - ) - })?, - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; - - if let Some(data) = res { - Ok(borsh::from_slice::(&data).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to deserialize last breakpoint id".to_owned()), - ) - })?) - } else { - Err(DbError::db_interaction_error( - "Last breakpoint id not found".to_owned(), - )) - } + self.get::(()).map(|cell| cell.0) } // Block pub fn get_block(&self, block_id: u64) -> DbResult> { - let cf_block = self.block_column(); - let res = self - .db - .get_cf( - &cf_block, - borsh::to_vec(&block_id).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize block id".to_owned()), - ) - })?, - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; - - if let Some(data) = res { - Ok(Some(borsh::from_slice::(&data).map_err(|serr| { - DbError::borsh_cast_message( - serr, - Some("Failed to deserialize block data".to_owned()), - ) - })?)) - } else { - Ok(None) - } + self.get_opt::(block_id) + .map(|opt| opt.map(|val| val.0)) } // State pub fn get_breakpoint(&self, br_id: u64) -> DbResult { - let cf_br = self.breakpoint_column(); - let res = self - .db - .get_cf( - &cf_br, - borsh::to_vec(&br_id).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize breakpoint id".to_owned()), - ) - })?, - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; - - if let Some(data) = res { - Ok(borsh::from_slice::(&data).map_err(|serr| { - DbError::borsh_cast_message( - serr, - Some("Failed to deserialize breakpoint data".to_owned()), - ) - })?) - } else { - Err(DbError::db_interaction_error( - "Breakpoint on this id not found".to_owned(), - )) - } + self.get::(br_id).map(|cell| cell.0) } // Mappings pub fn get_block_id_by_hash(&self, hash: [u8; 32]) -> DbResult> { - let cf_hti = self.hash_to_id_column(); - let res = self - .db - .get_cf( - &cf_hti, - borsh::to_vec(&hash).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize block hash".to_owned()), - ) - })?, - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; - - if let Some(data) = res { - Ok(Some(borsh::from_slice::(&data).map_err(|serr| { - DbError::borsh_cast_message(serr, Some("Failed to deserialize block id".to_owned())) - })?)) - } else { - Ok(None) - } + self.get_opt::(hash) + .map(|opt| opt.map(|cell| cell.0)) } pub fn get_block_id_by_tx_hash(&self, tx_hash: [u8; 32]) -> DbResult> { - let cf_tti = self.tx_hash_to_id_column(); - let res = self - .db - .get_cf( - &cf_tti, - borsh::to_vec(&tx_hash).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize transaction hash".to_owned()), - ) - })?, - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; - - if let Some(data) = res { - Ok(Some(borsh::from_slice::(&data).map_err(|serr| { - DbError::borsh_cast_message(serr, Some("Failed to deserialize block id".to_owned())) - })?)) - } else { - Ok(None) - } + self.get_opt::(tx_hash) + .map(|opt| opt.map(|cell| cell.0)) } // Accounts meta pub(crate) fn get_acc_meta_num_tx(&self, acc_id: [u8; 32]) -> DbResult> { - let cf_ameta = self.account_meta_column(); - let res = self.db.get_cf(&cf_ameta, acc_id).map_err(|rerr| { - DbError::rocksdb_cast_message(rerr, Some("Failed to read from acc meta cf".to_owned())) - })?; - - res.map(|data| { - borsh::from_slice::(&data).map_err(|serr| { - DbError::borsh_cast_message(serr, Some("Failed to deserialize num tx".to_owned())) - }) - }) - .transpose() + self.get_opt::(acc_id) + .map(|opt| opt.map(|cell| cell.0)) } } diff --git a/storage/src/indexer/write_atomic.rs b/storage/src/indexer/write_atomic.rs index 3274eb8e..cff8284a 100644 --- a/storage/src/indexer/write_atomic.rs +++ b/storage/src/indexer/write_atomic.rs @@ -2,11 +2,16 @@ use std::collections::HashMap; use rocksdb::WriteBatch; -use super::{Arc, BREAKPOINT_INTERVAL, Block, BoundColumnFamily, DbError, DbResult, RocksDBIO}; +use super::{BREAKPOINT_INTERVAL, Block, DbError, DbResult, RocksDBIO}; use crate::{ - DB_META_FIRST_BLOCK_IN_DB_KEY, DB_META_FIRST_BLOCK_SET_KEY, DB_META_LAST_BREAKPOINT_ID, - DB_META_LAST_OBSERVED_L1_LIB_HEADER_ID_IN_DB_KEY, - storable_cell::cells::meta_shared::LastBlockCell, + DB_META_FIRST_BLOCK_IN_DB_KEY, + storable_cell::cells::{ + meta_indexer::{ + AccNumTxCell, BlockHashToBlockIdMapCell, LastBreakpointIdCell, + LastObservedL1LibHeaderCell, TxHashToBlockIdMapCell, + }, + meta_shared::{FirstBlockSetCell, LastBlockCell}, + }, }; #[expect(clippy::multiple_inherent_impl, reason = "Readability")] @@ -19,22 +24,27 @@ impl RocksDBIO { num_tx: u64, write_batch: &mut WriteBatch, ) -> DbResult<()> { - let cf_ameta = self.account_meta_column(); + self.put_batch(&AccNumTxCell(num_tx), acc_id, write_batch) + } - write_batch.put_cf( - &cf_ameta, - borsh::to_vec(&acc_id).map_err(|err| { - DbError::borsh_cast_message(err, Some("Failed to serialize account id".to_owned())) - })?, - borsh::to_vec(&num_tx).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize acc metadata".to_owned()), - ) - })?, - ); + // Mappings - Ok(()) + pub fn put_block_id_by_hash_batch( + &self, + hash: [u8; 32], + block_id: u64, + write_batch: &mut WriteBatch, + ) -> DbResult<()> { + self.put_batch(&BlockHashToBlockIdMapCell(block_id), hash, write_batch) + } + + pub fn put_block_id_by_tx_hash_batch( + &self, + tx_hash: [u8; 32], + block_id: u64, + write_batch: &mut WriteBatch, + ) -> DbResult<()> { + self.put_batch(&TxHashToBlockIdMapCell(block_id), tx_hash, write_batch) } // Account @@ -164,7 +174,7 @@ impl RocksDBIO { block_id: u64, write_batch: &mut WriteBatch, ) -> DbResult<()> { - self.put_batch(&LastBlockCell(block_id), write_batch) + self.put_batch(&LastBlockCell(block_id), (), write_batch) } pub fn put_meta_last_observed_l1_lib_header_in_db_batch( @@ -172,26 +182,7 @@ impl RocksDBIO { l1_lib_header: [u8; 32], write_batch: &mut WriteBatch, ) -> DbResult<()> { - let cf_meta = self.meta_column(); - write_batch.put_cf( - &cf_meta, - borsh::to_vec(&DB_META_LAST_OBSERVED_L1_LIB_HEADER_ID_IN_DB_KEY).map_err(|err| { - DbError::borsh_cast_message( - err, - Some( - "Failed to serialize DB_META_LAST_OBSERVED_L1_LIB_HEADER_ID_IN_DB_KEY" - .to_owned(), - ), - ) - })?, - borsh::to_vec(&l1_lib_header).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize last l1 block header".to_owned()), - ) - })?, - ); - Ok(()) + self.put_batch(&LastObservedL1LibHeaderCell(l1_lib_header), (), write_batch) } pub fn put_meta_last_breakpoint_id_batch( @@ -199,46 +190,17 @@ impl RocksDBIO { br_id: u64, write_batch: &mut WriteBatch, ) -> DbResult<()> { - let cf_meta = self.meta_column(); - write_batch.put_cf( - &cf_meta, - borsh::to_vec(&DB_META_LAST_BREAKPOINT_ID).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize DB_META_LAST_BREAKPOINT_ID".to_owned()), - ) - })?, - borsh::to_vec(&br_id).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize last block id".to_owned()), - ) - })?, - ); - Ok(()) + self.put_batch(&LastBreakpointIdCell(br_id), (), write_batch) } pub fn put_meta_is_first_block_set_batch(&self, write_batch: &mut WriteBatch) -> DbResult<()> { - let cf_meta = self.meta_column(); - write_batch.put_cf( - &cf_meta, - borsh::to_vec(&DB_META_FIRST_BLOCK_SET_KEY).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize DB_META_FIRST_BLOCK_SET_KEY".to_owned()), - ) - })?, - [1_u8; 1], - ); - Ok(()) + self.put_batch(&FirstBlockSetCell(true), (), write_batch) } // Block pub fn put_block(&self, block: &Block, l1_lib_header: [u8; 32]) -> DbResult<()> { let cf_block = self.block_column(); - let cf_hti = self.hash_to_id_column(); - let cf_tti: Arc> = self.tx_hash_to_id_column(); let last_curr_block = self.get_meta_last_block_in_db()?; let mut write_batch = WriteBatch::default(); @@ -257,33 +219,22 @@ impl RocksDBIO { self.put_meta_last_observed_l1_lib_header_in_db_batch(l1_lib_header, &mut write_batch)?; } - write_batch.put_cf( - &cf_hti, - borsh::to_vec(&block.header.hash).map_err(|err| { - DbError::borsh_cast_message(err, Some("Failed to serialize block hash".to_owned())) - })?, - borsh::to_vec(&block.header.block_id).map_err(|err| { - DbError::borsh_cast_message(err, Some("Failed to serialize block id".to_owned())) - })?, - ); + self.put_block_id_by_hash_batch( + block.header.hash.into(), + block.header.block_id, + &mut write_batch, + )?; let mut acc_to_tx_map: HashMap<[u8; 32], Vec<[u8; 32]>> = HashMap::new(); for tx in &block.body.transactions { let tx_hash = tx.hash(); - write_batch.put_cf( - &cf_tti, - borsh::to_vec(&tx_hash).map_err(|err| { - DbError::borsh_cast_message(err, Some("Failed to serialize tx hash".to_owned())) - })?, - borsh::to_vec(&block.header.block_id).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize block id".to_owned()), - ) - })?, - ); + self.put_block_id_by_tx_hash_batch( + tx_hash.into(), + block.header.block_id, + &mut write_batch, + )?; let acc_ids = tx .affected_public_account_ids() diff --git a/storage/src/indexer/write_non_atomic.rs b/storage/src/indexer/write_non_atomic.rs index f44cda7d..96d133e4 100644 --- a/storage/src/indexer/write_non_atomic.rs +++ b/storage/src/indexer/write_non_atomic.rs @@ -1,8 +1,7 @@ use super::{BREAKPOINT_INTERVAL, DbError, DbResult, RocksDBIO, V03State}; -use crate::{ - DB_META_FIRST_BLOCK_SET_KEY, DB_META_LAST_BREAKPOINT_ID, - DB_META_LAST_OBSERVED_L1_LIB_HEADER_ID_IN_DB_KEY, - storable_cell::cells::meta_shared::LastBlockCell, +use crate::storable_cell::cells::{ + meta_indexer::{BreakpointCellRef, LastBreakpointIdCell, LastObservedL1LibHeaderCell}, + meta_shared::{FirstBlockSetCell, LastBlockCell}, }; #[expect(clippy::multiple_inherent_impl, reason = "Readability")] @@ -10,100 +9,28 @@ impl RocksDBIO { // Meta pub fn put_meta_last_block_in_db(&self, block_id: u64) -> DbResult<()> { - self.put(&LastBlockCell(block_id)) + self.put(&LastBlockCell(block_id), ()) } pub fn put_meta_last_observed_l1_lib_header_in_db( &self, l1_lib_header: [u8; 32], ) -> DbResult<()> { - let cf_meta = self.meta_column(); - self.db - .put_cf( - &cf_meta, - borsh::to_vec(&DB_META_LAST_OBSERVED_L1_LIB_HEADER_ID_IN_DB_KEY).map_err( - |err| { - DbError::borsh_cast_message( - err, - Some( - "Failed to serialize DB_META_LAST_OBSERVED_L1_LIB_HEADER_ID_IN_DB_KEY" - .to_owned(), - ), - ) - }, - )?, - borsh::to_vec(&l1_lib_header).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize last l1 block header".to_owned()), - ) - })?, - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; - Ok(()) + self.put(&LastObservedL1LibHeaderCell(l1_lib_header), ()) } pub fn put_meta_last_breakpoint_id(&self, br_id: u64) -> DbResult<()> { - let cf_meta = self.meta_column(); - self.db - .put_cf( - &cf_meta, - borsh::to_vec(&DB_META_LAST_BREAKPOINT_ID).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize DB_META_LAST_BREAKPOINT_ID".to_owned()), - ) - })?, - borsh::to_vec(&br_id).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize last block id".to_owned()), - ) - })?, - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; - Ok(()) + self.put(&LastBreakpointIdCell(br_id), ()) } pub fn put_meta_is_first_block_set(&self) -> DbResult<()> { - let cf_meta = self.meta_column(); - self.db - .put_cf( - &cf_meta, - borsh::to_vec(&DB_META_FIRST_BLOCK_SET_KEY).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize DB_META_FIRST_BLOCK_SET_KEY".to_owned()), - ) - })?, - [1_u8; 1], - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; - Ok(()) + self.put(&FirstBlockSetCell(true), ()) } // State pub fn put_breakpoint(&self, br_id: u64, breakpoint: &V03State) -> DbResult<()> { - let cf_br = self.breakpoint_column(); - - self.db - .put_cf( - &cf_br, - borsh::to_vec(&br_id).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize breakpoint id".to_owned()), - ) - })?, - borsh::to_vec(breakpoint).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize breakpoint data".to_owned()), - ) - })?, - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None)) + self.put(&BreakpointCellRef(breakpoint), br_id) } pub fn put_next_breakpoint(&self) -> DbResult<()> { diff --git a/storage/src/lib.rs b/storage/src/lib.rs index b1126626..9aa17356 100644 --- a/storage/src/lib.rs +++ b/storage/src/lib.rs @@ -5,8 +5,6 @@ pub mod indexer; pub mod sequencer; pub mod storable_cell; -pub type DbResult = Result; - // General /// Maximal size of stored blocks in base. @@ -67,3 +65,5 @@ pub const DB_NSSA_STATE_KEY: &str = "nssa_state"; /// Name of state column family. pub const CF_NSSA_STATE_NAME: &str = "cf_nssa_state"; + +pub type DbResult = Result; diff --git a/storage/src/sequencer.rs b/storage/src/sequencer.rs index f04785e5..c3424fb7 100644 --- a/storage/src/sequencer.rs +++ b/storage/src/sequencer.rs @@ -8,10 +8,17 @@ use rocksdb::{ use crate::{ CF_BLOCK_NAME, CF_META_NAME, CF_NSSA_STATE_NAME, DB_META_FIRST_BLOCK_IN_DB_KEY, - DB_META_FIRST_BLOCK_SET_KEY, DB_META_LAST_FINALIZED_BLOCK_ID, DB_META_LATEST_BLOCK_META_KEY, - DB_NSSA_STATE_KEY, error::DbError, - storable_cell::{SimpleStorableCell, cells::meta_shared::LastBlockCell}, + storable_cell::{ + SimpleReadableCell, SimpleWritableCell, + cells::{ + meta_sequencer::{ + LastFinalizedBlockIdCell, LatestBlockMetaCellOwned, LatestBlockMetaCellRef, + NSSAStateCellOwned, NSSAStateCellRef, + }, + meta_shared::{BlockCell, FirstBlockCell, FirstBlockSetCell, LastBlockCell}, + }, + }, }; pub type DbResult = Result; @@ -80,108 +87,65 @@ impl RocksDBIO { .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None)) } + // Columns + pub fn meta_column(&self) -> Arc> { - self.db.cf_handle(CF_META_NAME).unwrap() + self.db + .cf_handle(CF_META_NAME) + .expect("Meta column should exist") } pub fn block_column(&self) -> Arc> { - self.db.cf_handle(CF_BLOCK_NAME).unwrap() + self.db + .cf_handle(CF_BLOCK_NAME) + .expect("Block column should exist") } pub fn nssa_state_column(&self) -> Arc> { - self.db.cf_handle(CF_NSSA_STATE_NAME).unwrap() + self.db + .cf_handle(CF_NSSA_STATE_NAME) + .expect("State should exist") } // Generics - fn get(&self) -> DbResult { - T::get(&self.db) + fn get(&self, params: T::KeyParams) -> DbResult { + T::get(&self.db, params) } - #[expect(unused, reason = "Unused")] - fn get_opt(&self) -> DbResult> { - T::get_opt(&self.db) + fn get_opt(&self, params: T::KeyParams) -> DbResult> { + T::get_opt(&self.db, params) } - fn put(&self, cell: &T) -> DbResult<()> { - cell.put(&self.db) + fn put(&self, cell: &T, params: T::KeyParams) -> DbResult<()> { + cell.put(&self.db, params) } - fn put_batch( + fn put_batch( &self, cell: &T, + params: T::KeyParams, write_batch: &mut WriteBatch, ) -> DbResult<()> { - cell.put_batch(&self.db, write_batch) + cell.put_batch(&self.db, params, write_batch) } - pub fn get_meta_first_block_in_db(&self) -> DbResult { - let cf_meta = self.meta_column(); - let res = self - .db - .get_cf( - &cf_meta, - borsh::to_vec(&DB_META_FIRST_BLOCK_IN_DB_KEY).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize DB_META_FIRST_BLOCK_IN_DB_KEY".to_owned()), - ) - })?, - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; + // Meta - if let Some(data) = res { - Ok(borsh::from_slice::(&data).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to deserialize first block".to_owned()), - ) - })?) - } else { - Err(DbError::db_interaction_error( - "First block not found".to_owned(), - )) - } + pub fn get_meta_first_block_in_db(&self) -> DbResult { + self.get::(()).map(|cell| cell.0) } pub fn get_meta_last_block_in_db(&self) -> DbResult { - self.get::().map(|cell| cell.0) + self.get::(()).map(|cell| cell.0) } pub fn get_meta_is_first_block_set(&self) -> DbResult { - let cf_meta = self.meta_column(); - let res = self - .db - .get_cf( - &cf_meta, - borsh::to_vec(&DB_META_FIRST_BLOCK_SET_KEY).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize DB_META_FIRST_BLOCK_SET_KEY".to_owned()), - ) - })?, - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; - - Ok(res.is_some()) + Ok(self.get_opt::(())?.is_some()) } pub fn put_nssa_state_in_db(&self, state: &V03State, batch: &mut WriteBatch) -> DbResult<()> { - let cf_nssa_state = self.nssa_state_column(); - batch.put_cf( - &cf_nssa_state, - borsh::to_vec(&DB_NSSA_STATE_KEY).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize DB_NSSA_STATE_KEY".to_owned()), - ) - })?, - borsh::to_vec(state).map_err(|err| { - DbError::borsh_cast_message(err, Some("Failed to serialize NSSA state".to_owned())) - })?, - ); - - Ok(()) + self.put_batch(&NSSAStateCellRef(state), (), batch) } pub fn put_meta_first_block_in_db(&self, block: &Block, msg_id: MantleMsgId) -> DbResult<()> { @@ -217,7 +181,7 @@ impl RocksDBIO { } pub fn put_meta_last_block_in_db(&self, block_id: u64) -> DbResult<()> { - self.put(&LastBlockCell(block_id)) + self.put(&LastBlockCell(block_id), ()) } fn put_meta_last_block_in_db_batch( @@ -225,68 +189,19 @@ impl RocksDBIO { block_id: u64, batch: &mut WriteBatch, ) -> DbResult<()> { - self.put_batch(&LastBlockCell(block_id), batch) + self.put_batch(&LastBlockCell(block_id), (), batch) } pub fn put_meta_last_finalized_block_id(&self, block_id: Option) -> DbResult<()> { - let cf_meta = self.meta_column(); - self.db - .put_cf( - &cf_meta, - borsh::to_vec(&DB_META_LAST_FINALIZED_BLOCK_ID).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize DB_META_LAST_FINALIZED_BLOCK_ID".to_owned()), - ) - })?, - borsh::to_vec(&block_id).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize last block id".to_owned()), - ) - })?, - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; - Ok(()) + self.put(&LastFinalizedBlockIdCell(block_id), ()) } pub fn put_meta_is_first_block_set(&self) -> DbResult<()> { - let cf_meta = self.meta_column(); - self.db - .put_cf( - &cf_meta, - borsh::to_vec(&DB_META_FIRST_BLOCK_SET_KEY).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize DB_META_FIRST_BLOCK_SET_KEY".to_owned()), - ) - })?, - [1_u8; 1], - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; - Ok(()) + self.put(&FirstBlockSetCell(true), ()) } fn put_meta_latest_block_meta(&self, block_meta: &BlockMeta) -> DbResult<()> { - let cf_meta = self.meta_column(); - self.db - .put_cf( - &cf_meta, - borsh::to_vec(&DB_META_LATEST_BLOCK_META_KEY).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize DB_META_LATEST_BLOCK_META_KEY".to_owned()), - ) - })?, - borsh::to_vec(&block_meta).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize latest block meta".to_owned()), - ) - })?, - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; - Ok(()) + self.put(&LatestBlockMetaCellRef(block_meta), ()) } fn put_meta_latest_block_meta_batch( @@ -294,52 +209,11 @@ impl RocksDBIO { block_meta: &BlockMeta, batch: &mut WriteBatch, ) -> DbResult<()> { - let cf_meta = self.meta_column(); - batch.put_cf( - &cf_meta, - borsh::to_vec(&DB_META_LATEST_BLOCK_META_KEY).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize DB_META_LATEST_BLOCK_META_KEY".to_owned()), - ) - })?, - borsh::to_vec(&block_meta).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize latest block meta".to_owned()), - ) - })?, - ); - Ok(()) + self.put_batch(&LatestBlockMetaCellRef(block_meta), (), batch) } pub fn latest_block_meta(&self) -> DbResult { - let cf_meta = self.meta_column(); - let res = self - .db - .get_cf( - &cf_meta, - borsh::to_vec(&DB_META_LATEST_BLOCK_META_KEY).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize DB_META_LATEST_BLOCK_META_KEY".to_owned()), - ) - })?, - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; - - if let Some(data) = res { - Ok(borsh::from_slice::(&data).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to deserialize latest block meta".to_owned()), - ) - })?) - } else { - Err(DbError::db_interaction_error( - "Latest block meta not found".to_owned(), - )) - } + self.get::(()).map(|val| val.0) } pub fn put_block( @@ -380,59 +254,12 @@ impl RocksDBIO { } pub fn get_block(&self, block_id: u64) -> DbResult> { - let cf_block = self.block_column(); - let res = self - .db - .get_cf( - &cf_block, - borsh::to_vec(&block_id).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize block id".to_owned()), - ) - })?, - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; - - if let Some(data) = res { - Ok(Some(borsh::from_slice::(&data).map_err(|serr| { - DbError::borsh_cast_message( - serr, - Some("Failed to deserialize block data".to_owned()), - ) - })?)) - } else { - Ok(None) - } + self.get_opt::(block_id) + .map(|opt| opt.map(|val| val.0)) } pub fn get_nssa_state(&self) -> DbResult { - let cf_nssa_state = self.nssa_state_column(); - let res = self - .db - .get_cf( - &cf_nssa_state, - borsh::to_vec(&DB_NSSA_STATE_KEY).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize block id".to_owned()), - ) - })?, - ) - .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; - - if let Some(data) = res { - Ok(borsh::from_slice::(&data).map_err(|serr| { - DbError::borsh_cast_message( - serr, - Some("Failed to deserialize block data".to_owned()), - ) - })?) - } else { - Err(DbError::db_interaction_error( - "NSSA state not found".to_owned(), - )) - } + self.get::(()).map(|val| val.0) } pub fn delete_block(&self, block_id: u64) -> DbResult<()> { diff --git a/storage/src/storable_cell/cells/meta_indexer.rs b/storage/src/storable_cell/cells/meta_indexer.rs index 8b137891..7322ba8f 100644 --- a/storage/src/storable_cell/cells/meta_indexer.rs +++ b/storage/src/storable_cell/cells/meta_indexer.rs @@ -1 +1,287 @@ +use borsh::{BorshDeserialize, BorshSerialize}; +use nssa::V03State; +use crate::{ + CF_ACC_META, CF_BREAKPOINT_NAME, CF_HASH_TO_ID, CF_META_NAME, CF_TX_TO_ID, + DB_META_LAST_BREAKPOINT_ID, DB_META_LAST_OBSERVED_L1_LIB_HEADER_ID_IN_DB_KEY, DbResult, + error::DbError, + storable_cell::{SimpleReadableCell, SimpleStorableCell, SimpleWritableCell}, +}; + +#[derive(Debug)] +pub struct LastObservedL1LibHeaderCell(pub [u8; 32]); + +impl BorshSerialize for LastObservedL1LibHeaderCell { + fn serialize(&self, writer: &mut W) -> std::io::Result<()> { + <[u8; 32]>::serialize(&self.0, writer) + } +} + +impl BorshDeserialize for LastObservedL1LibHeaderCell { + fn deserialize_reader(reader: &mut R) -> std::io::Result { + <[u8; 32]>::deserialize_reader(reader).map(LastObservedL1LibHeaderCell) + } +} + +impl SimpleStorableCell for LastObservedL1LibHeaderCell { + type KeyParams = (); + + const CELL_NAME: &'static str = DB_META_LAST_OBSERVED_L1_LIB_HEADER_ID_IN_DB_KEY; + const CF_NAME: &'static str = CF_META_NAME; + + fn key_constructor(_params: Self::KeyParams) -> DbResult> { + borsh::to_vec(&Self::CELL_NAME).map_err(|err| { + DbError::borsh_cast_message( + err, + Some(format!("Failed to serialize {:?}", Self::CELL_NAME)), + ) + }) + } + + fn value_constructor(&self) -> DbResult> { + borsh::to_vec(&self).map_err(|err| { + DbError::borsh_cast_message( + err, + Some("Failed to serialize last observed l1 header".to_owned()), + ) + }) + } +} + +impl SimpleReadableCell for LastObservedL1LibHeaderCell {} + +impl SimpleWritableCell for LastObservedL1LibHeaderCell {} + +#[derive(Debug)] +pub struct LastBreakpointIdCell(pub u64); + +impl BorshSerialize for LastBreakpointIdCell { + fn serialize(&self, writer: &mut W) -> std::io::Result<()> { + u64::serialize(&self.0, writer) + } +} + +impl BorshDeserialize for LastBreakpointIdCell { + fn deserialize_reader(reader: &mut R) -> std::io::Result { + u64::deserialize_reader(reader).map(LastBreakpointIdCell) + } +} + +impl SimpleStorableCell for LastBreakpointIdCell { + type KeyParams = (); + + const CELL_NAME: &'static str = DB_META_LAST_BREAKPOINT_ID; + const CF_NAME: &'static str = CF_META_NAME; + + fn key_constructor(_params: Self::KeyParams) -> DbResult> { + borsh::to_vec(&Self::CELL_NAME).map_err(|err| { + DbError::borsh_cast_message( + err, + Some(format!("Failed to serialize {:?}", Self::CELL_NAME)), + ) + }) + } + + fn value_constructor(&self) -> DbResult> { + borsh::to_vec(&self).map_err(|err| { + DbError::borsh_cast_message( + err, + Some("Failed to serialize last breakpoint id".to_owned()), + ) + }) + } +} + +impl SimpleReadableCell for LastBreakpointIdCell {} + +impl SimpleWritableCell for LastBreakpointIdCell {} + +pub struct BreakpointCellOwned(pub V03State); + +impl BorshDeserialize for BreakpointCellOwned { + fn deserialize_reader(reader: &mut R) -> std::io::Result { + V03State::deserialize_reader(reader).map(BreakpointCellOwned) + } +} + +impl SimpleStorableCell for BreakpointCellOwned { + type KeyParams = u64; + + const CELL_NAME: &'static str = "breakpoint"; + const CF_NAME: &'static str = CF_BREAKPOINT_NAME; + + fn key_constructor(params: Self::KeyParams) -> DbResult> { + borsh::to_vec(¶ms).map_err(|err| { + DbError::borsh_cast_message( + err, + Some(format!("Failed to serialize {:?}", Self::CELL_NAME)), + ) + }) + } + + fn value_constructor(&self) -> DbResult> { + borsh::to_vec(&self.0).map_err(|err| { + DbError::borsh_cast_message(err, Some("Failed to serialize breakpoint".to_owned())) + }) + } +} + +impl SimpleReadableCell for BreakpointCellOwned {} + +pub struct BreakpointCellRef<'state>(pub &'state V03State); + +impl BorshSerialize for BreakpointCellRef<'_> { + fn serialize(&self, writer: &mut W) -> std::io::Result<()> { + V03State::serialize(self.0, writer) + } +} + +impl SimpleStorableCell for BreakpointCellRef<'_> { + type KeyParams = u64; + + const CELL_NAME: &'static str = "breakpoint"; + const CF_NAME: &'static str = CF_BREAKPOINT_NAME; + + fn key_constructor(params: Self::KeyParams) -> DbResult> { + borsh::to_vec(¶ms).map_err(|err| { + DbError::borsh_cast_message( + err, + Some(format!("Failed to serialize {:?}", Self::CELL_NAME)), + ) + }) + } + + fn value_constructor(&self) -> DbResult> { + borsh::to_vec(&self).map_err(|err| { + DbError::borsh_cast_message(err, Some("Failed to serialize breakpoint".to_owned())) + }) + } +} + +impl SimpleWritableCell for BreakpointCellRef<'_> {} + +#[derive(Debug)] +pub struct BlockHashToBlockIdMapCell(pub u64); + +impl BorshSerialize for BlockHashToBlockIdMapCell { + fn serialize(&self, writer: &mut W) -> std::io::Result<()> { + u64::serialize(&self.0, writer) + } +} + +impl BorshDeserialize for BlockHashToBlockIdMapCell { + fn deserialize_reader(reader: &mut R) -> std::io::Result { + u64::deserialize_reader(reader).map(BlockHashToBlockIdMapCell) + } +} + +impl SimpleStorableCell for BlockHashToBlockIdMapCell { + type KeyParams = [u8; 32]; + + const CELL_NAME: &'static str = "block hash"; + const CF_NAME: &'static str = CF_HASH_TO_ID; + + fn key_constructor(params: Self::KeyParams) -> DbResult> { + borsh::to_vec(¶ms).map_err(|err| { + DbError::borsh_cast_message( + err, + Some(format!("Failed to serialize {:?}", Self::CELL_NAME)), + ) + }) + } + + fn value_constructor(&self) -> DbResult> { + borsh::to_vec(&self).map_err(|err| { + DbError::borsh_cast_message(err, Some("Failed to serialize block id".to_owned())) + }) + } +} + +impl SimpleReadableCell for BlockHashToBlockIdMapCell {} + +impl SimpleWritableCell for BlockHashToBlockIdMapCell {} + +#[derive(Debug)] +pub struct TxHashToBlockIdMapCell(pub u64); + +impl BorshSerialize for TxHashToBlockIdMapCell { + fn serialize(&self, writer: &mut W) -> std::io::Result<()> { + u64::serialize(&self.0, writer) + } +} + +impl BorshDeserialize for TxHashToBlockIdMapCell { + fn deserialize_reader(reader: &mut R) -> std::io::Result { + u64::deserialize_reader(reader).map(TxHashToBlockIdMapCell) + } +} + +impl SimpleStorableCell for TxHashToBlockIdMapCell { + type KeyParams = [u8; 32]; + + const CELL_NAME: &'static str = "tx hash"; + const CF_NAME: &'static str = CF_TX_TO_ID; + + fn key_constructor(params: Self::KeyParams) -> DbResult> { + borsh::to_vec(¶ms).map_err(|err| { + DbError::borsh_cast_message( + err, + Some(format!("Failed to serialize {:?}", Self::CELL_NAME)), + ) + }) + } + + fn value_constructor(&self) -> DbResult> { + borsh::to_vec(&self).map_err(|err| { + DbError::borsh_cast_message(err, Some("Failed to serialize block id".to_owned())) + }) + } +} + +impl SimpleReadableCell for TxHashToBlockIdMapCell {} + +impl SimpleWritableCell for TxHashToBlockIdMapCell {} + +#[derive(Debug)] +pub struct AccNumTxCell(pub u64); + +impl BorshSerialize for AccNumTxCell { + fn serialize(&self, writer: &mut W) -> std::io::Result<()> { + u64::serialize(&self.0, writer) + } +} + +impl BorshDeserialize for AccNumTxCell { + fn deserialize_reader(reader: &mut R) -> std::io::Result { + u64::deserialize_reader(reader).map(AccNumTxCell) + } +} + +impl SimpleStorableCell for AccNumTxCell { + type KeyParams = [u8; 32]; + + const CELL_NAME: &'static str = "acc id"; + const CF_NAME: &'static str = CF_ACC_META; + + fn key_constructor(params: Self::KeyParams) -> DbResult> { + borsh::to_vec(¶ms).map_err(|err| { + DbError::borsh_cast_message( + err, + Some(format!("Failed to serialize {:?}", Self::CELL_NAME)), + ) + }) + } + + fn value_constructor(&self) -> DbResult> { + borsh::to_vec(&self).map_err(|err| { + DbError::borsh_cast_message( + err, + Some("Failed to serialize number of transactions".to_owned()), + ) + }) + } +} + +impl SimpleReadableCell for AccNumTxCell {} + +impl SimpleWritableCell for AccNumTxCell {} diff --git a/storage/src/storable_cell/cells/meta_sequencer.rs b/storage/src/storable_cell/cells/meta_sequencer.rs index 8b137891..9c564fd5 100644 --- a/storage/src/storable_cell/cells/meta_sequencer.rs +++ b/storage/src/storable_cell/cells/meta_sequencer.rs @@ -1 +1,182 @@ +use borsh::{BorshDeserialize, BorshSerialize}; +use common::block::BlockMeta; +use nssa::V03State; +use crate::{ + CF_META_NAME, CF_NSSA_STATE_NAME, DB_META_LAST_FINALIZED_BLOCK_ID, + DB_META_LATEST_BLOCK_META_KEY, DB_NSSA_STATE_KEY, DbResult, + error::DbError, + storable_cell::{SimpleReadableCell, SimpleStorableCell, SimpleWritableCell}, +}; + +pub struct NSSAStateCellOwned(pub V03State); + +impl BorshDeserialize for NSSAStateCellOwned { + fn deserialize_reader(reader: &mut R) -> std::io::Result { + V03State::deserialize_reader(reader).map(NSSAStateCellOwned) + } +} + +impl SimpleStorableCell for NSSAStateCellOwned { + type KeyParams = (); + + const CELL_NAME: &'static str = DB_NSSA_STATE_KEY; + const CF_NAME: &'static str = CF_NSSA_STATE_NAME; + + fn key_constructor(_params: Self::KeyParams) -> DbResult> { + borsh::to_vec(&Self::CELL_NAME).map_err(|err| { + DbError::borsh_cast_message( + err, + Some(format!("Failed to serialize {:?}", Self::CELL_NAME)), + ) + }) + } + + fn value_constructor(&self) -> DbResult> { + borsh::to_vec(&self.0).map_err(|err| { + DbError::borsh_cast_message(err, Some("Failed to serialize last state".to_owned())) + }) + } +} + +impl SimpleReadableCell for NSSAStateCellOwned {} + +pub struct NSSAStateCellRef<'state>(pub &'state V03State); + +impl BorshSerialize for NSSAStateCellRef<'_> { + fn serialize(&self, writer: &mut W) -> std::io::Result<()> { + V03State::serialize(self.0, writer) + } +} + +impl SimpleStorableCell for NSSAStateCellRef<'_> { + type KeyParams = (); + + const CELL_NAME: &'static str = DB_NSSA_STATE_KEY; + const CF_NAME: &'static str = CF_NSSA_STATE_NAME; + + fn key_constructor(_params: Self::KeyParams) -> DbResult> { + borsh::to_vec(&Self::CELL_NAME).map_err(|err| { + DbError::borsh_cast_message( + err, + Some(format!("Failed to serialize {:?}", Self::CELL_NAME)), + ) + }) + } + + fn value_constructor(&self) -> DbResult> { + borsh::to_vec(&self).map_err(|err| { + DbError::borsh_cast_message(err, Some("Failed to serialize last state".to_owned())) + }) + } +} + +impl SimpleWritableCell for NSSAStateCellRef<'_> {} + +#[derive(Debug)] +pub struct LastFinalizedBlockIdCell(pub Option); + +impl BorshSerialize for LastFinalizedBlockIdCell { + fn serialize(&self, writer: &mut W) -> std::io::Result<()> { + Option::::serialize(&self.0, writer) + } +} + +impl BorshDeserialize for LastFinalizedBlockIdCell { + fn deserialize_reader(reader: &mut R) -> std::io::Result { + Option::::deserialize_reader(reader).map(LastFinalizedBlockIdCell) + } +} + +impl SimpleStorableCell for LastFinalizedBlockIdCell { + type KeyParams = (); + + const CELL_NAME: &'static str = DB_META_LAST_FINALIZED_BLOCK_ID; + const CF_NAME: &'static str = CF_META_NAME; + + fn key_constructor(_params: Self::KeyParams) -> DbResult> { + borsh::to_vec(&Self::CELL_NAME).map_err(|err| { + DbError::borsh_cast_message( + err, + Some(format!("Failed to serialize {:?}", Self::CELL_NAME)), + ) + }) + } + + fn value_constructor(&self) -> DbResult> { + borsh::to_vec(&self).map_err(|err| { + DbError::borsh_cast_message( + err, + Some("Failed to serialize last finalized block id".to_owned()), + ) + }) + } +} + +impl SimpleReadableCell for LastFinalizedBlockIdCell {} + +impl SimpleWritableCell for LastFinalizedBlockIdCell {} + +pub struct LatestBlockMetaCellOwned(pub BlockMeta); + +impl BorshDeserialize for LatestBlockMetaCellOwned { + fn deserialize_reader(reader: &mut R) -> std::io::Result { + BlockMeta::deserialize_reader(reader).map(LatestBlockMetaCellOwned) + } +} + +impl SimpleStorableCell for LatestBlockMetaCellOwned { + type KeyParams = (); + + const CELL_NAME: &'static str = DB_META_LATEST_BLOCK_META_KEY; + const CF_NAME: &'static str = CF_META_NAME; + + fn key_constructor(_params: Self::KeyParams) -> DbResult> { + borsh::to_vec(&Self::CELL_NAME).map_err(|err| { + DbError::borsh_cast_message( + err, + Some(format!("Failed to serialize {:?}", Self::CELL_NAME)), + ) + }) + } + + fn value_constructor(&self) -> DbResult> { + borsh::to_vec(&self.0).map_err(|err| { + DbError::borsh_cast_message(err, Some("Failed to serialize last block meta".to_owned())) + }) + } +} + +impl SimpleReadableCell for LatestBlockMetaCellOwned {} + +pub struct LatestBlockMetaCellRef<'blockmeta>(pub &'blockmeta BlockMeta); + +impl BorshSerialize for LatestBlockMetaCellRef<'_> { + fn serialize(&self, writer: &mut W) -> std::io::Result<()> { + BlockMeta::serialize(self.0, writer) + } +} + +impl SimpleStorableCell for LatestBlockMetaCellRef<'_> { + type KeyParams = (); + + const CELL_NAME: &'static str = DB_META_LATEST_BLOCK_META_KEY; + const CF_NAME: &'static str = CF_META_NAME; + + fn key_constructor(_params: Self::KeyParams) -> DbResult> { + borsh::to_vec(&Self::CELL_NAME).map_err(|err| { + DbError::borsh_cast_message( + err, + Some(format!("Failed to serialize {:?}", Self::CELL_NAME)), + ) + }) + } + + fn value_constructor(&self) -> DbResult> { + borsh::to_vec(&self).map_err(|err| { + DbError::borsh_cast_message(err, Some("Failed to serialize last block meta".to_owned())) + }) + } +} + +impl SimpleWritableCell for LatestBlockMetaCellRef<'_> {} diff --git a/storage/src/storable_cell/cells/meta_shared.rs b/storage/src/storable_cell/cells/meta_shared.rs index 4b88a385..21ca74fc 100644 --- a/storage/src/storable_cell/cells/meta_shared.rs +++ b/storage/src/storable_cell/cells/meta_shared.rs @@ -1,8 +1,11 @@ use borsh::{BorshDeserialize, BorshSerialize}; +use common::block::Block; use crate::{ - CF_META_NAME, DB_META_LAST_BLOCK_IN_DB_KEY, DbResult, error::DbError, - storable_cell::SimpleStorableCell, + CF_BLOCK_NAME, CF_META_NAME, DB_META_FIRST_BLOCK_IN_DB_KEY, DB_META_FIRST_BLOCK_SET_KEY, + DB_META_LAST_BLOCK_IN_DB_KEY, DbResult, + error::DbError, + storable_cell::{SimpleReadableCell, SimpleStorableCell, SimpleWritableCell}, }; #[derive(Debug)] @@ -21,10 +24,12 @@ impl BorshDeserialize for LastBlockCell { } impl SimpleStorableCell for LastBlockCell { + type KeyParams = (); + const CELL_NAME: &'static str = DB_META_LAST_BLOCK_IN_DB_KEY; const CF_NAME: &'static str = CF_META_NAME; - fn key_constructor() -> DbResult> { + fn key_constructor(_params: Self::KeyParams) -> DbResult> { borsh::to_vec(&Self::CELL_NAME).map_err(|err| { DbError::borsh_cast_message( err, @@ -34,8 +39,135 @@ impl SimpleStorableCell for LastBlockCell { } fn value_constructor(&self) -> DbResult> { - borsh::to_vec(&self.0).map_err(|err| { + borsh::to_vec(&self).map_err(|err| { DbError::borsh_cast_message(err, Some("Failed to serialize last block id".to_owned())) }) } } + +impl SimpleReadableCell for LastBlockCell {} + +impl SimpleWritableCell for LastBlockCell {} + +#[derive(Debug)] +pub struct FirstBlockSetCell(pub bool); + +impl BorshSerialize for FirstBlockSetCell { + fn serialize(&self, writer: &mut W) -> std::io::Result<()> { + bool::serialize(&self.0, writer) + } +} + +impl BorshDeserialize for FirstBlockSetCell { + fn deserialize_reader(reader: &mut R) -> std::io::Result { + bool::deserialize_reader(reader).map(FirstBlockSetCell) + } +} + +impl SimpleStorableCell for FirstBlockSetCell { + type KeyParams = (); + + const CELL_NAME: &'static str = DB_META_FIRST_BLOCK_SET_KEY; + const CF_NAME: &'static str = CF_META_NAME; + + fn key_constructor(_params: Self::KeyParams) -> DbResult> { + borsh::to_vec(&Self::CELL_NAME).map_err(|err| { + DbError::borsh_cast_message( + err, + Some(format!("Failed to serialize {:?}", Self::CELL_NAME)), + ) + }) + } + + fn value_constructor(&self) -> DbResult> { + borsh::to_vec(&self).map_err(|err| { + DbError::borsh_cast_message( + err, + Some("Failed to serialize first block set flag".to_owned()), + ) + }) + } +} + +impl SimpleReadableCell for FirstBlockSetCell {} + +impl SimpleWritableCell for FirstBlockSetCell {} + +#[derive(Debug)] +pub struct FirstBlockCell(pub u64); + +impl BorshSerialize for FirstBlockCell { + fn serialize(&self, writer: &mut W) -> std::io::Result<()> { + u64::serialize(&self.0, writer) + } +} + +impl BorshDeserialize for FirstBlockCell { + fn deserialize_reader(reader: &mut R) -> std::io::Result { + u64::deserialize_reader(reader).map(FirstBlockCell) + } +} + +impl SimpleStorableCell for FirstBlockCell { + type KeyParams = (); + + const CELL_NAME: &'static str = DB_META_FIRST_BLOCK_IN_DB_KEY; + const CF_NAME: &'static str = CF_META_NAME; + + fn key_constructor(_params: Self::KeyParams) -> DbResult> { + borsh::to_vec(&Self::CELL_NAME).map_err(|err| { + DbError::borsh_cast_message( + err, + Some(format!("Failed to serialize {:?}", Self::CELL_NAME)), + ) + }) + } + + fn value_constructor(&self) -> DbResult> { + borsh::to_vec(&self).map_err(|err| { + DbError::borsh_cast_message(err, Some("Failed to serialize first block id".to_owned())) + }) + } +} + +impl SimpleReadableCell for FirstBlockCell {} + +#[derive(Debug)] +pub struct BlockCell(pub Block); + +impl BorshSerialize for BlockCell { + fn serialize(&self, writer: &mut W) -> std::io::Result<()> { + Block::serialize(&self.0, writer) + } +} + +impl BorshDeserialize for BlockCell { + fn deserialize_reader(reader: &mut R) -> std::io::Result { + Block::deserialize_reader(reader).map(BlockCell) + } +} + +impl SimpleStorableCell for BlockCell { + type KeyParams = u64; + + const CELL_NAME: &'static str = "block"; + const CF_NAME: &'static str = CF_BLOCK_NAME; + + fn key_constructor(params: Self::KeyParams) -> DbResult> { + // ToDo: Replace with increasing ordering serialization + borsh::to_vec(¶ms).map_err(|err| { + DbError::borsh_cast_message( + err, + Some(format!("Failed to serialize {:?}", Self::CELL_NAME)), + ) + }) + } + + fn value_constructor(&self) -> DbResult> { + borsh::to_vec(&self).map_err(|err| { + DbError::borsh_cast_message(err, Some("Failed to serialize block".to_owned())) + }) + } +} + +impl SimpleReadableCell for BlockCell {} diff --git a/storage/src/storable_cell/mod.rs b/storage/src/storable_cell/mod.rs index 06912829..8aa8b779 100644 --- a/storage/src/storable_cell/mod.rs +++ b/storage/src/storable_cell/mod.rs @@ -7,22 +7,25 @@ use crate::{DbResult, error::DbError}; pub mod cells; -pub trait SimpleStorableCell: BorshSerialize + BorshDeserialize { +pub trait SimpleStorableCell { const CF_NAME: &'static str; const CELL_NAME: &'static str; + type KeyParams; - fn key_constructor() -> DbResult>; + fn key_constructor(params: Self::KeyParams) -> DbResult>; fn value_constructor(&self) -> DbResult>; fn column_ref(db: &DBWithThreadMode) -> Arc> { db.cf_handle(Self::CF_NAME) .unwrap_or_else(|| panic!("Column family {:?} must be present", Self::CF_NAME)) } +} - fn get(db: &DBWithThreadMode) -> DbResult { +pub trait SimpleReadableCell: SimpleStorableCell + BorshDeserialize { + fn get(db: &DBWithThreadMode, params: Self::KeyParams) -> DbResult { let cf_ref = Self::column_ref(db); let res = db - .get_cf(&cf_ref, Self::key_constructor()?) + .get_cf(&cf_ref, Self::key_constructor(params)?) .map_err(|rerr| { DbError::rocksdb_cast_message( rerr, @@ -45,10 +48,13 @@ pub trait SimpleStorableCell: BorshSerialize + BorshDeserialize { } } - fn get_opt(db: &DBWithThreadMode) -> DbResult> { + fn get_opt( + db: &DBWithThreadMode, + params: Self::KeyParams, + ) -> DbResult> { let cf_ref = Self::column_ref(db); let res = db - .get_cf(&cf_ref, Self::key_constructor()?) + .get_cf(&cf_ref, Self::key_constructor(params)?) .map_err(|rerr| { DbError::rocksdb_cast_message( rerr, @@ -66,26 +72,37 @@ pub trait SimpleStorableCell: BorshSerialize + BorshDeserialize { }) .transpose() } +} - fn put(&self, db: &DBWithThreadMode) -> DbResult<()> { +pub trait SimpleWritableCell: SimpleStorableCell + BorshSerialize { + fn put(&self, db: &DBWithThreadMode, params: Self::KeyParams) -> DbResult<()> { let cf_ref = Self::column_ref(db); - db.put_cf(&cf_ref, Self::key_constructor()?, self.value_constructor()?) - .map_err(|rerr| { - DbError::rocksdb_cast_message( - rerr, - Some(format!("Failed to write {:?}", Self::CELL_NAME)), - ) - })?; + db.put_cf( + &cf_ref, + Self::key_constructor(params)?, + self.value_constructor()?, + ) + .map_err(|rerr| { + DbError::rocksdb_cast_message( + rerr, + Some(format!("Failed to write {:?}", Self::CELL_NAME)), + ) + })?; Ok(()) } fn put_batch( &self, db: &DBWithThreadMode, + params: Self::KeyParams, write_batch: &mut WriteBatch, ) -> DbResult<()> { let cf_ref = Self::column_ref(db); - write_batch.put_cf(&cf_ref, Self::key_constructor()?, self.value_constructor()?); + write_batch.put_cf( + &cf_ref, + Self::key_constructor(params)?, + self.value_constructor()?, + ); Ok(()) } }