feat: various cells

This commit is contained in:
Pravdyvy 2026-03-26 13:10:31 +02:00
parent 927f6de9bc
commit 392f9cf179
10 changed files with 767 additions and 627 deletions

View File

@ -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<T: SimpleStorableCell>(&self) -> DbResult<T> {
T::get(&self.db)
fn get<T: SimpleReadableCell>(&self, params: T::KeyParams) -> DbResult<T> {
T::get(&self.db, params)
}
#[expect(unused, reason = "Unused")]
fn get_opt<T: SimpleStorableCell>(&self) -> DbResult<Option<T>> {
T::get_opt(&self.db)
fn get_opt<T: SimpleReadableCell>(&self, params: T::KeyParams) -> DbResult<Option<T>> {
T::get_opt(&self.db, params)
}
fn put<T: SimpleStorableCell>(&self, cell: &T) -> DbResult<()> {
cell.put(&self.db)
fn put<T: SimpleWritableCell>(&self, cell: &T, params: T::KeyParams) -> DbResult<()> {
cell.put(&self.db, params)
}
fn put_batch<T: SimpleStorableCell>(
fn put_batch<T: SimpleWritableCell>(
&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

View File

@ -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<u64> {
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::<u64>(&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::<FirstBlockCell>(()).map(|cell| cell.0)
}
pub fn get_meta_last_block_in_db(&self) -> DbResult<u64> {
self.get::<LastBlockCell>().map(|cell| cell.0)
self.get::<LastBlockCell>(()).map(|cell| cell.0)
}
pub fn get_meta_last_observed_l1_lib_header_in_db(&self) -> DbResult<Option<[u8; 32]>> {
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::<LastObservedL1LibHeaderCell>(())
.map(|opt| opt.map(|val| val.0))
}
pub fn get_meta_is_first_block_set(&self) -> DbResult<bool> {
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::<FirstBlockSetCell>(())?.is_some())
}
pub fn get_meta_last_breakpoint_id(&self) -> DbResult<u64> {
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::<u64>(&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::<LastBreakpointIdCell>(()).map(|cell| cell.0)
}
// Block
pub fn get_block(&self, block_id: u64) -> DbResult<Option<Block>> {
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::<Block>(&data).map_err(|serr| {
DbError::borsh_cast_message(
serr,
Some("Failed to deserialize block data".to_owned()),
)
})?))
} else {
Ok(None)
}
self.get_opt::<BlockCell>(block_id)
.map(|opt| opt.map(|val| val.0))
}
// State
pub fn get_breakpoint(&self, br_id: u64) -> DbResult<V03State> {
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::<V03State>(&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::<BreakpointCellOwned>(br_id).map(|cell| cell.0)
}
// Mappings
pub fn get_block_id_by_hash(&self, hash: [u8; 32]) -> DbResult<Option<u64>> {
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::<u64>(&data).map_err(|serr| {
DbError::borsh_cast_message(serr, Some("Failed to deserialize block id".to_owned()))
})?))
} else {
Ok(None)
}
self.get_opt::<BlockHashToBlockIdMapCell>(hash)
.map(|opt| opt.map(|cell| cell.0))
}
pub fn get_block_id_by_tx_hash(&self, tx_hash: [u8; 32]) -> DbResult<Option<u64>> {
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::<u64>(&data).map_err(|serr| {
DbError::borsh_cast_message(serr, Some("Failed to deserialize block id".to_owned()))
})?))
} else {
Ok(None)
}
self.get_opt::<TxHashToBlockIdMapCell>(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<Option<u64>> {
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::<u64>(&data).map_err(|serr| {
DbError::borsh_cast_message(serr, Some("Failed to deserialize num tx".to_owned()))
})
})
.transpose()
self.get_opt::<AccNumTxCell>(acc_id)
.map(|opt| opt.map(|cell| cell.0))
}
}

View File

@ -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<BoundColumnFamily<'_>> = 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()

View File

@ -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<()> {

View File

@ -5,8 +5,6 @@ pub mod indexer;
pub mod sequencer;
pub mod storable_cell;
pub type DbResult<T> = Result<T, DbError>;
// 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<T> = Result<T, DbError>;

View File

@ -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<T> = Result<T, DbError>;
@ -80,108 +87,65 @@ impl RocksDBIO {
.map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))
}
// Columns
pub fn meta_column(&self) -> Arc<BoundColumnFamily<'_>> {
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<BoundColumnFamily<'_>> {
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<BoundColumnFamily<'_>> {
self.db.cf_handle(CF_NSSA_STATE_NAME).unwrap()
self.db
.cf_handle(CF_NSSA_STATE_NAME)
.expect("State should exist")
}
// Generics
fn get<T: SimpleStorableCell>(&self) -> DbResult<T> {
T::get(&self.db)
fn get<T: SimpleReadableCell>(&self, params: T::KeyParams) -> DbResult<T> {
T::get(&self.db, params)
}
#[expect(unused, reason = "Unused")]
fn get_opt<T: SimpleStorableCell>(&self) -> DbResult<Option<T>> {
T::get_opt(&self.db)
fn get_opt<T: SimpleReadableCell>(&self, params: T::KeyParams) -> DbResult<Option<T>> {
T::get_opt(&self.db, params)
}
fn put<T: SimpleStorableCell>(&self, cell: &T) -> DbResult<()> {
cell.put(&self.db)
fn put<T: SimpleWritableCell>(&self, cell: &T, params: T::KeyParams) -> DbResult<()> {
cell.put(&self.db, params)
}
fn put_batch<T: SimpleStorableCell>(
fn put_batch<T: SimpleWritableCell>(
&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<u64> {
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::<u64>(&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<u64> {
self.get::<FirstBlockCell>(()).map(|cell| cell.0)
}
pub fn get_meta_last_block_in_db(&self) -> DbResult<u64> {
self.get::<LastBlockCell>().map(|cell| cell.0)
self.get::<LastBlockCell>(()).map(|cell| cell.0)
}
pub fn get_meta_is_first_block_set(&self) -> DbResult<bool> {
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::<FirstBlockSetCell>(())?.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<u64>) -> 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<BlockMeta> {
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::<BlockMeta>(&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::<LatestBlockMetaCellOwned>(()).map(|val| val.0)
}
pub fn put_block(
@ -380,59 +254,12 @@ impl RocksDBIO {
}
pub fn get_block(&self, block_id: u64) -> DbResult<Option<Block>> {
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::<Block>(&data).map_err(|serr| {
DbError::borsh_cast_message(
serr,
Some("Failed to deserialize block data".to_owned()),
)
})?))
} else {
Ok(None)
}
self.get_opt::<BlockCell>(block_id)
.map(|opt| opt.map(|val| val.0))
}
pub fn get_nssa_state(&self) -> DbResult<V03State> {
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::<V03State>(&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::<NSSAStateCellOwned>(()).map(|val| val.0)
}
pub fn delete_block(&self, block_id: u64) -> DbResult<()> {

View File

@ -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<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
<[u8; 32]>::serialize(&self.0, writer)
}
}
impl BorshDeserialize for LastObservedL1LibHeaderCell {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
<[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<Vec<u8>> {
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<Vec<u8>> {
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<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
u64::serialize(&self.0, writer)
}
}
impl BorshDeserialize for LastBreakpointIdCell {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
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<Vec<u8>> {
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<Vec<u8>> {
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<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
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<Vec<u8>> {
borsh::to_vec(&params).map_err(|err| {
DbError::borsh_cast_message(
err,
Some(format!("Failed to serialize {:?}", Self::CELL_NAME)),
)
})
}
fn value_constructor(&self) -> DbResult<Vec<u8>> {
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<W: std::io::Write>(&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<Vec<u8>> {
borsh::to_vec(&params).map_err(|err| {
DbError::borsh_cast_message(
err,
Some(format!("Failed to serialize {:?}", Self::CELL_NAME)),
)
})
}
fn value_constructor(&self) -> DbResult<Vec<u8>> {
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<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
u64::serialize(&self.0, writer)
}
}
impl BorshDeserialize for BlockHashToBlockIdMapCell {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
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<Vec<u8>> {
borsh::to_vec(&params).map_err(|err| {
DbError::borsh_cast_message(
err,
Some(format!("Failed to serialize {:?}", Self::CELL_NAME)),
)
})
}
fn value_constructor(&self) -> DbResult<Vec<u8>> {
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<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
u64::serialize(&self.0, writer)
}
}
impl BorshDeserialize for TxHashToBlockIdMapCell {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
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<Vec<u8>> {
borsh::to_vec(&params).map_err(|err| {
DbError::borsh_cast_message(
err,
Some(format!("Failed to serialize {:?}", Self::CELL_NAME)),
)
})
}
fn value_constructor(&self) -> DbResult<Vec<u8>> {
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<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
u64::serialize(&self.0, writer)
}
}
impl BorshDeserialize for AccNumTxCell {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
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<Vec<u8>> {
borsh::to_vec(&params).map_err(|err| {
DbError::borsh_cast_message(
err,
Some(format!("Failed to serialize {:?}", Self::CELL_NAME)),
)
})
}
fn value_constructor(&self) -> DbResult<Vec<u8>> {
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 {}

View File

@ -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<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
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<Vec<u8>> {
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<Vec<u8>> {
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<W: std::io::Write>(&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<Vec<u8>> {
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<Vec<u8>> {
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<u64>);
impl BorshSerialize for LastFinalizedBlockIdCell {
fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
Option::<u64>::serialize(&self.0, writer)
}
}
impl BorshDeserialize for LastFinalizedBlockIdCell {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
Option::<u64>::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<Vec<u8>> {
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<Vec<u8>> {
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<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
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<Vec<u8>> {
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<Vec<u8>> {
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<W: std::io::Write>(&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<Vec<u8>> {
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<Vec<u8>> {
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<'_> {}

View File

@ -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<Vec<u8>> {
fn key_constructor(_params: Self::KeyParams) -> DbResult<Vec<u8>> {
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<Vec<u8>> {
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<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
bool::serialize(&self.0, writer)
}
}
impl BorshDeserialize for FirstBlockSetCell {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
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<Vec<u8>> {
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<Vec<u8>> {
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<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
u64::serialize(&self.0, writer)
}
}
impl BorshDeserialize for FirstBlockCell {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
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<Vec<u8>> {
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<Vec<u8>> {
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<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
Block::serialize(&self.0, writer)
}
}
impl BorshDeserialize for BlockCell {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
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<Vec<u8>> {
// ToDo: Replace with increasing ordering serialization
borsh::to_vec(&params).map_err(|err| {
DbError::borsh_cast_message(
err,
Some(format!("Failed to serialize {:?}", Self::CELL_NAME)),
)
})
}
fn value_constructor(&self) -> DbResult<Vec<u8>> {
borsh::to_vec(&self).map_err(|err| {
DbError::borsh_cast_message(err, Some("Failed to serialize block".to_owned()))
})
}
}
impl SimpleReadableCell for BlockCell {}

View File

@ -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<Vec<u8>>;
fn key_constructor(params: Self::KeyParams) -> DbResult<Vec<u8>>;
fn value_constructor(&self) -> DbResult<Vec<u8>>;
fn column_ref(db: &DBWithThreadMode<MultiThreaded>) -> Arc<BoundColumnFamily<'_>> {
db.cf_handle(Self::CF_NAME)
.unwrap_or_else(|| panic!("Column family {:?} must be present", Self::CF_NAME))
}
}
fn get(db: &DBWithThreadMode<MultiThreaded>) -> DbResult<Self> {
pub trait SimpleReadableCell: SimpleStorableCell + BorshDeserialize {
fn get(db: &DBWithThreadMode<MultiThreaded>, params: Self::KeyParams) -> DbResult<Self> {
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<MultiThreaded>) -> DbResult<Option<Self>> {
fn get_opt(
db: &DBWithThreadMode<MultiThreaded>,
params: Self::KeyParams,
) -> DbResult<Option<Self>> {
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<MultiThreaded>) -> DbResult<()> {
pub trait SimpleWritableCell: SimpleStorableCell + BorshSerialize {
fn put(&self, db: &DBWithThreadMode<MultiThreaded>, 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<MultiThreaded>,
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(())
}
}