mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-03-26 04:03:06 +00:00
320 lines
10 KiB
Rust
320 lines
10 KiB
Rust
use super::*;
|
|
|
|
impl RocksDBIO {
|
|
// Accounts meta
|
|
|
|
pub(crate) fn update_acc_meta_batch(
|
|
&self,
|
|
acc_id: [u8; 32],
|
|
num_tx: u64,
|
|
write_batch: &mut WriteBatch,
|
|
) -> DbResult<()> {
|
|
let cf_ameta = self.account_meta_column();
|
|
|
|
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_string()))
|
|
})?,
|
|
borsh::to_vec(&num_tx).map_err(|err| {
|
|
DbError::borsh_cast_message(
|
|
err,
|
|
Some("Failed to serialize acc metadata".to_string()),
|
|
)
|
|
})?,
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
// Account
|
|
|
|
pub fn put_account_transactions(
|
|
&self,
|
|
acc_id: [u8; 32],
|
|
tx_hashes: Vec<[u8; 32]>,
|
|
) -> DbResult<()> {
|
|
let acc_num_tx = self.get_acc_meta_num_tx(acc_id)?.unwrap_or(0);
|
|
let cf_att = self.account_id_to_tx_hash_column();
|
|
let mut write_batch = WriteBatch::new();
|
|
|
|
for (tx_id, tx_hash) in tx_hashes.iter().enumerate() {
|
|
let put_id = acc_num_tx + tx_id as u64;
|
|
|
|
let mut prefix = borsh::to_vec(&acc_id).map_err(|berr| {
|
|
DbError::borsh_cast_message(
|
|
berr,
|
|
Some("Failed to serialize account id".to_string()),
|
|
)
|
|
})?;
|
|
let suffix = borsh::to_vec(&put_id).map_err(|berr| {
|
|
DbError::borsh_cast_message(berr, Some("Failed to serialize tx id".to_string()))
|
|
})?;
|
|
|
|
prefix.extend_from_slice(&suffix);
|
|
|
|
write_batch.put_cf(
|
|
&cf_att,
|
|
prefix,
|
|
borsh::to_vec(tx_hash).map_err(|berr| {
|
|
DbError::borsh_cast_message(
|
|
berr,
|
|
Some("Failed to serialize tx hash".to_string()),
|
|
)
|
|
})?,
|
|
);
|
|
}
|
|
|
|
self.update_acc_meta_batch(
|
|
acc_id,
|
|
acc_num_tx + (tx_hashes.len() as u64),
|
|
&mut write_batch,
|
|
)?;
|
|
|
|
self.db.write(write_batch).map_err(|rerr| {
|
|
DbError::rocksdb_cast_message(rerr, Some("Failed to write batch".to_string()))
|
|
})
|
|
}
|
|
|
|
pub fn put_account_transactions_dependant(
|
|
&self,
|
|
acc_id: [u8; 32],
|
|
tx_hashes: Vec<[u8; 32]>,
|
|
write_batch: &mut WriteBatch,
|
|
) -> DbResult<()> {
|
|
let acc_num_tx = self.get_acc_meta_num_tx(acc_id)?.unwrap_or(0);
|
|
let cf_att = self.account_id_to_tx_hash_column();
|
|
|
|
for (tx_id, tx_hash) in tx_hashes.iter().enumerate() {
|
|
let put_id = acc_num_tx + tx_id as u64;
|
|
|
|
let mut prefix = borsh::to_vec(&acc_id).map_err(|berr| {
|
|
DbError::borsh_cast_message(
|
|
berr,
|
|
Some("Failed to serialize account id".to_string()),
|
|
)
|
|
})?;
|
|
let suffix = borsh::to_vec(&put_id).map_err(|berr| {
|
|
DbError::borsh_cast_message(berr, Some("Failed to serialize tx id".to_string()))
|
|
})?;
|
|
|
|
prefix.extend_from_slice(&suffix);
|
|
|
|
write_batch.put_cf(
|
|
&cf_att,
|
|
prefix,
|
|
borsh::to_vec(tx_hash).map_err(|berr| {
|
|
DbError::borsh_cast_message(
|
|
berr,
|
|
Some("Failed to serialize tx hash".to_string()),
|
|
)
|
|
})?,
|
|
);
|
|
}
|
|
|
|
self.update_acc_meta_batch(acc_id, acc_num_tx + (tx_hashes.len() as u64), write_batch)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
// Meta
|
|
|
|
pub fn put_meta_first_block_in_db_batch(&self, block: Block) -> DbResult<()> {
|
|
let cf_meta = self.meta_column();
|
|
self.db
|
|
.put_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_string()),
|
|
)
|
|
})?,
|
|
borsh::to_vec(&block.header.block_id).map_err(|err| {
|
|
DbError::borsh_cast_message(
|
|
err,
|
|
Some("Failed to serialize first block id".to_string()),
|
|
)
|
|
})?,
|
|
)
|
|
.map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?;
|
|
|
|
self.put_block_batch(block, [0; 32])?;
|
|
Ok(())
|
|
}
|
|
|
|
pub fn put_meta_last_block_in_db_batch(
|
|
&self,
|
|
block_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_BLOCK_IN_DB_KEY).map_err(|err| {
|
|
DbError::borsh_cast_message(
|
|
err,
|
|
Some("Failed to serialize DB_META_LAST_BLOCK_IN_DB_KEY".to_string()),
|
|
)
|
|
})?,
|
|
borsh::to_vec(&block_id).map_err(|err| {
|
|
DbError::borsh_cast_message(
|
|
err,
|
|
Some("Failed to serialize last block id".to_string()),
|
|
)
|
|
})?,
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
pub fn put_meta_last_observed_l1_lib_header_in_db_batch(
|
|
&self,
|
|
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_string(),
|
|
),
|
|
)
|
|
})?,
|
|
borsh::to_vec(&l1_lib_header).map_err(|err| {
|
|
DbError::borsh_cast_message(
|
|
err,
|
|
Some("Failed to serialize last l1 block header".to_string()),
|
|
)
|
|
})?,
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
pub fn put_meta_last_breakpoint_id_batch(
|
|
&self,
|
|
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_string()),
|
|
)
|
|
})?,
|
|
borsh::to_vec(&br_id).map_err(|err| {
|
|
DbError::borsh_cast_message(
|
|
err,
|
|
Some("Failed to serialize last block id".to_string()),
|
|
)
|
|
})?,
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
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_string()),
|
|
)
|
|
})?,
|
|
[1u8; 1],
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
// Block
|
|
|
|
pub fn put_block_batch(&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();
|
|
|
|
write_batch.put_cf(
|
|
&cf_block,
|
|
borsh::to_vec(&block.header.block_id).map_err(|err| {
|
|
DbError::borsh_cast_message(err, Some("Failed to serialize block id".to_string()))
|
|
})?,
|
|
borsh::to_vec(&block).map_err(|err| {
|
|
DbError::borsh_cast_message(err, Some("Failed to serialize block data".to_string()))
|
|
})?,
|
|
);
|
|
|
|
if block.header.block_id > last_curr_block {
|
|
self.put_meta_last_block_in_db_batch(block.header.block_id, &mut write_batch)?;
|
|
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_string()))
|
|
})?,
|
|
borsh::to_vec(&block.header.block_id).map_err(|err| {
|
|
DbError::borsh_cast_message(err, Some("Failed to serialize block id".to_string()))
|
|
})?,
|
|
);
|
|
|
|
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_string()),
|
|
)
|
|
})?,
|
|
borsh::to_vec(&block.header.block_id).map_err(|err| {
|
|
DbError::borsh_cast_message(
|
|
err,
|
|
Some("Failed to serialize block id".to_string()),
|
|
)
|
|
})?,
|
|
);
|
|
|
|
let acc_ids = tx
|
|
.affected_public_account_ids()
|
|
.into_iter()
|
|
.map(|account_id| account_id.into_value())
|
|
.collect::<Vec<_>>();
|
|
|
|
for acc_id in acc_ids {
|
|
acc_to_tx_map
|
|
.entry(acc_id)
|
|
.and_modify(|tx_hashes| tx_hashes.push(tx_hash.into()))
|
|
.or_insert(vec![tx_hash.into()]);
|
|
}
|
|
}
|
|
|
|
for (acc_id, tx_hashes) in acc_to_tx_map {
|
|
self.put_account_transactions_dependant(acc_id, tx_hashes, &mut write_batch)?;
|
|
}
|
|
|
|
self.db.write(write_batch).map_err(|rerr| {
|
|
DbError::rocksdb_cast_message(rerr, Some("Failed to write batch".to_string()))
|
|
})?;
|
|
|
|
if block.header.block_id.is_multiple_of(BREAKPOINT_INTERVAL) {
|
|
self.put_next_breakpoint()?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|