diff --git a/lib/modules-lib/bc-db-reader/src/current_frame.rs b/lib/modules-lib/bc-db-reader/src/current_frame.rs index 09397513a9a69afeded3a013558ecfc020a21f9d..9eee726e7376f5ee07dd6c0042d6235c9bc4f5ad 100644 --- a/lib/modules-lib/bc-db-reader/src/current_frame.rs +++ b/lib/modules-lib/bc-db-reader/src/current_frame.rs @@ -15,69 +15,16 @@ //! Current frame : Interval of blocks taken for the calculation of the personalized difficulty. -//use crate::constants::*; -use crate::*; - -extern crate num; +pub mod entities; use crate::current_meta_datas::get_current_blockstamp_; +use crate::*; use current_meta_datas::CurrentMetaDataKey; use dubp_common_doc::BlockNumber; use durs_dbs_tools::DbError; use durs_wot::WotId; +use entities::{MemberFrameInfo, MemberInCurrentFrame, PersonalDifficulty}; use num::Float; -//use rkv::store::integer::IntegerStore; -use serde::de::DeserializeOwned; -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -/// Describe a member in current frame -pub struct MemberInCurrentFrame { - /// Number of blocks forged by the member in the current frame. - pub forged_blocks: usize, - /// Personal difficulty of the member. - pub difficulty: PersonalDifficulty, -} - -#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)] -/// Personal difficulty of a member. -pub struct PersonalDifficulty { - /// Exclusion factor - pub exclusion_factor: usize, - /// handicap - pub handicap: usize, -} - -impl Default for PersonalDifficulty { - fn default() -> Self { - PersonalDifficulty { - exclusion_factor: 1, - handicap: 0, - } - } -} - -#[derive(Debug, Copy, Clone, Serialize, Deserialize)] -/// in frame member info data store -pub struct MemberFrameInfo { - /// last block number written by this member - pub last_personal_block_number: BlockNumber, - /// nb member in current frame when last block was written by this member - pub last_personal_nb_members_in_frame: usize, - /// nb blocks written by this member in current frame - pub nb_personal_blocks_in_frame: usize, - personal_difficulty: PersonalDifficulty, -} -//impl Default for MemberFrameInfo { -// fn default() -> Self { -// MemberFrameInfo { -// last_personal_block_number: BlockNumber, -// last_personal_members_in_frame: usize, -// nb_personal_blocks_in_frame: usize, -// personal_difficulty: PersonalDifficulty, -// } -// } -//} /// Get current frame datas pub fn get_current_frame<DB: DbReadable>( @@ -86,62 +33,18 @@ pub fn get_current_frame<DB: DbReadable>( unimplemented!(); } -// TODO: tester ça -/// -- fr -- -/// récupère dans le store store_name de la db active le contenu u64 de la clef key -/// la clef doit être présente dans le store, sinon DBCorrupted -/// ne fonctionne que pour des store à index / clef au format u32 -pub fn get_required_u64_in_int_store<DB: DbReadable, R: DbReader>( - db: &DB, - r: &R, - store_name: &str, - key: u32, -) -> Result<u64, DbError> { - if let Some(value) = db.get_int_store(store_name).get(r, key)? { - if let DbValue::U64(value_u64) = value { - Ok(value_u64) - } else { - Err(DbError::DBCorrupted) - } - } else { - Err(DbError::DBCorrupted) - } -} - -// TODO: tester ça -//pub fn get_required_bin_in_int_store<DB: DbReadable, R: DbReader, V: DeserializeOwned>( -// db: &DB, -// r: &R, -// store_name: &str, -// key: u32, -//) -> Result<V, DbError> { -// if let Some(value) = db.get_int_store(store_name).get(r, key)? { -// Ok(BcDbRo::from_db_value(value)?) -// } else { -// Err(DbError::DBCorrupted) -// } -//} -/// TODO: tester ça -/// -- fr -- -/// récupère dans le store store_name de la db active le contenu binaire/Blob de la clef key -/// retourne None si la clef n'est pas trouvée. -/// ne fonctionne que pour des store à index / clef au format u32 -pub fn get_bin_in_int_store<DB: DbReadable, R: DbReader, V: DeserializeOwned>( +/// Get the personal difficulty of a member. +/// If the member is not in the current window, returns `pow_min`. +pub fn get_member_diffi<DB: DbReadable, R: DbReader>( db: &DB, r: &R, - store_name: &str, - key: u32, -) -> Result<Option<V>, DbError> { - if let Some(value) = db.get_int_store(store_name).get(r, key)? { - Ok(Some(BcDbRo::from_db_value(value)?)) - } else { - Ok(None) - } + wot_id: WotId, +) -> Result<PersonalDifficulty, DbError> { + compute_member_diffi(db, r, wot_id) } - -/// Get the personal difficulty of a member. +/// Compute the personal difficulty of a member. /// If the member is not in the current window, returns `pow_min`. -pub fn get_member_diffi<DB: DbReadable, R: DbReader>( +pub fn compute_member_diffi<DB: DbReadable, R: DbReader>( db: &DB, r: &R, wot_id: WotId, @@ -150,12 +53,12 @@ pub fn get_member_diffi<DB: DbReadable, R: DbReader>( // difficulty par défaut // sinon récupérer le résultat et continuer let optional_member_info: Option<MemberFrameInfo> = - get_bin_in_int_store(db, r, CURRENT_FRAME_MEMBERS, wot_id.0 as u32)?; + crate::get::get_bin_in_int_store(db, r, CURRENT_FRAME_MEMBERS, wot_id.0 as u32)?; if let Some(member_info) = optional_member_info { let current_block_number = get_current_blockstamp_(db, r)? .ok_or(DbError::DBCorrupted)? .id; - let median_frame_member = get_required_u64_in_int_store( + let median_frame_member = crate::get::get_required_u64_in_int_store( db, r, CURRENT_METAS_DATAS, @@ -165,7 +68,7 @@ pub fn get_member_diffi<DB: DbReadable, R: DbReader>( member_info.last_personal_nb_members_in_frame.into(), member_info.last_personal_block_number, current_block_number, - member_info.nb_personal_blocks_in_frame, + member_info.member_in_current_frame.forged_blocks, median_frame_member as usize, )) } else { @@ -182,7 +85,7 @@ pub fn compute_personal_difficulty( nb_member_in_frame: usize, last_personal_block_number: BlockNumber, current_block_number: BlockNumber, - nb_personal_blocks_in_frame: usize, + personal_forged_blocks_in_frame: usize, median_of_blocks_in_frame: usize, ) -> PersonalDifficulty { PersonalDifficulty { @@ -190,7 +93,7 @@ pub fn compute_personal_difficulty( nb_member_in_frame, current_block_number.0 - last_personal_block_number.0, ), - handicap: handicap(nb_personal_blocks_in_frame, median_of_blocks_in_frame), + handicap: handicap(personal_forged_blocks_in_frame, median_of_blocks_in_frame), } } @@ -202,6 +105,7 @@ pub fn compute_personal_difficulty( /// exclusion_factor = MAX [ 1 ; FLOOR (0.67 * nb_member_in_frame / (1 + nb_blocks_since)) ] /// /// reference dans le protocol : https://github.com/duniter/duniter/blob/master/doc/Protocol.md#br_g18---headpowzeros-and-headpowremainder +#[inline] pub fn exclusion_factor(nb_member_in_frame: usize, nb_blocks_since: u32) -> usize { std::cmp::max( 1, @@ -213,15 +117,16 @@ pub fn exclusion_factor(nb_member_in_frame: usize, nb_blocks_since: u32) -> usiz /// nombre median de blocs écrits par les membres dans la fenêtre courante. /// ne gère pas le cas où le membre n'est pas dans la fenêtre courante /// -/// nb_personal_blocks_in_frame : le nombre de blocs écrits par le membre considéré dans la fenêtre courante +/// personal_forged_blocks_in_frame : le nombre de blocs écrits par le membre considéré dans la fenêtre courante /// median_of_blocks_in_frame : le nombre médian de blocs écrits par les membres au sein de la fenêtre courante. -/// handicap = FLOOR(LN(MAX(1;(nb_personal_blocks_in_frame + 1) / median_of_blocks_in_frame)) / LN(1.189)) +/// handicap = FLOOR(LN(MAX(1;(personal_forged_blocks_in_frame + 1) / median_of_blocks_in_frame)) / LN(1.189)) /// /// reference dans le protocol : https://github.com/duniter/duniter/blob/master/doc/Protocol.md#br_g18---headpowzeros-and-headpowremainder -pub fn handicap(nb_personal_blocks_in_frame: usize, median_of_blocks_in_frame: usize) -> usize { +#[inline] +pub fn handicap(personal_forged_blocks_in_frame: usize, median_of_blocks_in_frame: usize) -> usize { (((std::cmp::max( 1, - (nb_personal_blocks_in_frame + 1) / median_of_blocks_in_frame, + (personal_forged_blocks_in_frame + 1) / median_of_blocks_in_frame, )) as f64) .ln() / 1.189.ln()) @@ -300,13 +205,15 @@ mod tests { fn factory_member_frame_info( last_bn: u32, last_mf: usize, - nbr_pbf: usize, + fb: usize, ) -> Result<Vec<u8>, DbError> { durs_dbs_tools::to_bytes(&MemberFrameInfo { last_personal_block_number: BlockNumber(last_bn), last_personal_nb_members_in_frame: last_mf, - nb_personal_blocks_in_frame: nbr_pbf, - personal_difficulty: PersonalDifficulty::default(), + member_in_current_frame: MemberInCurrentFrame { + forged_blocks: fb, + difficulty: PersonalDifficulty::default(), + }, }) } diff --git a/lib/modules-lib/bc-db-reader/src/current_frame/entities.rs b/lib/modules-lib/bc-db-reader/src/current_frame/entities.rs new file mode 100644 index 0000000000000000000000000000000000000000..8b3b4b796eed5d0703617d64ceb1b0360c5a6996 --- /dev/null +++ b/lib/modules-lib/bc-db-reader/src/current_frame/entities.rs @@ -0,0 +1,56 @@ +// Copyright (C) 2017-2019 The AXIOM TEAM Association. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +//! Defines current frame entities (struct and traits) +use dubp_common_doc::BlockNumber; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)] +/// Describe a member in current frame +pub struct MemberInCurrentFrame { + /// Number of blocks forged by the member in the current frame. + pub forged_blocks: usize, + /// Personal difficulty of the member. + pub difficulty: PersonalDifficulty, +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)] +/// Personal difficulty of a member. +pub struct PersonalDifficulty { + /// Exclusion factor + pub exclusion_factor: usize, + /// Handicap + pub handicap: usize, +} + +impl Default for PersonalDifficulty { + fn default() -> Self { + PersonalDifficulty { + exclusion_factor: 1, + handicap: 0, + } + } +} + +#[derive(Debug, Copy, Clone, Serialize, Deserialize)] +/// In frame member info data store +pub struct MemberFrameInfo { + /// Last block number written by this member + pub last_personal_block_number: BlockNumber, + /// Nb member in current frame when last block was written by this member + pub last_personal_nb_members_in_frame: usize, + /// Substruct member_in_current_frame (forged_blocks, difficulty) read scope oriented + pub member_in_current_frame: MemberInCurrentFrame, +} diff --git a/lib/modules-lib/bc-db-reader/src/get.rs b/lib/modules-lib/bc-db-reader/src/get.rs new file mode 100644 index 0000000000000000000000000000000000000000..9d358b97a998a20c49785aba81b6697dedb7eb5f --- /dev/null +++ b/lib/modules-lib/bc-db-reader/src/get.rs @@ -0,0 +1,72 @@ +// Copyright (C) 2017-2019 The AXIOM TEAM Association. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +//! Getters for easyer access to store + +use crate::*; +use serde::de::DeserializeOwned; + +// TODO: tester ça +/// -- fr -- +/// Récupère dans le store store_name de la db active le contenu u64 de la clef key +/// la clef doit être présente dans le store, sinon DBCorrupted +/// ne fonctionne que pour des store à index / clef au format u32 +pub fn get_required_u64_in_int_store<DB: DbReadable, R: DbReader>( + db: &DB, + r: &R, + store_name: &str, + key: u32, +) -> Result<u64, DbError> { + if let Some(value) = db.get_int_store(store_name).get(r, key)? { + if let DbValue::U64(value_u64) = value { + Ok(value_u64) + } else { + Err(DbError::DBCorrupted) + } + } else { + Err(DbError::DBCorrupted) + } +} + +// TODO: tester ça +//pub fn get_required_bin_in_int_store<DB: DbReadable, R: DbReader, V: DeserializeOwned>( +// db: &DB, +// r: &R, +// store_name: &str, +// key: u32, +//) -> Result<V, DbError> { +// if let Some(value) = db.get_int_store(store_name).get(r, key)? { +// Ok(BcDbRo::from_db_value(value)?) +// } else { +// Err(DbError::DBCorrupted) +// } +//} +/// TODO: tester ça +/// -- fr -- +/// récupère dans le store store_name de la db active le contenu binaire/Blob de la clef key +/// retourne None si la clef n'est pas trouvée. +/// ne fonctionne que pour des store à index / clef au format u32 +pub fn get_bin_in_int_store<DB: DbReadable, R: DbReader, V: DeserializeOwned>( + db: &DB, + r: &R, + store_name: &str, + key: u32, +) -> Result<Option<V>, DbError> { + if let Some(value) = db.get_int_store(store_name).get(r, key)? { + Ok(Some(BcDbRo::from_db_value(value)?)) + } else { + Ok(None) + } +} diff --git a/lib/modules-lib/bc-db-reader/src/lib.rs b/lib/modules-lib/bc-db-reader/src/lib.rs index 2128a0842d1c53834f3224592f3bb4fc8e317471..bcc4237af08bd21b2378baf0cbceba65b01cb1e4 100644 --- a/lib/modules-lib/bc-db-reader/src/lib.rs +++ b/lib/modules-lib/bc-db-reader/src/lib.rs @@ -32,6 +32,7 @@ pub mod constants; pub mod currency_params; pub mod current_frame; pub mod current_meta_datas; +pub mod get; pub mod indexes; pub mod paging; pub mod tools;