Skip to content
Snippets Groups Projects
Commit adcd76dd authored by Hugo Trentesaux's avatar Hugo Trentesaux
Browse files

[feat] bc-db-reader: implement personal difficulty

implémentation de la partie pur métier du calcul de la difficulté personnalisée
par 1000i100, Hugo et Krousky
parent df845e17
Branches
Tags
No related merge requests found
...@@ -577,6 +577,7 @@ dependencies = [ ...@@ -577,6 +577,7 @@ dependencies = [
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unwrap 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "unwrap 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
...@@ -1327,6 +1328,38 @@ dependencies = [ ...@@ -1327,6 +1328,38 @@ dependencies = [
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "num"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num-complex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
"num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-bigint"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-complex"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "num-integer" name = "num-integer"
version = "0.1.41" version = "0.1.41"
...@@ -1336,6 +1369,27 @@ dependencies = [ ...@@ -1336,6 +1369,27 @@ dependencies = [
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "num-iter"
version = "0.1.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-rational"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.8" version = "0.2.8"
...@@ -2611,7 +2665,12 @@ dependencies = [ ...@@ -2611,7 +2665,12 @@ dependencies = [
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" "checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
"checksum num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db"
"checksum num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a"
"checksum num-complex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fcb0cf31fb3ff77e6d2a6ebd6800df7fdcd106f2ad89113c9130bcd07f93dffc"
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" "checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
"checksum num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "76bd5272412d173d6bf9afdf98db8612bbabc9a7a830b7bfc9c188911716132e"
"checksum num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2885278d5fe2adc2f75ced642d52d879bffaceb5a2e0b1d4309ffdfb239b454"
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" "checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
......
...@@ -26,6 +26,7 @@ maplit = "1.0.1" ...@@ -26,6 +26,7 @@ maplit = "1.0.1"
fnv = "1.0.6" fnv = "1.0.6"
serde = { version = "1.0.*", features = ["derive"] } serde = { version = "1.0.*", features = ["derive"] }
unwrap = "1.2.1" unwrap = "1.2.1"
num = "0.2"
[dev-dependencies] [dev-dependencies]
dup-crypto-tests-tools = { path = "../../tests-tools/crypto-tests-tools" } dup-crypto-tests-tools = { path = "../../tests-tools/crypto-tests-tools" }
......
...@@ -17,8 +17,11 @@ ...@@ -17,8 +17,11 @@
//use crate::constants::*; //use crate::constants::*;
use crate::*; use crate::*;
extern crate num;
use dubp_common_doc::BlockNumber;
use durs_dbs_tools::DbError; use durs_dbs_tools::DbError;
use durs_wot::WotId; use durs_wot::WotId;
use num::Float;
#[derive(Clone, Copy, Debug, Eq, PartialEq)] #[derive(Clone, Copy, Debug, Eq, PartialEq)]
/// Describe a member in current frame /// Describe a member in current frame
...@@ -54,3 +57,95 @@ pub fn get_member_diffi<DB: DbReadable, R: DbReader>( ...@@ -54,3 +57,95 @@ pub fn get_member_diffi<DB: DbReadable, R: DbReader>(
) -> Result<PersonalDifficulty, DbError> { ) -> Result<PersonalDifficulty, DbError> {
unimplemented!(); unimplemented!();
} }
/// calcule la difficulté personnalisée à partir des données prêtes à l'emploi
/// reference dans le protocol : https://github.com/duniter/duniter/blob/master/doc/Protocol.md#br_g18---headpowzeros-and-headpowremainder
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,
median_of_blocks_in_frame: usize,
) -> PersonalDifficulty {
PersonalDifficulty {
exclusion_factor: exclusion_factor(
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),
}
}
/// calcule le facteur d'exclusion à partir des membres de la fenêtres courante et du dernier block du membre concerné
/// ne gère pas le cas où le membre n'est pas dans la fenêtre courante
///
/// nb_member_in_frame : la valeur du champ issuersCount du dernier bloc trouvé par le membre
/// nb_blocks_since : le nombre de blocs trouvés par le reste du réseau depuis que le membre considéré a trouvé son dernier bloc
/// 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
pub fn exclusion_factor(nb_member_in_frame: usize, nb_blocks_since: u32) -> usize {
std::cmp::max(
1,
(0.67 * (nb_member_in_frame as f64 / (1 + nb_blocks_since) as f64)).floor() as usize,
)
}
/// handicap calcule le handicap d'un membre à partir du nombre de blocs qu'il a caclulé dans la fenêtre courante et du
/// 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
/// 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))
///
/// 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 {
(((std::cmp::max(
1,
(nb_personal_blocks_in_frame + 1) / median_of_blocks_in_frame,
)) as f64)
.ln()
/ 1.189.ln())
.floor() as usize
}
#[cfg(test)]
mod tests {
use super::*;
//TODO: déplacer la fonction métier dans blockchain ou bc-db-writer
#[test]
fn test_exclusion_factor() {
assert_eq!(1, exclusion_factor(1, 0));
assert_eq!(2, exclusion_factor(15, 4));
}
#[test]
fn test_handicap() {
assert_eq!(13, handicap(500, 50));
assert_eq!(0, handicap(1, 50));
}
#[test]
fn test_compute_personal_difficulty_no_penality() {
assert_eq!(
PersonalDifficulty {
exclusion_factor: 1,
handicap: 0
},
compute_personal_difficulty(100, BlockNumber(1000), BlockNumber(1100), 2, 5)
);
}
#[test]
fn test_compute_personal_difficulty_double_penality() {
assert_eq!(
PersonalDifficulty {
exclusion_factor: 3,
handicap: 10
},
compute_personal_difficulty(50, BlockNumber(1000), BlockNumber(1010), 5, 1)
);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment