diff --git a/lib/modules-lib/bc-db-reader/src/blocks.rs b/lib/modules-lib/bc-db-reader/src/blocks.rs index 92be9d98fa978dc366b537e36860038203c03ad0..2867c98afb44c8bdc65b83398bf2a7228736b6bf 100644 --- a/lib/modules-lib/bc-db-reader/src/blocks.rs +++ b/lib/modules-lib/bc-db-reader/src/blocks.rs @@ -99,27 +99,28 @@ pub fn get_block<DB: DbReadable>( db: &DB, blockstamp: Blockstamp, ) -> Result<Option<DbBlock>, DbError> { - let opt_dal_block = get_dal_block_in_local_blockchain(db, blockstamp.id)?; - if opt_dal_block.is_none() { - get_fork_block(db, blockstamp) - } else { - Ok(opt_dal_block) - } + db.read(|r| { + let opt_dal_block = get_dal_block_in_local_blockchain(db, r, blockstamp.id)?; + if opt_dal_block.is_none() { + get_fork_block(db, r, blockstamp) + } else { + Ok(opt_dal_block) + } + }) } /// Get fork block -pub fn get_fork_block<DB: DbReadable>( +pub fn get_fork_block<DB: DbReadable, R: DbReader>( db: &DB, + r: &R, blockstamp: Blockstamp, ) -> Result<Option<DbBlock>, DbError> { let blockstamp_bytes: Vec<u8> = blockstamp.into(); - db.read(|r| { - if let Some(v) = db.get_store(FORK_BLOCKS).get(r, &blockstamp_bytes)? { - Ok(Some(DB::from_db_value(v)?)) - } else { - Ok(None) - } - }) + if let Some(v) = db.get_store(FORK_BLOCKS).get(r, &blockstamp_bytes)? { + Ok(Some(DB::from_db_value(v)?)) + } else { + Ok(None) + } } /// Get block hash @@ -142,21 +143,25 @@ pub fn get_block_in_local_blockchain<DB: DbReadable>( db: &DB, block_number: BlockNumber, ) -> Result<Option<BlockDocument>, DbError> { - Ok(get_dal_block_in_local_blockchain(db, block_number)?.map(|dal_block| dal_block.block)) + db.read(|r| { + Ok( + get_dal_block_in_local_blockchain(db, r, block_number)? + .map(|dal_block| dal_block.block), + ) + }) } /// Get block in local blockchain -pub fn get_dal_block_in_local_blockchain<DB: DbReadable>( +pub fn get_dal_block_in_local_blockchain<DB: DbReadable, R: DbReader>( db: &DB, + r: &R, block_number: BlockNumber, ) -> Result<Option<DbBlock>, DbError> { - db.read(|r| { - if let Some(v) = db.get_int_store(MAIN_BLOCKS).get(r, block_number.0)? { - Ok(Some(DB::from_db_value(v)?)) - } else { - Ok(None) - } - }) + if let Some(v) = db.get_int_store(MAIN_BLOCKS).get(r, block_number.0)? { + Ok(Some(DB::from_db_value(v)?)) + } else { + Ok(None) + } } /// Get several blocks in local blockchain diff --git a/lib/modules-lib/bc-db-reader/src/current_meta_datas.rs b/lib/modules-lib/bc-db-reader/src/current_meta_datas.rs index a57b7155d9e9244afb3dd85f6842301918dc778d..ae41fd98db03099d643060309fca543d371bbabe 100644 --- a/lib/modules-lib/bc-db-reader/src/current_meta_datas.rs +++ b/lib/modules-lib/bc-db-reader/src/current_meta_datas.rs @@ -97,7 +97,7 @@ pub fn get_current_blockstamp<DB: DbReadable>(db: &DB) -> Result<Option<Blocksta } /// Get current blockstamp -pub fn get_current_blockstamp_<DB: DbReadable, R: Reader>( +pub fn get_current_blockstamp_<DB: DbReadable, R: DbReader>( db: &DB, r: &R, ) -> Result<Option<Blockstamp>, DbError> { @@ -119,21 +119,28 @@ pub fn get_current_blockstamp_<DB: DbReadable, R: Reader>( } /// Get current common time (also named "blockchain time") +#[inline] pub fn get_current_common_time<DB: DbReadable>(db: &DB) -> Result<u64, DbError> { - db.read(|r| { - if let Some(v) = db - .get_int_store(CURRENT_METAS_DATAS) - .get(r, CurrentMetaDataKey::CurrentBlockchainTime.to_u32())? - { - if let DbValue::U64(current_common_time) = v { - Ok(current_common_time) - } else { - Err(DbError::DBCorrupted) - } + db.read(|r| get_current_common_time_(db, r)) +} + +/// Get current common time (also named "blockchain time") +pub fn get_current_common_time_<DB: DbReadable, R: DbReader>( + db: &DB, + r: &R, +) -> Result<u64, DbError> { + if let Some(v) = db + .get_int_store(CURRENT_METAS_DATAS) + .get(r, CurrentMetaDataKey::CurrentBlockchainTime.to_u32())? + { + if let DbValue::U64(current_common_time) = v { + Ok(current_common_time) } else { - Ok(0u64) + Err(DbError::DBCorrupted) } - }) + } else { + Ok(0u64) + } } /// Get fork tree root @@ -152,7 +159,7 @@ pub fn get_fork_tree<DB: DbReadable>(db: &DB) -> Result<ForkTree, DbError> { /// Get greatest wot id #[inline] -pub fn get_greatest_wot_id_<DB: DbReadable, R: Reader>(db: &DB, r: &R) -> Result<WotId, DbError> { +pub fn get_greatest_wot_id_<DB: DbReadable, R: DbReader>(db: &DB, r: &R) -> Result<WotId, DbError> { if let Some(v) = db .get_int_store(CURRENT_METAS_DATAS) .get(r, CurrentMetaDataKey::NextWotId.to_u32())? diff --git a/lib/modules-lib/bc-db-reader/src/indexes/identities.rs b/lib/modules-lib/bc-db-reader/src/indexes/identities.rs index 9b008a8ab4bf77188c66024bfd8cac372b01cdf6..e51cd888ace369274823f5b511efb3345aca3f39 100644 --- a/lib/modules-lib/bc-db-reader/src/indexes/identities.rs +++ b/lib/modules-lib/bc-db-reader/src/indexes/identities.rs @@ -146,7 +146,7 @@ pub fn get_identity_by_pubkey<DB: DbReadable>( } /// Get identity by pubkey -pub fn get_identity_by_pubkey_<DB: DbReadable, R: Reader>( +pub fn get_identity_by_pubkey_<DB: DbReadable, R: DbReader>( db: &DB, r: &R, pubkey: &PubKey, @@ -169,7 +169,7 @@ pub fn get_identity_by_wot_id<DB: DbReadable>( /// Get identity by pubkey #[inline] -pub fn get_identity_by_wot_id_<DB: DbReadable, R: Reader>( +pub fn get_identity_by_wot_id_<DB: DbReadable, R: DbReader>( db: &DB, r: &R, wot_id: WotId, @@ -209,7 +209,7 @@ pub fn get_wot_id<DB: DbReadable>(db: &DB, pubkey: &PubKey) -> Result<Option<Wot /// Get identity wot_id #[inline] -pub fn get_wot_id_<DB: DbReadable, R: Reader>( +pub fn get_wot_id_<DB: DbReadable, R: DbReader>( db: &DB, r: &R, pubkey: &PubKey, diff --git a/lib/modules-lib/bc-db-reader/src/indexes/sources.rs b/lib/modules-lib/bc-db-reader/src/indexes/sources.rs index 5aade1616619fc3b8f5999ddab4999ebcb7507eb..77978c8d6b022fd0ff050d44c21c58e47f8f73b1 100644 --- a/lib/modules-lib/bc-db-reader/src/indexes/sources.rs +++ b/lib/modules-lib/bc-db-reader/src/indexes/sources.rs @@ -141,7 +141,7 @@ pub fn get_utxo_v10<DB: DbReadable>( } /// Get utxo v10 -pub fn get_utxo_v10_<DB: DbReadable, R: Reader>( +pub fn get_utxo_v10_<DB: DbReadable, R: DbReader>( db: &DB, r: &R, utxo_id: UniqueIdUTXOv10, @@ -155,7 +155,7 @@ pub fn get_utxo_v10_<DB: DbReadable, R: Reader>( } /// Get block consumed sources -pub fn get_block_consumed_sources_<DB: DbReadable, R: Reader>( +pub fn get_block_consumed_sources_<DB: DbReadable, R: DbReader>( db: &DB, r: &R, block_number: BlockNumber, diff --git a/lib/modules-lib/bc-db-reader/src/lib.rs b/lib/modules-lib/bc-db-reader/src/lib.rs index 3d824cccce67b43c2891e21fe6a9685fccae6de9..83b2ea514796837cb2ab1634010b2ff0ccc8d067 100644 --- a/lib/modules-lib/bc-db-reader/src/lib.rs +++ b/lib/modules-lib/bc-db-reader/src/lib.rs @@ -37,7 +37,7 @@ pub mod tools; pub use durs_dbs_tools::kv_db::{ KvFileDbRead as DbReadable, KvFileDbRoHandler as BcDbRo, KvFileDbSchema, KvFileDbStoreType, - KvFileDbValue as DbValue, Readable as Reader, + KvFileDbValue as DbValue, Readable as DbReader, }; use constants::*; diff --git a/lib/modules/blockchain/blockchain/src/dunp/receiver.rs b/lib/modules/blockchain/blockchain/src/dunp/receiver.rs index 0776a10c37974c6e69aa482d1762792676bba5a1..5990a53692c1a0c240280f42037477198419309e 100644 --- a/lib/modules/blockchain/blockchain/src/dunp/receiver.rs +++ b/lib/modules/blockchain/blockchain/src/dunp/receiver.rs @@ -42,6 +42,9 @@ pub fn receive_blocks(bc: &mut BlockchainModule, blocks: Vec<BlockDocument>) { for block in blocks.into_iter() { let blockstamp = block.blockstamp(); + // For eventually rollback + let mut new_bc_branch_opt = None; + // Open write db transaction let db = bc.take_db(); db.write(|mut w| { @@ -93,13 +96,13 @@ pub fn receive_blocks(bc: &mut BlockchainModule, blocks: Vec<BlockDocument>) { info!("blockchain: new fork block(#{})", blockstamp); if let Ok(Some(new_bc_branch)) = fork_algo::fork_resolution_algo( &db, + w.as_ref(), &bc.fork_tree, unwrap!(bc.currency_params).fork_window_size, bc.current_blockstamp, &bc.invalid_forks, ) { - info!("blockchain: apply_rollback({:?})", new_bc_branch); - rollback::apply_rollback(bc, new_bc_branch); + new_bc_branch_opt = Some(new_bc_branch); } } CheckAndApplyBlockReturn::OrphanBlock => { @@ -144,6 +147,11 @@ pub fn receive_blocks(bc: &mut BlockchainModule, blocks: Vec<BlockDocument>) { }) .unwrap_or_else(|_| fatal_error!("Fail to check or apply block: {}.", blockstamp)); bc.db = Some(db); + + if let Some(new_bc_branch) = new_bc_branch_opt { + info!("blockchain: apply_rollback({:?})", new_bc_branch); + rollback::apply_rollback(bc, new_bc_branch); + } } // Save databases if save_dbs { diff --git a/lib/modules/blockchain/blockchain/src/fork/fork_algo.rs b/lib/modules/blockchain/blockchain/src/fork/fork_algo.rs index 7cdcb6b52bfe99b5476a9ef9f5b9202a4f54dc9c..7adda645f6b27483dc6907e3570bd3febde2ec2e 100644 --- a/lib/modules/blockchain/blockchain/src/fork/fork_algo.rs +++ b/lib/modules/blockchain/blockchain/src/fork/fork_algo.rs @@ -16,7 +16,7 @@ use dubp_block_doc::block::BlockDocumentTrait; use dubp_common_doc::Blockstamp; use durs_bc_db_reader::blocks::fork_tree::ForkTree; -use durs_bc_db_reader::DbReadable; +use durs_bc_db_reader::{DbReadable, DbReader}; use durs_bc_db_writer::DbError; use std::collections::HashSet; @@ -25,14 +25,15 @@ pub static ADVANCE_BLOCKS: &u32 = &3; /// Advance blockchain time required (in seconds) pub static ADVANCE_TIME: &u64 = &900; -pub fn fork_resolution_algo<DB: DbReadable>( +pub fn fork_resolution_algo<DB: DbReadable, R: DbReader>( db: &DB, + r: &R, fork_tree: &ForkTree, fork_window_size: usize, current_blockstamp: Blockstamp, invalid_blocks: &HashSet<Blockstamp>, ) -> Result<Option<Vec<Blockstamp>>, DbError> { - let current_bc_time = durs_bc_db_reader::current_meta_datas::get_current_common_time(db)?; + let current_bc_time = durs_bc_db_reader::current_meta_datas::get_current_common_time_(db, r)?; debug!( "fork_resolution_algo({}, {})", @@ -53,7 +54,7 @@ pub fn fork_resolution_algo<DB: DbReadable>( let branch_head_blockstamp = branch.last().expect("safe unwrap"); let branch_head_median_time = - durs_bc_db_reader::blocks::get_fork_block(db, *branch_head_blockstamp)? + durs_bc_db_reader::blocks::get_fork_block(db, r, *branch_head_blockstamp)? .unwrap_or_else(|| { panic!( "Db corrupted: fork block {} referenced in fork tree but not exist in db.", @@ -179,13 +180,14 @@ mod tests { // Must not fork assert_eq!( None, - fork_resolution_algo( + db.read(|r| fork_resolution_algo( &db, + r, &fork_tree, fork_window_size, current_blockstamp, &invalid_blocks - )? + ))? ); // Add the determining fork block @@ -223,13 +225,14 @@ mod tests { fork_blocks[2].blockstamp(), determining_blockstamp, ]), - fork_resolution_algo( + db.read(|r| fork_resolution_algo( &db, + r, &mut fork_tree, fork_window_size, current_blockstamp, &invalid_blocks - )? + ))? ); current_blockstamp = determining_blockstamp; @@ -257,13 +260,14 @@ mod tests { // Must refork assert_eq!( Some(new_main_blocks.iter().map(|b| b.blockstamp()).collect()), - fork_resolution_algo( + db.read(|r| fork_resolution_algo( &db, + r, &mut fork_tree, fork_window_size, current_blockstamp, &invalid_blocks - )? + ))? ); //current_blockstamp = new_main_blocks.last().expect("safe unwrap").blockstamp(); diff --git a/lib/modules/blockchain/blockchain/src/fork/rollback.rs b/lib/modules/blockchain/blockchain/src/fork/rollback.rs index 0808c8ee8e1951a806ceea7c124aeb9d6dc6ae80..d9129e56c2370eb245f2ed42998b2664aba209c9 100644 --- a/lib/modules/blockchain/blockchain/src/fork/rollback.rs +++ b/lib/modules/blockchain/blockchain/src/fork/rollback.rs @@ -36,7 +36,7 @@ pub fn apply_rollback(bc: &mut BlockchainModule, new_bc_branch: Vec<Blockstamp>) // Rollback (revert old branch) while bc.current_blockstamp.id.0 > last_common_block_number { if let Some(dal_block) = - durs_bc_db_reader::blocks::get_fork_block(&db, bc.current_blockstamp) + durs_bc_db_reader::blocks::get_fork_block(&db, w.as_ref(), bc.current_blockstamp) .unwrap_or_else(|_| { fatal_error!("revert block {} fail !", bc.current_blockstamp); }) @@ -90,7 +90,8 @@ pub fn apply_rollback(bc: &mut BlockchainModule, new_bc_branch: Vec<Blockstamp>) // Apply new branch let mut new_branch_is_valid = true; for blockstamp in &new_bc_branch { - if let Ok(Some(dal_block)) = durs_bc_db_reader::blocks::get_fork_block(&db, *blockstamp) + if let Ok(Some(dal_block)) = + durs_bc_db_reader::blocks::get_fork_block(&db, w.as_ref(), *blockstamp) { new_branch_blocks.push(dal_block.clone()); if let Ok(CheckAndApplyBlockReturn::ValidMainBlock(ValidBlockApplyReqs(