diff --git a/lib/dubp/common-doc/src/blockstamp.rs b/lib/dubp/common-doc/src/blockstamp.rs index 3f87b514053e38da765ceedb0f359076cfb860c0..c9648f5de154c1800887d4fed3027ce53f2b245d 100644 --- a/lib/dubp/common-doc/src/blockstamp.rs +++ b/lib/dubp/common-doc/src/blockstamp.rs @@ -77,10 +77,12 @@ impl Blockstamp { impl Into<Vec<u8>> for Blockstamp { fn into(self) -> Vec<u8> { - let mut bytes = Vec::with_capacity(Self::SIZE_IN_BYTES); - bytes.append(&mut self.id.0.to_be_bytes().to_vec()); - bytes.append(&mut (self.hash.0).0.to_vec()); - bytes + let mut bytes = [0u8; Self::SIZE_IN_BYTES]; + + bytes[..4].copy_from_slice(&self.id.0.to_be_bytes()[..4]); + bytes[4..Self::SIZE_IN_BYTES].copy_from_slice(&(self.hash.0).0[..]); + + bytes.to_vec() } } diff --git a/lib/dubp/indexes/src/sindex.rs b/lib/dubp/indexes/src/sindex.rs index 58568bdb69211f7c70478e9de310e06ae39ba39b..b10ea40960d34ae64762aec2701e6ef00d6564ff 100644 --- a/lib/dubp/indexes/src/sindex.rs +++ b/lib/dubp/indexes/src/sindex.rs @@ -31,10 +31,13 @@ pub struct UniqueIdUTXOv10(pub Hash, pub OutputIndex); impl Into<Vec<u8>> for UniqueIdUTXOv10 { fn into(self) -> Vec<u8> { - let mut buffer = Vec::with_capacity(UTXO_ID_SIZE); - buffer.append(&mut (self.0).0.to_vec()); - buffer.append(&mut (self.1).0.to_be_bytes().to_vec()); - buffer + let mut bytes = [0u8; UTXO_ID_SIZE]; + + bytes[..Hash::SIZE_IN_BYTES].copy_from_slice(&(self.0).0[..]); + bytes[Hash::SIZE_IN_BYTES..UTXO_ID_SIZE] + .copy_from_slice(&((self.1).0 as u32).to_be_bytes()[..]); + + bytes.to_vec() } } diff --git a/lib/modules-lib/bc-db-reader/src/constants.rs b/lib/modules-lib/bc-db-reader/src/constants.rs index 0ca5f166d8ebb25c0e0c07b6a624499648fccdbb..5eabbb72cb918650b711c70eb8f6d52f6ffd0767 100644 --- a/lib/modules-lib/bc-db-reader/src/constants.rs +++ b/lib/modules-lib/bc-db-reader/src/constants.rs @@ -40,6 +40,12 @@ pub static WOT_ID_INDEX: &str = "wii"; /// Identities (WotId, DbIdentity) pub static IDENTITIES: &str = "idty"; +/// Memberships sorted by created block (BlockNumber, Vec<WotId>) +pub static MBS_BY_CREATED_BLOCK: &str = "mb"; + +/// Certifications sorted by created block (BlockNumber, Vec<(WotId, WotId)) +pub static CERTS_BY_CREATED_BLOCK: &str = "cert"; + /// Unused universal dividends pub static DIVIDENDS: &str = "du"; diff --git a/lib/modules-lib/bc-db-reader/src/indexes/certs.rs b/lib/modules-lib/bc-db-reader/src/indexes/certs.rs index 3dc4959641734315e9738bce532da0d1f2c90d87..db2861db8caabcf02695887f1489910181abc781 100644 --- a/lib/modules-lib/bc-db-reader/src/indexes/certs.rs +++ b/lib/modules-lib/bc-db-reader/src/indexes/certs.rs @@ -15,26 +15,46 @@ //! Certificatiosn stored index. -use crate::CertsExpirV10Datas; +use crate::*; use dubp_common_doc::BlockNumber; -use durs_dbs_tools::{BinFreeStructDb, DbError}; +use durs_dbs_tools::DbError; use durs_wot::WotId; use std::collections::HashMap; /// Find certifications that emitted in indicated blocks expiring -pub fn find_expire_certs( - certs_db: &BinFreeStructDb<CertsExpirV10Datas>, +pub fn find_expire_certs<DB: DbReadable, R: DbReader>( + db: &DB, + r: &R, blocks_expiring: Vec<BlockNumber>, ) -> Result<HashMap<(WotId, WotId), BlockNumber>, DbError> { - Ok(certs_db.read(|db| { - let mut all_expire_certs = HashMap::new(); - for expire_block_id in blocks_expiring { - if let Some(expire_certs) = db.get(&expire_block_id) { - for (source, target) in expire_certs { - all_expire_certs.insert((*source, *target), expire_block_id); + let mut all_expire_certs = HashMap::new(); + for expire_block_id in blocks_expiring { + for entry_result in db + .get_multi_int_store(CERTS_BY_CREATED_BLOCK) + .get(r, expire_block_id.0)? + { + if let Some(value) = entry_result?.1 { + if let DbValue::U64(cert) = value { + let (source, target) = cert_from_u64(cert); + all_expire_certs.insert((source, target), expire_block_id); + } else { + return Err(DbError::DBCorrupted); } } } - all_expire_certs - })?) + } + Ok(all_expire_certs) +} + +fn cert_from_u64(cert: u64) -> (WotId, WotId) { + let mut source = [0u8; 4]; + let mut target = [0u8; 4]; + let cert_bytes = cert.to_be_bytes(); + source.copy_from_slice(&cert_bytes[..4]); + target.copy_from_slice(&cert_bytes[4..]); + + ( + WotId(u32::from_be_bytes(source) as usize), + WotId(u32::from_be_bytes(target) as usize), + ) } diff --git a/lib/modules-lib/bc-db-reader/src/lib.rs b/lib/modules-lib/bc-db-reader/src/lib.rs index 83b2ea514796837cb2ab1634010b2ff0ccc8d067..9364d67a32dcf7512dbe1301f0dc4bcfb90ab18f 100644 --- a/lib/modules-lib/bc-db-reader/src/lib.rs +++ b/lib/modules-lib/bc-db-reader/src/lib.rs @@ -55,6 +55,8 @@ pub fn bc_db_schema() -> KvFileDbSchema { FORK_BLOCKS.to_owned() => KvFileDbStoreType::Single, ORPHAN_BLOCKSTAMP.to_owned() => KvFileDbStoreType::Single, IDENTITIES.to_owned() => KvFileDbStoreType::SingleIntKey, + MBS_BY_CREATED_BLOCK.to_owned() => KvFileDbStoreType::MultiIntKey, + CERTS_BY_CREATED_BLOCK.to_owned() => KvFileDbStoreType::MultiIntKey, WOT_ID_INDEX.to_owned() => KvFileDbStoreType::Single, DIVIDENDS.to_owned() => KvFileDbStoreType::Multi, UTXOS.to_owned() => KvFileDbStoreType::Single, @@ -69,16 +71,6 @@ pub fn open_db_ro(path: &Path) -> Result<BcDbRo, DbError> { BcDbRo::open_db_ro(path, &bc_db_schema()) } -/////////////////////////// -// Migration in progress // -/////////////////////////// - -/// Certifications sorted by created block -pub type CertsExpirV10Datas = fnv::FnvHashMap< - dubp_common_doc::BlockNumber, - std::collections::HashSet<(durs_wot::WotId, durs_wot::WotId)>, ->; - #[cfg(test)] pub mod tests { diff --git a/lib/modules/blockchain/bc-db-writer/src/indexes/certs.rs b/lib/modules/blockchain/bc-db-writer/src/indexes/certs.rs index e1aa5ee797e7ed61bac1ec05fca2b3a5efae2913..fcc9c3ee16732da26e8f0c43b105d0a66a7aac20 100644 --- a/lib/modules/blockchain/bc-db-writer/src/indexes/certs.rs +++ b/lib/modules/blockchain/bc-db-writer/src/indexes/certs.rs @@ -15,13 +15,13 @@ //! Certifications stored indexes: write requests. -use crate::{BinFreeStructDb, Db, DbError, DbWriter}; +use crate::{Db, DbError, DbWriter}; use dubp_common_doc::BlockNumber; use dubp_currency_params::CurrencyParameters; use dubp_user_docs::documents::certification::CompactCertificationDocumentV10; use durs_bc_db_reader::constants::*; use durs_bc_db_reader::indexes::identities::DbIdentity; -use durs_bc_db_reader::{CertsExpirV10Datas, DbReadable, DbValue}; +use durs_bc_db_reader::{DbReadable, DbValue}; use durs_wot::WotId; /// Apply "certification" event in databases @@ -29,7 +29,6 @@ pub fn write_certification( currency_params: &CurrencyParameters, db: &Db, w: &mut DbWriter, - certs_db: &BinFreeStructDb<CertsExpirV10Datas>, source: WotId, target: WotId, created_block_id: BlockNumber, @@ -51,11 +50,11 @@ pub fn write_certification( &DbValue::Blob(&bin_member_datas), )?; // Add cert in certs_db - certs_db.write(|db| { - let mut created_certs = db.get(&created_block_id).cloned().unwrap_or_default(); - created_certs.insert((source, target)); - db.insert(created_block_id, created_certs); - })?; + db.get_multi_int_store(CERTS_BY_CREATED_BLOCK).put( + w.as_mut(), + created_block_id.0, + &DbValue::U64(cert_to_u64(source, target)), + )?; Ok(()) } @@ -63,20 +62,17 @@ pub fn write_certification( pub fn revert_write_cert( db: &Db, w: &mut DbWriter, - certs_db: &BinFreeStructDb<CertsExpirV10Datas>, compact_doc: CompactCertificationDocumentV10, source: WotId, target: WotId, ) -> Result<(), DbError> { // Remove CertsExpirV10Datas entry - certs_db.write(|db| { - let mut certs = db - .get(&compact_doc.block_number) - .cloned() - .unwrap_or_default(); - certs.remove(&(source, target)); - db.insert(compact_doc.block_number, certs); - })?; + db.get_multi_int_store(CERTS_BY_CREATED_BLOCK).delete( + w.as_mut(), + compact_doc.block_number.0, + &DbValue::U64(cert_to_u64(source, target)), + )?; + // Pop last cert_chainable_on let identities_store = db.get_int_store(IDENTITIES); if let Some(v) = identities_store.get(w.as_ref(), source.0 as u32)? { @@ -94,28 +90,62 @@ pub fn revert_write_cert( /// Revert "certification expiry" event in databases pub fn revert_expire_cert( - certs_db: &BinFreeStructDb<CertsExpirV10Datas>, + db: &Db, + w: &mut DbWriter, source: WotId, target: WotId, created_block_id: BlockNumber, ) -> Result<(), DbError> { // Reinsert CertsExpirV10Datas entry - certs_db.write(|db| { - let mut certs = db.get(&created_block_id).cloned().unwrap_or_default(); - certs.insert((source, target)); - db.insert(created_block_id, certs); - })?; + db.get_multi_int_store(CERTS_BY_CREATED_BLOCK).put( + w.as_mut(), + created_block_id.0, + &DbValue::U64(cert_to_u64(source, target)), + )?; Ok(()) } /// Apply "certification expiry" event in databases pub fn expire_certs( - certs_db: &BinFreeStructDb<CertsExpirV10Datas>, + db: &Db, + w: &mut DbWriter, created_block_id: BlockNumber, ) -> Result<(), DbError> { - // Remove CertsExpirV10Datas entries - certs_db.write(|db| { - db.remove(&created_block_id); - })?; + // Remove all certs created at block `created_block_id` + if db + .get_multi_int_store(CERTS_BY_CREATED_BLOCK) + .get_first(w.as_ref(), created_block_id.0)? + .is_some() + { + db.get_multi_int_store(CERTS_BY_CREATED_BLOCK) + .delete_all(w.as_mut(), created_block_id.0)?; + } + Ok(()) } + +fn cert_to_u64(source: WotId, target: WotId) -> u64 { + let source_bytes = (source.0 as u32).to_be_bytes(); + let target_bytes = (target.0 as u32).to_be_bytes(); + let mut cert_u64_bytes = [0u8; 8]; + cert_u64_bytes[..4].copy_from_slice(&source_bytes[..4]); + cert_u64_bytes[4..8].copy_from_slice(&target_bytes[..4]); + /*for i in 0..4 { + cert_u64_bytes[i] = source_bytes[i]; + cert_u64_bytes[i + 4] = target_bytes[i]; + }*/ + u64::from_be_bytes(cert_u64_bytes) +} + +#[cfg(test)] +mod tests { + + use super::*; + + #[test] + fn test_cert_to_u64() { + assert_eq!(1u64, cert_to_u64(WotId(0), WotId(1))); + assert_eq!(2_623u64, cert_to_u64(WotId(0), WotId(2_623))); + assert_eq!((std::u32::MAX as u64) + 1, cert_to_u64(WotId(1), WotId(0))); + } +} diff --git a/lib/modules/blockchain/bc-db-writer/src/indexes/identities.rs b/lib/modules/blockchain/bc-db-writer/src/indexes/identities.rs index a15634c6517efa4197deeba34a3057f01da9b361..ed249e9ed95d69f492bcb289b0c9e7911f460185 100644 --- a/lib/modules/blockchain/bc-db-writer/src/indexes/identities.rs +++ b/lib/modules/blockchain/bc-db-writer/src/indexes/identities.rs @@ -15,7 +15,7 @@ //! Identities stored indexes: write requests. -use crate::{BinFreeStructDb, Db, DbError, DbWriter, MsExpirV10Datas}; +use crate::{Db, DbError, DbWriter}; use dubp_common_doc::traits::Document; use dubp_common_doc::{BlockNumber, Blockstamp}; use dubp_currency_params::CurrencyParameters; @@ -31,23 +31,15 @@ use durs_common_tools::fatal_error; use durs_wot::WotId; /// Remove identity from databases -pub fn revert_create_identity( - db: &Db, - w: &mut DbWriter, - ms_db: &BinFreeStructDb<MsExpirV10Datas>, - pubkey: &PubKey, -) -> Result<(), DbError> { +pub fn revert_create_identity(db: &Db, w: &mut DbWriter, pubkey: &PubKey) -> Result<(), DbError> { let dal_idty = durs_bc_db_reader::indexes::identities::get_identity_by_pubkey(db, pubkey)? .expect("Try to revert unexist idty."); // Remove membership - ms_db.write(|db| { - let mut memberships = db - .get(&dal_idty.ms_created_block_id) - .cloned() - .expect("Try to revert a membership that does not exist !"); - memberships.remove(&dal_idty.wot_id); - db.insert(dal_idty.ms_created_block_id, memberships); - })?; + db.get_multi_int_store(MBS_BY_CREATED_BLOCK).delete( + w.as_mut(), + dal_idty.ms_created_block_id.0, + &DbValue::U64(dal_idty.wot_id.0 as u64), + )?; // Remove identity let pubkey_bytes = dal_idty.idty_doc.issuers()[0].to_bytes_vector(); if let Some(DbValue::U64(wot_id)) = db.get_store(WOT_ID_INDEX).get(w.as_ref(), &pubkey_bytes)? { @@ -83,7 +75,6 @@ pub fn create_identity( currency_params: &CurrencyParameters, db: &Db, w: &mut DbWriter, - ms_db: &BinFreeStructDb<MsExpirV10Datas>, idty_doc: &IdentityDocumentV10, ms_created_block_id: BlockNumber, wot_id: WotId, @@ -114,11 +105,11 @@ pub fn create_identity( db.get_int_store(IDENTITIES) .put(w.as_mut(), wot_id.0 as u32, &DbValue::Blob(&bin_idty))?; // Write membership - ms_db.write(|db| { - let mut memberships = db.get(&ms_created_block_id).cloned().unwrap_or_default(); - memberships.insert(wot_id); - db.insert(ms_created_block_id, memberships); - })?; + db.get_multi_int_store(MBS_BY_CREATED_BLOCK).put( + w.as_mut(), + ms_created_block_id.0, + &DbValue::U64(wot_id.0 as u64), + )?; Ok(()) } @@ -225,7 +216,6 @@ pub fn renewal_identity( currency_params: &CurrencyParameters, db: &Db, w: &mut DbWriter, - ms_db: &BinFreeStructDb<MsExpirV10Datas>, idty_wot_id: WotId, renewal_timestamp: u64, ms_created_block_id: BlockNumber, @@ -280,11 +270,11 @@ pub fn renewal_identity( &DbValue::Blob(&bin_idty), )?; // Update MsExpirV10DB - ms_db.write(|db| { - let mut memberships = db.get(&ms_created_block_id).cloned().unwrap_or_default(); - memberships.insert(idty_wot_id); - db.insert(ms_created_block_id, memberships); - })?; + db.get_multi_int_store(MBS_BY_CREATED_BLOCK).put( + w.as_mut(), + ms_created_block_id.0, + &DbValue::U64(idty_wot_id.0 as u64), + )?; Ok(()) } diff --git a/lib/modules/blockchain/bc-db-writer/src/lib.rs b/lib/modules/blockchain/bc-db-writer/src/lib.rs index 0978d03b83d469f7954a2322b4f0abf50541a35f..83eeeeb3e98f3b9c827bf40b57cbf0d02f6e454a 100644 --- a/lib/modules/blockchain/bc-db-writer/src/lib.rs +++ b/lib/modules/blockchain/bc-db-writer/src/lib.rs @@ -48,9 +48,7 @@ use dubp_indexes::sindex::UniqueIdUTXOv10; use dubp_user_docs::documents::transaction::*; use dup_crypto::hashs::Hash; use dup_crypto::keys::*; -use durs_bc_db_reader::CertsExpirV10Datas; -use durs_wot::data::{rusty::RustyWebOfTrust, WotId}; -use fnv::FnvHashMap; +use durs_wot::data::rusty::RustyWebOfTrust; use std::collections::{HashMap, HashSet}; use std::path::{Path, PathBuf}; @@ -60,14 +58,8 @@ pub type Db = KvFileDbHandler; /// Read-only database handler pub type DbReader = KvFileDbRoHandler; -/// Forks tree meta datas (block number and hash only) -pub type ForksTreeV10Datas = durs_bc_db_reader::blocks::fork_tree::ForkTree; /// Database containing the wot graph (each node of the graph in an u32) pub type WotDB = RustyWebOfTrust; -/// Memberships sorted by created block -pub type MsExpirV10Datas = FnvHashMap<BlockNumber, HashSet<WotId>>; -/// V10 UDs sources -pub type UDsV10Datas = HashMap<PubKey, HashSet<BlockNumber>>; /// Open database #[inline] @@ -80,10 +72,6 @@ pub fn open_db(path: &Path) -> Result<Db, DbError> { pub struct WotsV10DBs { /// Store wot graph pub wot_db: BinFreeStructDb<WotDB>, - /// Store memberships created_block_id (Use only to detect expirations) - pub ms_db: BinFreeStructDb<MsExpirV10Datas>, - /// Store certifications created_block_id (Use only to detect expirations) - pub certs_db: BinFreeStructDb<CertsExpirV10Datas>, } impl WotsV10DBs { @@ -92,10 +80,6 @@ impl WotsV10DBs { WotsV10DBs { wot_db: open_free_struct_db::<RustyWebOfTrust>(db_path, "wot.db") .expect("Fail to open WotDB"), - ms_db: open_free_struct_db::<MsExpirV10Datas>(db_path, "ms.db") - .expect("Fail to open MsExpirV10DB"), - certs_db: open_free_struct_db::<CertsExpirV10Datas>(db_path, "certs.db") - .expect("Fail to open CertsExpirV10DB"), } } /// Save wot databases from their respective files @@ -104,16 +88,6 @@ impl WotsV10DBs { self.wot_db .save() .expect("Fatal error : fail to save WotDB !"); - self.save_dbs_except_graph(); - } - /// Save wot databases from their respective files (except wot graph) - pub fn save_dbs_except_graph(&self) { - self.ms_db - .save() - .expect("Fatal error : fail to save MsExpirV10DB !"); - self.certs_db - .save() - .expect("Fatal error : fail to save CertsExpirV10DB !"); } } diff --git a/lib/modules/blockchain/bc-db-writer/src/writers/requests.rs b/lib/modules/blockchain/bc-db-writer/src/writers/requests.rs index 1f635870dd74ead5dcff9d4a77798ad7a610e893..fcbd528da38d0f7c178674547fda3c1bae5b149d 100644 --- a/lib/modules/blockchain/bc-db-writer/src/writers/requests.rs +++ b/lib/modules/blockchain/bc-db-writer/src/writers/requests.rs @@ -129,7 +129,6 @@ impl WotsDBsWriteQuery { w: &mut DbWriter, _blockstamp: &Blockstamp, currency_params: &CurrencyParameters, - databases: &WotsV10DBs, ) -> Result<(), DbError> { match *self { WotsDBsWriteQuery::CreateIdentity( @@ -143,7 +142,6 @@ impl WotsDBsWriteQuery { currency_params, &db, w, - &databases.ms_db, idty_doc.deref(), *ms_created_block_id, *wot_id, @@ -152,12 +150,7 @@ impl WotsDBsWriteQuery { )?; } WotsDBsWriteQuery::RevertCreateIdentity(ref pubkey) => { - crate::indexes::identities::revert_create_identity( - &db, - w, - &databases.ms_db, - pubkey, - )?; + crate::indexes::identities::revert_create_identity(&db, w, pubkey)?; } WotsDBsWriteQuery::RenewalIdentity( _, @@ -170,7 +163,6 @@ impl WotsDBsWriteQuery { currency_params, &db, w, - &databases.ms_db, *idty_wot_id, *current_bc_time, ms_created_block_id, @@ -188,7 +180,6 @@ impl WotsDBsWriteQuery { currency_params, &db, w, - &databases.ms_db, *idty_wot_id, *current_bc_time, ms_created_block_id, @@ -223,7 +214,6 @@ impl WotsDBsWriteQuery { currency_params, &db, w, - &databases.certs_db, *source, *target, *created_block_id, @@ -233,22 +223,16 @@ impl WotsDBsWriteQuery { } WotsDBsWriteQuery::RevertCert(ref compact_doc, ref source, ref target) => { trace!("WotsDBsWriteQuery::CreateCert..."); - crate::indexes::certs::revert_write_cert( - &db, - w, - &databases.certs_db, - *compact_doc, - *source, - *target, - )?; + crate::indexes::certs::revert_write_cert(&db, w, *compact_doc, *source, *target)?; trace!("WotsDBsWriteQuery::CreateCert...finish"); } WotsDBsWriteQuery::ExpireCerts(ref created_block_id) => { - crate::indexes::certs::expire_certs(&databases.certs_db, *created_block_id)?; + crate::indexes::certs::expire_certs(&db, w, *created_block_id)?; } WotsDBsWriteQuery::RevertExpireCert(ref source, ref target, ref created_block_id) => { crate::indexes::certs::revert_expire_cert( - &databases.certs_db, + &db, + w, *source, *target, *created_block_id, @@ -260,7 +244,7 @@ impl WotsDBsWriteQuery { } #[derive(Debug, Clone)] -/// Contain a pending write request for currency databases +/// Contain a pending write request for currency indexes pub enum CurrencyDBsWriteQuery { /// Write transaction WriteTx(Box<TransactionDocument>), diff --git a/lib/modules/blockchain/blockchain/src/dbex.rs b/lib/modules/blockchain/blockchain/src/dbex.rs index 43d115c866a58eb90ae47e11f10252fa8fc7dc25..1aea3853ab4ab5268baecb18cdb1c875118335ec 100644 --- a/lib/modules/blockchain/blockchain/src/dbex.rs +++ b/lib/modules/blockchain/blockchain/src/dbex.rs @@ -19,7 +19,8 @@ use crate::*; use dubp_block_doc::block::BlockDocumentTrait; use dubp_common_doc::BlockNumber; use dup_crypto::keys::*; -use durs_bc_db_reader::BcDbRo; +use durs_bc_db_reader::constants::*; +use durs_bc_db_reader::{BcDbRo, DbValue}; use durs_wot::data::rusty::RustyWebOfTrust; use durs_wot::data::WebOfTrust; use durs_wot::operations::distance::{DistanceCalculator, WotDistance, WotDistanceParameters}; @@ -295,7 +296,6 @@ pub fn dbex_wot(profile_path: PathBuf, csv: bool, query: &DbExWotQuery) { } else { return; }; - let wot_databases = WotsV10DBs::open(Some(&db_path)); let load_dbs_duration = SystemTime::now() .duration_since(load_db_begin) .expect("duration_since error"); @@ -407,6 +407,7 @@ pub fn dbex_wot(profile_path: PathBuf, csv: bool, query: &DbExWotQuery) { 10_000_000, ) .expect("Fail to get all blocks"); + let current_bc_number = all_blocks.last().expect("empty blockchain").number(); let current_bc_time = all_blocks.last().expect("empty blockchain").common_time(); let blocks_times: HashMap<BlockNumber, u64> = all_blocks .iter() @@ -414,24 +415,28 @@ pub fn dbex_wot(profile_path: PathBuf, csv: bool, query: &DbExWotQuery) { .collect(); // Get expire_dates let min_created_ms_time = current_bc_time - currency_params.ms_validity; - let mut expire_dates: Vec<(WotId, u64)> = wot_databases - .ms_db - .read(|db| { + let mut expire_dates: Vec<(WotId, u64)> = db + .read(|r| { let mut expire_dates = Vec::new(); - for (block_id, nodes_ids) in db { - let created_ms_time = blocks_times[&block_id.0]; + for block_id in 0..current_bc_number.0 { + let created_ms_time = blocks_times[&block_id]; if created_ms_time > min_created_ms_time { - for node_id in nodes_ids { - expire_dates.push(( - *node_id, - created_ms_time + currency_params.ms_validity, - )); + for entry_result in db + .get_multi_int_store(MBS_BY_CREATED_BLOCK) + .get(r, block_id)? + { + if let Some(DbValue::U64(wot_id)) = entry_result?.1 { + expire_dates.push(( + WotId(wot_id as usize), + created_ms_time + currency_params.ms_validity, + )); + } } } } - expire_dates + Ok(expire_dates) }) - .expect("Fail to read ms db"); + .expect("Fail to read db"); if *reverse { expire_dates.sort_unstable_by(|(_, d1), (_, d2)| d1.cmp(&d2)); } else { diff --git a/lib/modules/blockchain/blockchain/src/dubp/check/mod.rs b/lib/modules/blockchain/blockchain/src/dubp/check/mod.rs index db03eb950e0e881bf3832660b158de87d550b14b..caa7422b049a62594e91d3bdc169ad81da4f173d 100644 --- a/lib/modules/blockchain/blockchain/src/dubp/check/mod.rs +++ b/lib/modules/blockchain/blockchain/src/dubp/check/mod.rs @@ -22,7 +22,7 @@ use dubp_block_doc::block::{BlockDocument, BlockDocumentTrait}; use dubp_common_doc::traits::Document; use dubp_common_doc::BlockNumber; use dup_crypto::keys::PubKey; -use durs_bc_db_reader::CertsExpirV10Datas; +use durs_bc_db_reader::DbReader; use durs_bc_db_writer::*; use durs_wot::*; use std::collections::HashMap; @@ -33,15 +33,16 @@ pub enum InvalidBlockError { VersionDecrease, } -pub fn verify_block_validity<DB, W>( +pub fn verify_block_validity<DB, R, W>( block: &BlockDocument, db: &DB, - _certs_db: &BinFreeStructDb<CertsExpirV10Datas>, + _r: &R, _wot_index: &HashMap<PubKey, WotId>, _wot_db: &BinFreeStructDb<W>, ) -> Result<(), BlockError> where DB: DbReadable, + R: DbReader, W: WebOfTrust, { // Rules that do not concern genesis block diff --git a/lib/modules/blockchain/blockchain/src/dubp/mod.rs b/lib/modules/blockchain/blockchain/src/dubp/mod.rs index 14060ec9b6e2cfcfa28e06ab1d7999eebd6a3166..4bd230556c0d61ea222fb097a01114f0e34434f1 100644 --- a/lib/modules/blockchain/blockchain/src/dubp/mod.rs +++ b/lib/modules/blockchain/blockchain/src/dubp/mod.rs @@ -91,16 +91,14 @@ pub fn check_and_apply_block( ); // Detect expire_certs let blocks_expiring = Vec::with_capacity(0); - let expire_certs = durs_bc_db_reader::indexes::certs::find_expire_certs( - &bc.wot_databases.certs_db, - blocks_expiring, - )?; + let expire_certs = + durs_bc_db_reader::indexes::certs::find_expire_certs(db, w.as_ref(), blocks_expiring)?; // Verify block validity (check all protocol rule, very long !) verify_block_validity( &block_doc, db, - &bc.wot_databases.certs_db, + w.as_ref(), &bc.wot_index, &bc.wot_databases.wot_db, )?; diff --git a/lib/modules/blockchain/blockchain/src/dunp/receiver.rs b/lib/modules/blockchain/blockchain/src/dunp/receiver.rs index 5990a53692c1a0c240280f42037477198419309e..f3d640fc1c45d7d789441940b69c9a4671d44cba 100644 --- a/lib/modules/blockchain/blockchain/src/dunp/receiver.rs +++ b/lib/modules/blockchain/blockchain/src/dunp/receiver.rs @@ -68,13 +68,7 @@ pub fn receive_blocks(bc: &mut BlockchainModule, blocks: Vec<BlockDocument>) { )?; for query in &wot_dbs_queries { query - .apply( - &db, - &mut w, - &blockstamp, - &unwrap!(bc.currency_params), - &bc.wot_databases, - ) + .apply(&db, &mut w, &blockstamp, &unwrap!(bc.currency_params)) .expect("Fatal error : Fail to apply WotsDBsWriteRequest !"); } exec_currency_queries(&db, &mut w, blockstamp.id, tx_dbs_queries)?; diff --git a/lib/modules/blockchain/blockchain/src/fork/rollback.rs b/lib/modules/blockchain/blockchain/src/fork/rollback.rs index d9129e56c2370eb245f2ed42998b2664aba209c9..6df5e61d044b3409e8012529ca7d207211746d79 100644 --- a/lib/modules/blockchain/blockchain/src/fork/rollback.rs +++ b/lib/modules/blockchain/blockchain/src/fork/rollback.rs @@ -67,16 +67,10 @@ pub fn apply_rollback(bc: &mut BlockchainModule, new_bc_branch: Vec<Blockstamp>) unwrap!(bc.currency_params).fork_window_size, None, ) - .expect("Fatal error : Fail to apply DBWriteRequest !"); + .expect("Fatal error : revert block: Fail to apply BlocksDBsWriteRequest !"); for query in &wot_queries { query - .apply( - &db, - &mut w, - &blockstamp, - &unwrap!(bc.currency_params), - &bc.wot_databases, - ) + .apply(&db, &mut w, &blockstamp, &unwrap!(bc.currency_params)) .expect("Fatal error : Fail to apply WotsDBsWriteRequest !"); } exec_currency_queries(&db, &mut w, blockstamp.id, currency_queries)?; @@ -114,13 +108,7 @@ pub fn apply_rollback(bc: &mut BlockchainModule, new_bc_branch: Vec<Blockstamp>) .expect("Fatal error : Fail to apply DBWriteRequest !"); for query in &wot_dbs_queries { query - .apply( - &db, - &mut w, - &blockstamp, - &unwrap!(bc.currency_params), - &bc.wot_databases, - ) + .apply(&db, &mut w, &blockstamp, &unwrap!(bc.currency_params)) .expect("Fatal error : Fail to apply WotsDBsWriteRequest !"); } exec_currency_queries(&db, &mut w, blockstamp.id, tx_dbs_queries)?; diff --git a/lib/modules/blockchain/blockchain/src/fork/stackable_blocks.rs b/lib/modules/blockchain/blockchain/src/fork/stackable_blocks.rs index 0248b0fea1eaace7a6076731a68c78712efff828..447d0f82a18c5ee51d0b7abf76e2a671f3e4b5b6 100644 --- a/lib/modules/blockchain/blockchain/src/fork/stackable_blocks.rs +++ b/lib/modules/blockchain/blockchain/src/fork/stackable_blocks.rs @@ -60,13 +60,7 @@ pub fn apply_stackable_blocks(bc: &mut BlockchainModule) { .expect("DB error : Fail to apply block query !"); for query in &wot_dbs_queries { query - .apply( - &db, - &mut w, - &blockstamp, - &unwrap!(bc.currency_params), - &bc.wot_databases, - ) + .apply(&db, &mut w, &blockstamp, &unwrap!(bc.currency_params)) .expect("DB error : Fail to apply wot queries !"); } exec_currency_queries(&db, &mut w, blockstamp.id, tx_dbs_queries) diff --git a/lib/modules/blockchain/blockchain/src/sync/apply/blocks_worker.rs b/lib/modules/blockchain/blockchain/src/sync/apply/blocks_worker.rs index 684857e4e75ed39b2a2decefbf5b034ff7c0e821..556fa5b53580a4af0d1dd116edb680a3ec6b02b8 100644 --- a/lib/modules/blockchain/blockchain/src/sync/apply/blocks_worker.rs +++ b/lib/modules/blockchain/blockchain/src/sync/apply/blocks_worker.rs @@ -59,7 +59,7 @@ pub fn execute( )?; Ok(w) }) - .expect("Fatal error : Fail to apply DBWriteRequest !"); + .expect("Fatal error : Fail to apply BlocksDBsWriteQuery !"); chunk_index += 1; if chunk_index == 250 { diff --git a/lib/modules/blockchain/blockchain/src/sync/apply/mod.rs b/lib/modules/blockchain/blockchain/src/sync/apply/mod.rs index b50c9aaf7bd1f91473db319773d264defd463789..07aa12b02c59fa9bc7a61e46317bda379062b380 100644 --- a/lib/modules/blockchain/blockchain/src/sync/apply/mod.rs +++ b/lib/modules/blockchain/blockchain/src/sync/apply/mod.rs @@ -27,9 +27,9 @@ use dubp_common_doc::traits::Document; use dubp_common_doc::{BlockNumber, Blockstamp}; use dubp_currency_params::{CurrencyName, CurrencyParameters}; use dup_crypto::keys::PubKey; -use durs_bc_db_reader::CertsExpirV10Datas; +use durs_bc_db_reader::DbReadable; use durs_bc_db_writer::writers::requests::WotsDBsWriteQuery; -use durs_bc_db_writer::{BinFreeStructDb, WotsV10DBs}; +use durs_bc_db_writer::WotsV10DBs; use durs_common_tools::fatal_error; use durs_network_documents::url::Url; use durs_wot::data::rusty::RustyWebOfTrust; @@ -62,7 +62,6 @@ pub struct BlockApplicator { pub db: Option<Db>, pub wot_index: HashMap<PubKey, WotId>, pub wot_databases: WotsV10DBs, - pub certs_db: BinFreeStructDb<CertsExpirV10Datas>, // time measurement pub wait_begin: SystemTime, pub all_wait_duration: Duration, @@ -97,9 +96,17 @@ impl BlockApplicator { } // Find expire_certs - let expire_certs = - durs_bc_db_reader::indexes::certs::find_expire_certs(&self.certs_db, blocks_expiring) + let expire_certs = if let Some(db) = self.db.take() { + let expire_certs = db + .read(|r| { + durs_bc_db_reader::indexes::certs::find_expire_certs(&db, r, blocks_expiring) + }) .expect("find_expire_certs() : DbError"); + self.db = Some(db); + expire_certs + } else { + fatal_error!("Dev error: BlockApplicator must have DB.") + }; // Get block blockstamp let blockstamp = block_doc.blockstamp(); @@ -142,22 +149,13 @@ impl BlockApplicator { for req in wot_db_reqs { if let WotsDBsWriteQuery::CreateCert( ref _source_pubkey, - ref source, - ref target, - ref created_block_id, + ref _source, + ref _target, + ref _created_block_id, ref _median_time, ) = req { self.certs_count += 1; - // Add cert in certs_db - self.certs_db - .write(|db| { - let mut created_certs = - db.get(&created_block_id.0).cloned().unwrap_or_default(); - created_certs.insert((*source, *target)); - db.insert(*created_block_id, created_certs); - }) - .expect("RustBreakError : please reset data and resync !"); } self.sender_wot_thread .send(SyncJobsMess::WotsDBsWriteQuery( diff --git a/lib/modules/blockchain/blockchain/src/sync/apply/txs_worker.rs b/lib/modules/blockchain/blockchain/src/sync/apply/txs_worker.rs index e49686651ac8063234d0b1b1c75726a715150fcd..5b8b0d2f2116adf0f2670a93318d89197eafee48 100644 --- a/lib/modules/blockchain/blockchain/src/sync/apply/txs_worker.rs +++ b/lib/modules/blockchain/blockchain/src/sync/apply/txs_worker.rs @@ -43,7 +43,7 @@ pub fn execute( req.apply(&db, &mut w, None, in_fork_window)?; Ok(w) }) - .expect("Fatal error : Fail to apply DBWriteRequest !"); + .expect("Fatal error : Fail to apply CurrencyDBsWriteQuery !"); wait_begin = SystemTime::now(); } diff --git a/lib/modules/blockchain/blockchain/src/sync/apply/wot_worker.rs b/lib/modules/blockchain/blockchain/src/sync/apply/wot_worker.rs index 8c78e91a9ae7e64576e585875acfa43e6528550d..4c245a71e33d3081e1e34e06c37f507f87310ba3 100644 --- a/lib/modules/blockchain/blockchain/src/sync/apply/wot_worker.rs +++ b/lib/modules/blockchain/blockchain/src/sync/apply/wot_worker.rs @@ -29,7 +29,6 @@ pub fn execute( // Open databases let db_path = durs_conf::get_blockchain_db_path(profile_path); let db = open_db(&db_path).expect("Fail to open DB."); - let databases = WotsV10DBs::open(Some(&db_path)); // Listen db requets let mut all_wait_duration = Duration::from_millis(0); @@ -39,25 +38,18 @@ pub fn execute( match mess { SyncJobsMess::WotsDBsWriteQuery(blockstamp, currency_params, req) => { db.write(|mut w| { - req.apply( - &db, - &mut w, - &blockstamp, - ¤cy_params.deref(), - &databases, - )?; + req.apply(&db, &mut w, &blockstamp, ¤cy_params.deref())?; Ok(w) }) - .expect("Fatal error : Fail to apply DBWriteRequest !"); + .unwrap_or_else(|_| { + fatal_error!("Fail to apply WotsDBsWriteQuery ({})", blockstamp) + }); } SyncJobsMess::End => break, _ => {} } wait_begin = SystemTime::now(); } - // Save wots databases - info!("Save wots databases in files..."); - databases.save_dbs_except_graph(); // Send finish signal sender_sync_thread diff --git a/lib/modules/blockchain/blockchain/src/sync/mod.rs b/lib/modules/blockchain/blockchain/src/sync/mod.rs index 6d8e7d5d76eff80047ac8b9792a521455311b1fb..ab580d34431bb32746d472cdc9e7e3d781c76a7e 100644 --- a/lib/modules/blockchain/blockchain/src/sync/mod.rs +++ b/lib/modules/blockchain/blockchain/src/sync/mod.rs @@ -23,8 +23,6 @@ use dubp_common_doc::Blockstamp; use dubp_common_doc::{BlockHash, BlockNumber}; use dubp_currency_params::{CurrencyName, CurrencyParameters}; use dup_crypto::keys::*; -use durs_bc_db_reader::CertsExpirV10Datas; -use durs_bc_db_writer::open_free_struct_memory_db; use durs_bc_db_writer::writers::requests::*; use durs_common_tools::fatal_error; use durs_wot::WotId; @@ -267,9 +265,6 @@ pub fn local_sync<DC: DursConfTrait>( // Open databases let dbs_path = durs_conf::get_blockchain_db_path(profile_path.clone()); let db = open_db(dbs_path.as_path()).expect("Fail to open blockchain DB."); - let certs_db = BinFreeStructDb::Mem( - open_free_struct_memory_db::<CertsExpirV10Datas>().expect("Fail to create memory certs_db"), - ); // initialise le BlockApplicator let mut block_applicator = BlockApplicator { @@ -289,7 +284,6 @@ pub fn local_sync<DC: DursConfTrait>( certs_count: 0, blocks_not_expiring: VecDeque::with_capacity(200_000), last_block_expiring: -1, - certs_db, wait_begin: SystemTime::now(), all_wait_duration: Duration::from_millis(0), all_verif_block_hashs_duration: Duration::from_millis(0), diff --git a/lib/tools/dbs-tools/src/kv_db/file.rs b/lib/tools/dbs-tools/src/kv_db/file.rs index b810704a7f6914fb1d5e56ea473d4eb213a0c190..9b8020715e166e076088fee3c01c464f2a61e22a 100644 --- a/lib/tools/dbs-tools/src/kv_db/file.rs +++ b/lib/tools/dbs-tools/src/kv_db/file.rs @@ -139,6 +139,9 @@ pub trait KvFileDbRead: Sized { /// get a multi store fn get_multi_store(&self, store_name: &str) -> &super::MultiStore; + /// get a multi integer store + fn get_multi_int_store(&self, store_name: &str) -> &super::MultiIntegerStore<u32>; + /// Read datas in transaction database fn read<F, R>(&self, f: F) -> Result<R, DbError> where @@ -163,6 +166,10 @@ impl KvFileDbRead for KvFileDbRoHandler { self.0.get_multi_store(store_name) } #[inline] + fn get_multi_int_store(&self, store_name: &str) -> &super::MultiIntegerStore<u32> { + self.0.get_multi_int_store(store_name) + } + #[inline] fn read<F, R>(&self, f: F) -> Result<R, DbError> where F: FnOnce(KvFileDbReader) -> Result<R, DbError>, @@ -256,6 +263,20 @@ impl KvFileDbRead for KvFileDbHandler { fatal_error!("Dev error: store '{}' don't exist in DB.", store_name); } } + fn get_multi_int_store(&self, store_name: &str) -> &super::MultiIntegerStore<u32> { + if let Some(store_enum) = self.stores.get(store_name) { + if let KvFileDbStore::MultiIntKey(store) = store_enum { + store + } else { + fatal_error!( + "Dev error: store '{}' is not a multi integer store.", + store_name + ); + } + } else { + fatal_error!("Dev error: store '{}' don't exist in DB.", store_name); + } + } fn read<F, R>(&self, f: F) -> Result<R, DbError> where F: FnOnce(KvFileDbReader) -> Result<R, DbError>,