Skip to content
Snippets Groups Projects
Commit 2dc0ffb8 authored by Pascal Engélibert's avatar Pascal Engélibert :bicyclist:
Browse files

fix(distance): max_depth, compute min_certs_for_referee

parent 75b06534
No related branches found
No related tags found
No related merge requests found
Pipeline #32320 failed
...@@ -8,7 +8,7 @@ use subxt::storage::StorageKey; ...@@ -8,7 +8,7 @@ use subxt::storage::StorageKey;
pub struct Settings { pub struct Settings {
pub evaluation_result_dir: PathBuf, pub evaluation_result_dir: PathBuf,
pub min_certs_for_referee: u32, pub max_depth: u32,
pub rpc_url: String, pub rpc_url: String,
} }
...@@ -16,7 +16,7 @@ impl Default for Settings { ...@@ -16,7 +16,7 @@ impl Default for Settings {
fn default() -> Self { fn default() -> Self {
Self { Self {
evaluation_result_dir: PathBuf::from("/tmp/duniter/chains/gdev/distance"), evaluation_result_dir: PathBuf::from("/tmp/duniter/chains/gdev/distance"),
min_certs_for_referee: 2, max_depth: 5,
rpc_url: String::from("ws://127.0.0.1:9944"), rpc_url: String::from("ws://127.0.0.1:9944"),
} }
} }
...@@ -145,6 +145,10 @@ pub async fn run(settings: Settings) { ...@@ -145,6 +145,10 @@ pub async fn run(settings: Settings) {
members.insert(idty_id_from_storage_key(&member_idty), 0); members.insert(idty_id_from_storage_key(&member_idty), 0);
} }
let min_certs_for_referee = (members.len() as f32)
.powf(1. / (settings.max_depth as f32))
.ceil() as u32;
// idty -> received certs // idty -> received certs
let mut received_certs = HashMap::<IdtyIndex, Vec<IdtyIndex>>::new(); let mut received_certs = HashMap::<IdtyIndex, Vec<IdtyIndex>>::new();
...@@ -160,7 +164,7 @@ pub async fn run(settings: Settings) { ...@@ -160,7 +164,7 @@ pub async fn run(settings: Settings) {
while let Some((receiver, issuers)) = certs_iter.next().await.unwrap() { while let Some((receiver, issuers)) = certs_iter.next().await.unwrap() {
let receiver = idty_id_from_storage_key(&receiver); let receiver = idty_id_from_storage_key(&receiver);
// Update members' issued certs count // Update members' issued certs count
if issuers.len() as u32 >= settings.min_certs_for_referee { if issuers.len() as u32 >= min_certs_for_referee {
for (issuer, _removable_on) in issuers.iter() { for (issuer, _removable_on) in issuers.iter() {
if let Some(issued_certs) = members.get_mut(issuer) { if let Some(issued_certs) = members.get_mut(issuer) {
*issued_certs += 1; *issued_certs += 1;
...@@ -181,7 +185,7 @@ pub async fn run(settings: Settings) { ...@@ -181,7 +185,7 @@ pub async fn run(settings: Settings) {
// Only retain referees // Only retain referees
// TODO benchmark: can it be faster? (maybe using drain_filter) // TODO benchmark: can it be faster? (maybe using drain_filter)
members.retain(|_idty, issued_certs| *issued_certs >= settings.min_certs_for_referee); members.retain(|_idty, issued_certs| *issued_certs >= min_certs_for_referee);
let referees = members; let referees = members;
let evaluation: Vec<Perbill> = evaluation_pool let evaluation: Vec<Perbill> = evaluation_pool
...@@ -190,12 +194,7 @@ pub async fn run(settings: Settings) { ...@@ -190,12 +194,7 @@ pub async fn run(settings: Settings) {
.into_par_iter() .into_par_iter()
.map(|(idty, _)| { .map(|(idty, _)| {
Perbill::from_rational( Perbill::from_rational(
distance_rule( distance_rule(&received_certs, &referees, settings.max_depth, idty),
&received_certs,
&referees,
settings.min_certs_for_referee,
idty,
),
referees.len() as u32, referees.len() as u32,
) )
}) })
......
...@@ -4,8 +4,9 @@ use clap::Parser; ...@@ -4,8 +4,9 @@ use clap::Parser;
struct Cli { struct Cli {
#[clap(short = 'd', long, default_value = "/tmp/duniter/chains/gdev/distance")] #[clap(short = 'd', long, default_value = "/tmp/duniter/chains/gdev/distance")]
evaluation_result_dir: String, evaluation_result_dir: String,
#[clap(short = 'c', long, default_value = "2")] /// Maximum depth to explore the WoT graph for referees
min_certs_for_referee: u32, #[clap(short = 'D', long, default_value = "5")]
max_depth: u32,
#[clap(short = 'u', long, default_value = "ws://127.0.0.1:9944")] #[clap(short = 'u', long, default_value = "ws://127.0.0.1:9944")]
rpc_url: String, rpc_url: String,
} }
...@@ -16,7 +17,7 @@ async fn main() { ...@@ -16,7 +17,7 @@ async fn main() {
distance_oracle::run(distance_oracle::Settings { distance_oracle::run(distance_oracle::Settings {
evaluation_result_dir: cli.evaluation_result_dir.into(), evaluation_result_dir: cli.evaluation_result_dir.into(),
min_certs_for_referee: cli.min_certs_for_referee, max_depth: cli.max_depth,
rpc_url: cli.rpc_url, rpc_url: cli.rpc_url,
}) })
.await; .await;
......
...@@ -18,10 +18,14 @@ It will be available at `./target/release/distance-oracle`. Move it to somewhere ...@@ -18,10 +18,14 @@ It will be available at `./target/release/distance-oracle`. Move it to somewhere
Add this line to your cron with the command `crontab -e`: (add option `-u <user>` to edit another user's cron) Add this line to your cron with the command `crontab -e`: (add option `-u <user>` to edit another user's cron)
4,24,44 * * * * /absolute/path/to/distance-oracle 4,24,44 * * * * nice -n 2 /absolute/path/to/distance-oracle
The precise hours don't matter so you can pick random values, but it should run at least one time per hour, and running it more often decreases the risk of problem in case of missing blocks or temporary network failure. The precise hours don't matter so you can pick random values, but it should run at least one time per hour, and running it more often decreases the risk of problem in case of missing blocks or temporary network failure.
If the evaluation ran successfully in a session, the next runs in the same session won't re-evaluate the same data. If the evaluation ran successfully in a session, the next runs in the same session won't re-evaluate the same data.
No additional configuration is needed for Duniter. The `nice -n 2` lowers the oracle's priority, so that Duniter has the priority even when the oracle wants to use all the cores.
### Additional Duniter configuration
Duniter should keep states at least one session old, that it 600 blocks (while 256 is the default). Use the option `--state-pruning 600` if your node is not already an archive (`--state-pruning archive`).
...@@ -264,8 +264,6 @@ pub fn spawn_distance_oracle(distance_oracle_binary_path: &str, duniter_rpc_port ...@@ -264,8 +264,6 @@ pub fn spawn_distance_oracle(distance_oracle_binary_path: &str, duniter_rpc_port
&format!("ws://127.0.0.1:{duniter_rpc_port}"), &format!("ws://127.0.0.1:{duniter_rpc_port}"),
"-d", "-d",
"/tmp/duniter-cucumber/chains/gdev/distance", "/tmp/duniter-cucumber/chains/gdev/distance",
"-c",
"2",
] ]
.iter(), .iter(),
) )
......
...@@ -514,7 +514,7 @@ async fn should_have_distance_ok(world: &mut DuniterWorld, who: String) -> Resul ...@@ -514,7 +514,7 @@ async fn should_have_distance_ok(world: &mut DuniterWorld, who: String) -> Resul
.unwrap(); .unwrap();
if world if world
.read(&gdev::storage().distance().distance_ok_identities(&idty_id)) .read(&gdev::storage().distance().distance_ok_identities(idty_id))
.await? .await?
.unwrap() .unwrap()
{ {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment