diff --git a/.vscode/settings.json b/.vscode/settings.json
index 3070b8018c7c4e188342e3ca960c949140efd8c5..f6e785cae54a157c5013b596877b512387c97924 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -14,5 +14,6 @@
     "port_p2p": 19931,
     "port_rpc": 19932,
     "port_ws": 19933
-  }
+  },
+  "rust-analyzer.showUnlinkedFileNotification": false
 }
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
index e4699eb8721ab4d035b58961fe0b7a81e6bd5fb2..2c5d16da462af2dd947e304887bd6de4ee131bc8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -836,6 +836,15 @@ dependencies = [
  "os_str_bytes",
 ]
 
+[[package]]
+name = "cmake"
+version = "0.1.50"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130"
+dependencies = [
+ "cc",
+]
+
 [[package]]
 name = "codespan-reporting"
 version = "0.11.1"
@@ -1558,7 +1567,11 @@ dependencies = [
 name = "distance-oracle"
 version = "0.1.0"
 dependencies = [
+ "bincode",
  "clap 4.1.4",
+ "dubp-wot",
+ "flate2",
+ "num-traits",
  "parity-scale-codec",
  "rayon",
  "sp-core",
@@ -1596,6 +1609,19 @@ version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c00704156a7de8df8da0911424e30c2049957b0a714542a44e05fe693dd85313"
 
+[[package]]
+name = "dubp-wot"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59f62bdc1abf2da65794c9fd7fe46f7328834a97a2346048d46b0b6676302de0"
+dependencies = [
+ "log",
+ "once_cell",
+ "parking_lot 0.11.2",
+ "rayon",
+ "serde",
+]
+
 [[package]]
 name = "duniter"
 version = "0.3.0"
@@ -1683,6 +1709,7 @@ dependencies = [
  "clap 3.2.23",
  "ctrlc",
  "cucumber",
+ "distance-oracle",
  "env_logger 0.9.3",
  "hex",
  "notify",
@@ -4206,6 +4233,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf"
 dependencies = [
  "cc",
+ "cmake",
+ "libc",
  "pkg-config",
  "vcpkg",
 ]
@@ -9800,7 +9829,7 @@ version = "1.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
 dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
  "digest 0.10.6",
  "rand 0.8.5",
  "static_assertions",
diff --git a/client/distance/src/lib.rs b/client/distance/src/lib.rs
index 87a973c7c21687c2d0072f1fa7d7f7ae80f12e6d..a89ef6bc14c65818da0e93053163cd35f5cf5556 100644
--- a/client/distance/src/lib.rs
+++ b/client/distance/src/lib.rs
@@ -78,12 +78,9 @@ where
             ),
         )?
         .map_or_else(Default::default, |raw| {
-            pallet_distance::EvaluationPool::<
-                AccountId32,
-                IdtyIndex,
-                ConstU32<100>,
-                ConstU32<100>,
-            >::decode(&mut &raw.0[..])
+            pallet_distance::EvaluationPool::<AccountId32, IdtyIndex, ConstU32<100>, 100>::decode(
+                &mut &raw.0[..],
+            )
             .expect("cannot decode EvaluationPool")
         });
 
diff --git a/distance-oracle/Cargo.toml b/distance-oracle/Cargo.toml
index 8869a5fc6b1901d53eb0bd49904822139890f497..5e561323bed4466dca42e5f292d073a8636b988e 100644
--- a/distance-oracle/Cargo.toml
+++ b/distance-oracle/Cargo.toml
@@ -10,6 +10,7 @@ edition = "2021"
 sp-distance = { path = "../primitives/distance" }
 
 codec = { package = "parity-scale-codec", version = "3.1.5" }
+num-traits = "0.2.15"
 rayon = "1.7.0"
 sp-core = { git = "https://github.com/duniter/substrate.git", branch = "duniter-substrate-v0.9.32" }
 sp-runtime = { git = "https://github.com/duniter/substrate.git", branch = "duniter-substrate-v0.9.32" }
@@ -22,6 +23,13 @@ tokio = { version = "1.15.0", features = [
 	"macros",
 ], optional = true }
 
+[dev-dependencies]
+bincode = "1.3.3"
+dubp-wot = "0.11.1"
+flate2 = { version = "1.0", features = [
+	"zlib-ng-compat",
+], default-features = false }
+
 [features]
 default = ["standalone"]
 standalone = ["clap", "tokio"]
diff --git a/distance-oracle/src/api.rs b/distance-oracle/src/api.rs
new file mode 100644
index 0000000000000000000000000000000000000000..71bf77e7aa08aff93621ec5c98246d0484e6849a
--- /dev/null
+++ b/distance-oracle/src/api.rs
@@ -0,0 +1,113 @@
+use crate::{
+    gdev,
+    gdev::runtime_types::{
+        pallet_distance::median::MedianAcc,
+        sp_arithmetic::per_things::Perbill,
+        sp_core::bounded::{bounded_btree_set::BoundedBTreeSet, bounded_vec::BoundedVec},
+    },
+};
+
+use sp_core::H256;
+
+pub type Client = subxt::OnlineClient<crate::GdevConfig>;
+pub type AccountId = subxt::ext::sp_runtime::AccountId32;
+pub type IdtyIndex = u32;
+pub type EvaluationPool<AccountId, IdtyIndex> = (
+    BoundedVec<(IdtyIndex, MedianAcc<Perbill>)>,
+    BoundedBTreeSet<AccountId>,
+);
+
+pub async fn client(rpc_url: String) -> Client {
+    Client::from_url(rpc_url).await.unwrap()
+}
+
+pub async fn parent_hash(client: &Client) -> H256 {
+    client
+        .storage()
+        .fetch(&gdev::storage().system().parent_hash(), None)
+        .await
+        .unwrap()
+        .unwrap()
+}
+
+pub async fn current_session(client: &Client, parent_hash: H256) -> u32 {
+    client
+        .storage()
+        .fetch(
+            &gdev::storage().session().current_index(),
+            Some(parent_hash),
+        )
+        .await
+        .unwrap()
+        .unwrap_or_default()
+}
+
+pub async fn current_pool(
+    client: &Client,
+    parent_hash: H256,
+    current_session: u32,
+) -> Option<EvaluationPool<AccountId, IdtyIndex>> {
+    client
+        .storage()
+        .fetch(
+            &match current_session % 3 {
+                0 => gdev::storage().distance().evaluation_pool1(),
+                1 => gdev::storage().distance().evaluation_pool2(),
+                2 => gdev::storage().distance().evaluation_pool0(),
+                _ => unreachable!("n%3<3"),
+            },
+            Some(parent_hash),
+        )
+        .await
+        .unwrap()
+}
+
+pub async fn evaluation_block(client: &Client, parent_hash: H256) -> H256 {
+    client
+        .storage()
+        .fetch(
+            &gdev::storage().distance().evaluation_block(),
+            Some(parent_hash),
+        )
+        .await
+        .unwrap()
+        .unwrap()
+}
+
+pub async fn member_iter(
+    client: &Client,
+    evaluation_block: H256,
+) -> subxt::storage::KeyIter<
+    crate::GdevConfig,
+    Client,
+    subxt::metadata::DecodeStaticType<gdev::runtime_types::sp_membership::MembershipData<u32>>,
+> {
+    client
+        .storage()
+        .iter(
+            gdev::storage().membership().membership(0),
+            100,
+            Some(evaluation_block),
+        )
+        .await
+        .unwrap()
+}
+
+pub async fn cert_iter(
+    client: &Client,
+    evaluation_block: H256,
+) -> subxt::storage::KeyIter<
+    crate::GdevConfig,
+    Client,
+    subxt::metadata::DecodeStaticType<Vec<(u32, u32)>>,
+> {
+    client
+        .storage()
+        .iter(
+            gdev::storage().cert().certs_by_receiver(0),
+            100,
+            Some(evaluation_block),
+        )
+        .await
+        .unwrap()
+}
diff --git a/distance-oracle/src/lib.rs b/distance-oracle/src/lib.rs
index 62fc97b5d772ef81d36ce479684702360ec02e22..47418cc941771306158d9146b22cae2a8326c125 100644
--- a/distance-oracle/src/lib.rs
+++ b/distance-oracle/src/lib.rs
@@ -1,39 +1,33 @@
+#[cfg(not(test))]
+mod api;
+#[cfg(test)]
+mod mock;
+#[cfg(test)]
+mod tests;
+
+#[cfg(test)]
+use mock as api;
+
+use api::{AccountId, IdtyIndex};
+
 use codec::Encode;
-use rayon::iter::{IntoParallelIterator, ParallelIterator};
+use rayon::iter::IntoParallelRefIterator;
+use rayon::iter::ParallelIterator;
 use std::collections::{HashMap, HashSet};
 use std::io::Write;
 use std::path::PathBuf;
-use subxt::ext::sp_runtime::Perbill;
 use subxt::storage::StorageKey;
 
-pub struct Settings {
-    pub evaluation_result_dir: PathBuf,
-    pub max_depth: u32,
-    pub rpc_url: String,
-}
-
-impl Default for Settings {
-    fn default() -> Self {
-        Self {
-            evaluation_result_dir: PathBuf::from("/tmp/duniter/chains/gdev/distance"),
-            max_depth: 5,
-            rpc_url: String::from("ws://127.0.0.1:9944"),
-        }
-    }
-}
-
 #[subxt::subxt(runtime_metadata_path = "../resources/metadata.scale")]
 pub mod gdev {}
 
-pub type Client = subxt::OnlineClient<GdevConfig>;
-
 pub enum GdevConfig {}
 impl subxt::config::Config for GdevConfig {
     type Index = u32;
     type BlockNumber = u32;
     type Hash = sp_core::H256;
     type Hashing = subxt::ext::sp_runtime::traits::BlakeTwo256;
-    type AccountId = subxt::ext::sp_runtime::AccountId32;
+    type AccountId = AccountId;
     type Address = subxt::ext::sp_runtime::MultiAddress<Self::AccountId, u32>;
     type Header = subxt::ext::sp_runtime::generic::Header<
         Self::BlockNumber,
@@ -61,86 +55,101 @@ impl From<u64> for Tip {
     }
 }
 
-type IdtyIndex = u32;
+pub struct Settings {
+    pub evaluation_result_dir: PathBuf,
+    pub max_depth: u32,
+    pub rpc_url: String,
+}
+
+impl Default for Settings {
+    fn default() -> Self {
+        Self {
+            evaluation_result_dir: PathBuf::from("/tmp/duniter/chains/gdev/distance"),
+            max_depth: 5,
+            rpc_url: String::from("ws://127.0.0.1:9944"),
+        }
+    }
+}
 
-pub async fn run(settings: Settings) {
-    let client = Client::from_url(settings.rpc_url).await.unwrap();
+pub async fn run_and_save(settings: Settings) {
+    let Some((evaluation, current_session, evaluation_result_path)) = run(&settings, true).await else {return};
 
-    let parent_hash = client
-        .storage()
-        .fetch(&gdev::storage().system().parent_hash(), None)
-        .await
-        .unwrap()
+    let mut evaluation_result_file = std::fs::OpenOptions::new()
+        .write(true)
+        .create_new(true)
+        .open(evaluation_result_path)
         .unwrap();
-
-    let current_session = client
-        .storage()
-        .fetch(
-            &gdev::storage().session().current_index(),
-            Some(parent_hash),
+    evaluation_result_file
+        .write_all(
+            &sp_distance::ComputationResult {
+                distances: evaluation,
+            }
+            .encode(),
         )
-        .await
-        .unwrap()
-        .unwrap_or_default();
+        .unwrap();
+
+    // Remove old results
+    let mut files_to_remove = Vec::new();
+    for entry in settings.evaluation_result_dir.read_dir().unwrap().flatten() {
+        if let Ok(entry_name) = entry.file_name().into_string() {
+            if let Ok(entry_session) = entry_name.parse::<isize>() {
+                if current_session as isize - entry_session > 3 {
+                    files_to_remove.push(entry.path());
+                }
+            }
+        }
+    }
+    files_to_remove.into_iter().for_each(|f| {
+        std::fs::remove_file(&f).unwrap_or_else(move |e| {
+            eprintln!("Warning: Cannot remove old result file `{f:?}`: {e:?}")
+        });
+    });
+}
+
+/// Returns `(evaluation, current_session, evaluation_result_path)`
+pub async fn run(
+    settings: &Settings,
+    handle_fs: bool,
+) -> Option<(Vec<sp_runtime::Perbill>, u32, PathBuf)> {
+    let client = api::client(settings.rpc_url.clone()).await;
+
+    let parent_hash = api::parent_hash(&client).await;
+
+    let current_session = api::current_session(&client, parent_hash).await;
 
     // Fetch the pending identities
-    let Some(evaluation_pool) = client
-        .storage()
-        .fetch(
-            &match current_session % 3 {
-                0 => gdev::storage().distance().evaluation_pool1(),
-                1 => gdev::storage().distance().evaluation_pool2(),
-                2 => gdev::storage().distance().evaluation_pool0(),
-                _ => unreachable!("n%3<3"),
-            },
-            Some(parent_hash),
-        )
-        .await
-        .unwrap() else {
+    let Some(evaluation_pool) = api::current_pool(&client, parent_hash, current_session).await
+         else {
             println!("Pool does not exist");
-            return
+            return None
         };
 
     // Stop if nothing to evaluate
     if evaluation_pool.0 .0.is_empty() {
         println!("Pool is empty");
-        return;
+        return None;
     }
 
     let evaluation_result_path = settings
         .evaluation_result_dir
         .join((current_session + 1).to_string());
 
-    // Stop if already evaluated
-    if evaluation_result_path.try_exists().unwrap() {
-        println!("File already exists");
-        return;
-    }
+    if handle_fs {
+        // Stop if already evaluated
+        if evaluation_result_path.try_exists().unwrap() {
+            println!("File already exists");
+            return None;
+        }
 
-    let evaluation_block = client
-        .storage()
-        .fetch(
-            &gdev::storage().distance().evaluation_block(),
-            Some(parent_hash),
-        )
-        .await
-        .unwrap()
-        .unwrap();
+        std::fs::create_dir_all(&settings.evaluation_result_dir).unwrap();
+    }
 
-    std::fs::create_dir_all(&settings.evaluation_result_dir).unwrap();
+    let evaluation_block = api::evaluation_block(&client, parent_hash).await;
 
     // member idty -> issued certs
     let mut members = HashMap::<IdtyIndex, u32>::new();
 
-    let mut members_iter = client
-        .storage()
-        .iter(
-            gdev::storage().membership().membership(0),
-            100,
-            Some(evaluation_block),
-        )
-        .await
-        .unwrap();
+    let mut members_iter = api::member_iter(&client, evaluation_block).await;
     while let Some((member_idty, _membership_expire)) = members_iter.next().await.unwrap() {
         members.insert(idty_id_from_storage_key(&member_idty), 0);
     }
@@ -152,15 +161,7 @@ pub async fn run(settings: Settings) {
     // idty -> received certs
     let mut received_certs = HashMap::<IdtyIndex, Vec<IdtyIndex>>::new();
 
-    let mut certs_iter = client
-        .storage()
-        .iter(
-            gdev::storage().cert().certs_by_receiver(0),
-            100,
-            Some(evaluation_block),
-        )
-        .await
-        .unwrap();
+    let mut certs_iter = api::cert_iter(&client, evaluation_block).await;
     while let Some((receiver, issuers)) = certs_iter.next().await.unwrap() {
         let receiver = idty_id_from_storage_key(&receiver);
         // Update members' issued certs count
@@ -188,48 +189,20 @@ pub async fn run(settings: Settings) {
     members.retain(|_idty, issued_certs| *issued_certs >= min_certs_for_referee);
     let referees = members;
 
-    let evaluation: Vec<Perbill> = evaluation_pool
+    let evaluation = evaluation_pool
         .0
          .0
-        .into_par_iter()
+        .as_slice()
+        .par_iter()
         .map(|(idty, _)| {
-            Perbill::from_rational(
-                distance_rule(&received_certs, &referees, settings.max_depth, idty),
+            sp_runtime::Perbill::from_rational(
+                distance_rule(&received_certs, &referees, settings.max_depth, *idty),
                 referees.len() as u32,
             )
         })
         .collect();
 
-    let mut evaluation_result_file = std::fs::OpenOptions::new()
-        .write(true)
-        .create_new(true)
-        .open(evaluation_result_path)
-        .unwrap();
-    evaluation_result_file
-        .write_all(
-            &sp_distance::ComputationResult {
-                distances: evaluation,
-            }
-            .encode(),
-        )
-        .unwrap();
-
-    // Remove old results
-    let mut files_to_remove = Vec::new();
-    for entry in settings.evaluation_result_dir.read_dir().unwrap().flatten() {
-        if let Ok(entry_name) = entry.file_name().into_string() {
-            if let Ok(entry_session) = entry_name.parse::<isize>() {
-                if current_session as isize - entry_session > 3 {
-                    files_to_remove.push(entry.path());
-                }
-            }
-        }
-    }
-    files_to_remove.into_iter().for_each(|f| {
-        std::fs::remove_file(&f).unwrap_or_else(move |e| {
-            eprintln!("Warning: Cannot remove old result file `{f:?}`: {e:?}")
-        });
-    });
+    Some((evaluation, current_session, evaluation_result_path))
 }
 
 fn distance_rule_recursive(
@@ -276,3 +249,11 @@ fn distance_rule(
 fn idty_id_from_storage_key(storage_key: &StorageKey) -> IdtyIndex {
     u32::from_le_bytes(storage_key.as_ref()[40..44].try_into().unwrap())
 }
+/*
+impl num_traits::Pow<usize> for Perbill {}
+impl std::ops::Div<Perbill> for Perbill {}
+impl num_traits::Bounded for Perbill {}
+impl Ord for Perbill {}
+impl Eq for Perbill {}
+
+impl PerThing for Perbill {}*/
diff --git a/distance-oracle/src/main.rs b/distance-oracle/src/main.rs
index af83eb398eec59a18f9ec49d6ebc1c80d3f31913..5d25f621b95cd49673016f73d80952ff08a22e42 100644
--- a/distance-oracle/src/main.rs
+++ b/distance-oracle/src/main.rs
@@ -15,7 +15,7 @@ struct Cli {
 async fn main() {
     let cli = Cli::parse();
 
-    distance_oracle::run(distance_oracle::Settings {
+    distance_oracle::run_and_save(distance_oracle::Settings {
         evaluation_result_dir: cli.evaluation_result_dir.into(),
         max_depth: cli.max_depth,
         rpc_url: cli.rpc_url,
diff --git a/distance-oracle/src/mock.rs b/distance-oracle/src/mock.rs
new file mode 100644
index 0000000000000000000000000000000000000000..faf20d0ef41b73e271c7c76606fae04282069754
--- /dev/null
+++ b/distance-oracle/src/mock.rs
@@ -0,0 +1,65 @@
+use crate::gdev::runtime_types::{
+    pallet_distance::median::MedianAcc, sp_arithmetic::per_things::Perbill,
+};
+
+use sp_core::H256;
+use std::collections::BTreeSet;
+
+pub struct Client;
+pub type AccountId = subxt::ext::sp_runtime::AccountId32;
+pub type IdtyIndex = u32;
+pub type EvaluationPool<AccountId, IdtyIndex> =
+    ((Vec<(IdtyIndex, MedianAcc<Perbill>)>,), BTreeSet<AccountId>);
+
+pub async fn client(_rpc_url: String) -> Client {
+    Client
+}
+
+pub async fn parent_hash(_client: &Client) -> H256 {
+    Default::default()
+}
+
+pub async fn current_session(_client: &Client, _parent_hash: H256) -> u32 {
+    0
+}
+
+pub async fn current_pool(
+    _client: &Client,
+    _parent_hash: H256,
+    _current_session: u32,
+) -> Option<EvaluationPool<AccountId, IdtyIndex>> {
+    Some(((vec![],), std::collections::BTreeSet::new()))
+}
+
+pub async fn evaluation_block(_client: &Client, _parent_hash: H256) -> H256 {
+    Default::default()
+}
+
+pub async fn member_iter(
+    _client: &Client,
+    _evaluation_block: H256,
+) -> KeyIter<(subxt::storage::StorageKey, ())> {
+    KeyIter::new(Vec::new())
+}
+
+pub async fn cert_iter(
+    _client: &Client,
+    _evaluation_block: H256,
+) -> KeyIter<(subxt::storage::StorageKey, Vec<(u32, u32)>)> {
+    KeyIter::new(Vec::new())
+}
+
+pub struct KeyIter<T>(std::vec::IntoIter<T>);
+
+impl<T> KeyIter<T> {
+    fn new(items: Vec<T>) -> Self {
+        Self(items.into_iter())
+    }
+
+    pub async fn next(&mut self) -> Result<Option<T>, subxt::error::Error>
+    where
+        T: Clone,
+    {
+        Ok(self.0.next())
+    }
+}
diff --git a/distance-oracle/src/tests.rs b/distance-oracle/src/tests.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4c3f90fbe616d0483a3b4e7d266ce850332880b3
--- /dev/null
+++ b/distance-oracle/src/tests.rs
@@ -0,0 +1,20 @@
+use dubp_wot::data::rusty::RustyWebOfTrust;
+use flate2::read::ZlibDecoder;
+use std::{fs::File, io::Read};
+
+#[tokio::test]
+async fn test_distance_against_v1() {
+    let _wot = wot_from_v1_file();
+
+    crate::run(&Default::default(), false).await;
+}
+
+fn wot_from_v1_file() -> RustyWebOfTrust {
+    let file = File::open("wot.deflate").expect("Cannot open wot.deflate");
+    let mut decompressor = ZlibDecoder::new(file);
+    let mut decompressed_bytes = Vec::new();
+    decompressor
+        .read_to_end(&mut decompressed_bytes)
+        .expect("Cannot decompress wot.deflate");
+    bincode::deserialize::<RustyWebOfTrust>(&decompressed_bytes).expect("Cannot decode wot.deflate")
+}
diff --git a/distance-oracle/wot.deflate b/distance-oracle/wot.deflate
new file mode 100644
index 0000000000000000000000000000000000000000..087c09cfc125ee954a63b79d04e4013630b4c4f5
Binary files /dev/null and b/distance-oracle/wot.deflate differ
diff --git a/end2end-tests/Cargo.toml b/end2end-tests/Cargo.toml
index 07df18c1aa1878428fd2c5c9b1b655df405ea810..95e15c04acbbcdfd5179b8b5e1a7ecab6e6cc9a4 100644
--- a/end2end-tests/Cargo.toml
+++ b/end2end-tests/Cargo.toml
@@ -14,6 +14,7 @@ async-trait = "0.1"
 clap = { version = "3.2.23", features = ["derive"] }
 ctrlc = "3.2.2"
 cucumber = "0.11"
+distance-oracle = { path = "../distance-oracle", default_features = false }
 env_logger = "0.9.0"
 hex = "0.4"
 notify = "4.0"
@@ -26,4 +27,4 @@ tokio = { version = "1.15.0", features = ["macros"] }
 
 [[test]]
 name = "cucumber_tests"
-harness = false  # allows Cucumber to print output instead of libtest
+harness = false         # allows Cucumber to print output instead of libtest
diff --git a/end2end-tests/cucumber-features/distance.feature b/end2end-tests/cucumber-features/distance.feature
deleted file mode 100644
index 9cc18d514ce91ef7d296edfbcb3cab0520b4691c..0000000000000000000000000000000000000000
--- a/end2end-tests/cucumber-features/distance.feature
+++ /dev/null
@@ -1,24 +0,0 @@
-Feature: Distance
-
-    Scenario: Alice certifies Eve
-        When alice sends 6 ĞD to dave
-        When 15 blocks later
-        When alice creates identity for dave
-        Then dave identity should be created
-        Then dave should be certified by alice
-        When dave confirms his identity with pseudo "dave"
-        Then dave identity should be confirmed
-        When bob certifies dave
-        Then dave should be certified by bob
-        When alice requests distance evaluation for dave
-        Then dave should have distance result in 2 sessions
-        When 30 blocks later
-        Then dave should have distance result in 1 session
-        When distance oracle runs
-        Then dave should have distance result in 1 session
-        When 30 blocks later
-        Then dave should have distance result in 0 session
-        Then dave should have distance ok
-        When alice validates dave identity
-        When 3 blocks later
-        Then dave identity should be validated
diff --git a/end2end-tests/cucumber-features/identity_creation.feature b/end2end-tests/cucumber-features/identity_creation.feature
index 81113d8b1549154e6f3ca5e91691ff137691a18b..56a7404dffbd9390f1560fb547259c540fcfaa1a 100644
--- a/end2end-tests/cucumber-features/identity_creation.feature
+++ b/end2end-tests/cucumber-features/identity_creation.feature
@@ -5,8 +5,9 @@ Feature: Identity creation
     # - account creation fees (3 ĞD) 
     # - existential deposit (2 ĞD)
     # - transaction fees (below 1 ĞD)
-    When alice sends 6 ĞD to dave
-    When bob sends 6 ĞD to eve
+    When alice sends 7 ĞD to dave
+    When bob sends 750 cĞD to dave
+    When charlie sends 6 ĞD to eve
     # alice last certification is counted from block zero
     # then next cert can be done after cert_period, which is 15
     When 15 block later
@@ -20,6 +21,12 @@ Feature: Identity creation
     When charlie certifies dave
     Then dave should be certified by bob
     Then dave should be certified by charlie
-    When 3 block later
+    When dave requests distance evaluation
+    Then dave should have distance result in 2 sessions
+    When 30 blocks later
+    Then dave should have distance result in 1 session
+    When alice runs distance oracle
+    When 30 blocks later
+    Then dave should have distance ok
     When eve validates dave identity
     Then dave identity should be validated
diff --git a/end2end-tests/tests/common/distance.rs b/end2end-tests/tests/common/distance.rs
index 6c792700d3140c150fbdb218b2aeb93282bc0cac..15f9d61cee4bd9c4f94aa8f7b3750a70e1abb9b5 100644
--- a/end2end-tests/tests/common/distance.rs
+++ b/end2end-tests/tests/common/distance.rs
@@ -19,18 +19,19 @@ use super::gdev::runtime_types::pallet_identity;
 use super::*;
 use crate::DuniterWorld;
 use sp_keyring::AccountKeyring;
-use subxt::tx::PairSigner;
+use subxt::ext::sp_runtime::AccountId32;
+use subxt::tx::{PairSigner, Signer};
 
-pub async fn request_evaluation(client: &Client, from: AccountKeyring, to: u32) -> Result<()> {
-    let from = PairSigner::new(from.pair());
+pub async fn request_evaluation(client: &Client, origin: AccountKeyring) -> Result<()> {
+    let origin = PairSigner::new(origin.pair());
 
     let _events = create_block_with_extrinsic(
         client,
         client
             .tx()
             .create_signed(
-                &gdev::tx().distance().evaluate_distance(to),
-                &from,
+                &gdev::tx().distance().evaluate_distance(),
+                &origin,
                 BaseExtrinsicParamsBuilder::new(),
             )
             .await?,
@@ -39,3 +40,52 @@ pub async fn request_evaluation(client: &Client, from: AccountKeyring, to: u32)
 
     Ok(())
 }
+
+pub async fn run_oracle(client: &Client, origin: AccountKeyring, rpc_url: String) -> Result<()> {
+    let origin = PairSigner::new(origin.pair());
+    let account_id: &AccountId32 = origin.account_id();
+
+    if let Some((distances, _current_session, _evaluation_result_path)) = distance_oracle::run(
+        &distance_oracle::Settings {
+            evaluation_result_dir: PathBuf::default(),
+            max_depth: 5,
+            rpc_url,
+        },
+        false,
+    )
+    .await
+    {
+        for _ in 0..30 {
+            super::create_empty_block(client).await?;
+        }
+
+        let _events = create_block_with_extrinsic(
+            client,
+            client
+                .tx()
+                .create_signed(
+                    &gdev::tx().sudo().sudo(/*gdev::runtime_types::gdev_runtime::RuntimeCall::UpgradeOrigin(gdev::runtime_types::pallet_upgrade_origin::pallet::Call::dispatch_as_root {
+                        call: Box::new(*/gdev::runtime_types::gdev_runtime::RuntimeCall::Distance(
+                            gdev::runtime_types::pallet_distance::pallet::Call::force_update_evaluation {
+                                evaluator: account_id.clone(),
+                                computation_result:
+                                    gdev::runtime_types::sp_distance::ComputationResult {
+                                        distances: unsafe {
+                                            std::mem::transmute(distances)
+                                        },
+                                    },
+                            },
+                        )/*)
+                    })*/),
+                    //&gdev::tx().upgrade_origin().dispatch_as_root(
+                    //),
+                    &origin,
+                    BaseExtrinsicParamsBuilder::new(),
+                )
+                .await?,
+        )
+        .await?;
+    }
+
+    Ok(())
+}
diff --git a/end2end-tests/tests/common/identity.rs b/end2end-tests/tests/common/identity.rs
index 58e881264a4daed837fdc4bc0a039e3f2428f27c..735e655fd66fa8d55bb74e709a7d0fc5946e245a 100644
--- a/end2end-tests/tests/common/identity.rs
+++ b/end2end-tests/tests/common/identity.rs
@@ -84,9 +84,11 @@ pub async fn validate_identity(client: &Client, from: AccountKeyring, to: u32) -
                 &from,
                 BaseExtrinsicParamsBuilder::new(),
             )
-            .await?,
+            .await
+            .unwrap(),
     )
-    .await?;
+    .await
+    .unwrap();
 
     Ok(())
 }
diff --git a/end2end-tests/tests/cucumber_tests.rs b/end2end-tests/tests/cucumber_tests.rs
index 8ac684502e3ad1bd0114dc2f4cec4582d7a3b60d..1712389a72c462c85d6dfc3e4f8ce6060fee758d 100644
--- a/end2end-tests/tests/cucumber_tests.rs
+++ b/end2end-tests/tests/cucumber_tests.rs
@@ -322,31 +322,30 @@ async fn confirm_identity(world: &mut DuniterWorld, from: String, pseudo: String
 async fn validate_identity(world: &mut DuniterWorld, from: String, to: String) -> Result<()> {
     // input names to keyrings
     let from = AccountKeyring::from_str(&from).expect("unknown from");
-    let to: u32 = common::identity::get_identity_index(world, to).await?;
+    let to: u32 = common::identity::get_identity_index(world, to)
+        .await
+        .unwrap();
 
     common::identity::validate_identity(world.client(), from, to).await
 }
 
-#[when(regex = r#"([a-zA-Z]+) requests distance evaluation for ([a-zA-Z]+)"#)]
-async fn request_distance_evaluation(
-    world: &mut DuniterWorld,
-    from: String,
-    to: String,
-) -> Result<()> {
-    // input names to keyrings
-    let from = AccountKeyring::from_str(&from).expect("unknown from");
-    let to: u32 = common::identity::get_identity_index(world, to).await?;
+#[when(regex = r#"([a-zA-Z]+) requests distance evaluation"#)]
+async fn request_distance_evaluation(world: &mut DuniterWorld, who: String) -> Result<()> {
+    let who = AccountKeyring::from_str(&who).expect("unknown origin");
 
-    common::distance::request_evaluation(world.client(), from, to).await
+    common::distance::request_evaluation(world.client(), who).await
 }
 
-#[when(regex = r#"distance oracle runs"#)]
-async fn run_distance_oracle(world: &mut DuniterWorld) -> Result<()> {
-    common::spawn_distance_oracle(
-        common::DISTANCE_ORACLE_LOCAL_PATH,
-        world.inner.as_ref().unwrap().ws_port,
-    );
-    Ok(())
+#[when(regex = r#"([a-zA-Z]+) runs distance oracle"#)]
+async fn run_distance_oracle(world: &mut DuniterWorld, who: String) -> Result<()> {
+    let who = AccountKeyring::from_str(&who).expect("unknown origin");
+
+    common::distance::run_oracle(
+        world.client(),
+        who,
+        format!("ws://127.0.0.1:{}", world.inner.as_ref().unwrap().ws_port),
+    )
+    .await
 }
 
 // ===== then ====
@@ -513,14 +512,19 @@ async fn should_have_distance_ok(world: &mut DuniterWorld, who: String) -> Resul
         .await?
         .unwrap();
 
-    if world
-        .read(&gdev::storage().distance().distance_ok_identities(idty_id))
+    match world
+        .read(
+            &gdev::storage()
+                .distance()
+                .identities_distance_status(idty_id),
+        )
         .await?
-        .unwrap()
     {
-        Ok(())
-    } else {
-        Err(anyhow::anyhow!("no evaluation in given pool").into())
+        Some(gdev::runtime_types::pallet_distance::types::DistanceStatus::Valid) => Ok(()),
+        Some(gdev::runtime_types::pallet_distance::types::DistanceStatus::Pending) => {
+            Err(anyhow::anyhow!("pending distance status").into())
+        }
+        None => Err(anyhow::anyhow!("no distance status").into()),
     }
 }
 
diff --git a/pallets/distance/src/lib.rs b/pallets/distance/src/lib.rs
index cce777e7d6d3e43a76b6135c2534774ab1497c9c..1779011ef308f9e6db346509122d95e486c8d9d6 100644
--- a/pallets/distance/src/lib.rs
+++ b/pallets/distance/src/lib.rs
@@ -20,12 +20,12 @@ mod median;
 mod traits;
 mod types;
 
-use median::*;
 pub use pallet::*;
 pub use traits::*;
 pub use types::*;
 
 use frame_support::traits::StorageVersion;
+//use median_accumulator::*;
 use pallet_authority_members::SessionIndex;
 use sp_distance::{InherentError, INHERENT_IDENTIFIER};
 use sp_inherents::{InherentData, InherentIdentifier};
@@ -36,7 +36,7 @@ type IdtyIndex = u32;
 #[frame_support::pallet]
 pub mod pallet {
     use super::*;
-    use frame_support::{pallet_prelude::*, traits::ReservableCurrency, BoundedBTreeSet};
+    use frame_support::{pallet_prelude::*, traits::ReservableCurrency};
     use frame_system::pallet_prelude::*;
     use sp_runtime::Perbill;
 
@@ -65,6 +65,7 @@ pub mod pallet {
         /// Maximum number of identities to be evaluated in a session
         type MaxEvaluationsPerSession: Get<u32>;
         /// Maximum number of evaluators in a session
+        #[pallet::constant]
         type MaxEvaluatorsPerSession: Get<u32>;
         /// Minimum ratio of accessible referees
         type MinAccessibleReferees: Get<Perbill>;
@@ -74,46 +75,39 @@ pub mod pallet {
 
     // STORAGE //
 
-    pub type EvaluationPool<
-        AccountId,
-        IdtyIndex,
-        MaxEvaluationsPerSession,
-        MaxEvaluatorsPerSession,
-    > = (
-        BoundedVec<(IdtyIndex, MedianAcc<Perbill>), MaxEvaluationsPerSession>,
-        BoundedBTreeSet<AccountId, MaxEvaluatorsPerSession>,
-    );
-
     #[pallet::storage]
+    #[pallet::getter(fn evaluation_pool_0)]
     pub type EvaluationPool0<T: Config<I>, I: 'static = ()> = StorageValue<
         _,
         EvaluationPool<
             <T as frame_system::Config>::AccountId,
             <T as pallet_certification::Config<I>>::IdtyIndex,
             <T as Config<I>>::MaxEvaluationsPerSession,
-            <T as Config<I>>::MaxEvaluatorsPerSession,
+            100, //<T as Config<I>>::MaxEvaluatorsPerSession,
         >,
         ValueQuery,
     >;
     #[pallet::storage]
+    #[pallet::getter(fn evaluation_pool_1)]
     pub type EvaluationPool1<T: Config<I>, I: 'static = ()> = StorageValue<
         _,
         EvaluationPool<
             <T as frame_system::Config>::AccountId,
             <T as pallet_certification::Config<I>>::IdtyIndex,
             <T as Config<I>>::MaxEvaluationsPerSession,
-            <T as Config<I>>::MaxEvaluatorsPerSession,
+            100, //<T as Config<I>>::MaxEvaluatorsPerSession,
         >,
         ValueQuery,
     >;
     #[pallet::storage]
+    #[pallet::getter(fn evaluation_pool_2)]
     pub type EvaluationPool2<T: Config<I>, I: 'static = ()> = StorageValue<
         _,
         EvaluationPool<
             <T as frame_system::Config>::AccountId,
             <T as pallet_certification::Config<I>>::IdtyIndex,
             <T as Config<I>>::MaxEvaluationsPerSession,
-            <T as Config<I>>::MaxEvaluatorsPerSession,
+            100, //<T as Config<I>>::MaxEvaluatorsPerSession,
         >,
         ValueQuery,
     >;
@@ -209,66 +203,24 @@ pub mod pallet {
                 !DidUpdate::<T, I>::exists(),
                 Error::<T, I>::ManyEvaluationsInBlock,
             );
+            let author = pallet_authorship::Pallet::<T>::author().ok_or(Error::<T, I>::NoAuthor)?;
 
-            Pallet::<T, I>::mutate_current_pool(
-                pallet_session::CurrentIndex::<T>::get().wrapping_add(1),
-                |result_pool| {
-                    ensure!(
-                        computation_result.distances.len() == result_pool.0.len(),
-                        Error::<T, I>::WrongResultLength
-                    );
-
-                    let author =
-                        pallet_authorship::Pallet::<T>::author().ok_or(Error::<T, I>::NoAuthor)?;
-
-                    if result_pool
-                        .1
-                        .try_insert(author)
-                        .map_err(|_| Error::<T, I>::TooManyEvaluators)?
-                    {
-                        for (distance_value, (_identity, median_acc)) in computation_result
-                            .distances
-                            .into_iter()
-                            .zip(result_pool.0.iter_mut())
-                        {
-                            median_acc.push(distance_value);
-                        }
+            Pallet::<T, I>::do_update_evaluation(author, computation_result)?;
 
-                        Ok(())
-                    } else {
-                        Err(Error::<T, I>::ManyEvaluationsByAuthor.into())
-                    }
-                },
-            )
+            DidUpdate::<T, I>::set(true);
+            Ok(())
         }
-    }
-
-    // PUBLIC FUNCTIONS //
-
-    impl<T: Config<I>, I: 'static> Pallet<T, I> {
-        pub fn do_evaluate_distance(
-            who: T::AccountId,
-            idty_index: <T as pallet_certification::Config<I>>::IdtyIndex,
-        ) -> Result<(), DispatchError> {
-            Pallet::<T, I>::mutate_current_pool(
-                pallet_session::CurrentIndex::<T>::get(),
-                |current_pool| {
-                    ensure!(
-                        current_pool.0.len()
-                            < (<T as Config<I>>::MaxEvaluationsPerSession::get() as usize),
-                        Error::<T, I>::QueueFull
-                    );
-
-                    T::Currency::reserve(&who, <T as Config<I>>::EvaluationPrice::get())?;
 
-                    current_pool
-                        .0
-                        .try_push((idty_index, median::MedianAcc::new()))
-                        .map_err(|_| Error::<T, I>::QueueFull)?;
+        /// Push an evaluation result to the pool
+        #[pallet::weight(1_000_000_000)]
+        pub fn force_update_evaluation(
+            origin: OriginFor<T>,
+            evaluator: <T as frame_system::Config>::AccountId,
+            computation_result: ComputationResult,
+        ) -> DispatchResult {
+            ensure_root(origin)?;
 
-                    Ok(())
-                },
-            )
+            Pallet::<T, I>::do_update_evaluation(evaluator, computation_result)
         }
     }
 
@@ -283,7 +235,7 @@ pub mod pallet {
                     <T as frame_system::Config>::AccountId,
                     <T as pallet_certification::Config<I>>::IdtyIndex,
                     <T as Config<I>>::MaxEvaluationsPerSession,
-                    <T as Config<I>>::MaxEvaluatorsPerSession,
+                    100, //<T as Config<I>>::MaxEvaluatorsPerSession,
                 >,
             ) -> R,
         >(
@@ -294,7 +246,7 @@ pub mod pallet {
                 0 => EvaluationPool2::<T, I>::mutate(f),
                 1 => EvaluationPool0::<T, I>::mutate(f),
                 2 => EvaluationPool1::<T, I>::mutate(f),
-                _ => panic!("index % 3 < 3"),
+                _ => unreachable!("index % 3 < 3"),
             }
         }
 
@@ -306,15 +258,75 @@ pub mod pallet {
             <T as frame_system::Config>::AccountId,
             <T as pallet_certification::Config<I>>::IdtyIndex,
             <T as Config<I>>::MaxEvaluationsPerSession,
-            <T as Config<I>>::MaxEvaluatorsPerSession,
+            100, //<T as Config<I>>::MaxEvaluatorsPerSession,
         > {
             match index % 3 {
                 0 => EvaluationPool2::<T, I>::take(),
                 1 => EvaluationPool0::<T, I>::take(),
                 2 => EvaluationPool1::<T, I>::take(),
-                _ => panic!("index % 3 < 3"),
+                _ => unreachable!("index % 3 < 3"),
             }
         }
+
+        fn do_evaluate_distance(
+            who: T::AccountId,
+            idty_index: <T as pallet_certification::Config<I>>::IdtyIndex,
+        ) -> Result<(), DispatchError> {
+            Pallet::<T, I>::mutate_current_pool(
+                pallet_session::CurrentIndex::<T>::get(),
+                |current_pool| {
+                    ensure!(
+                        current_pool.0.len()
+                            < (<T as Config<I>>::MaxEvaluationsPerSession::get() as usize),
+                        Error::<T, I>::QueueFull
+                    );
+
+                    T::Currency::reserve(&who, <T as Config<I>>::EvaluationPrice::get())?;
+
+                    current_pool
+                        .0
+                        .try_push((idty_index, median::MedianAcc::new()))
+                        .map_err(|_| Error::<T, I>::QueueFull)?;
+
+                    IdentitiesDistanceStatus::<T, I>::insert(idty_index, DistanceStatus::Pending);
+
+                    Ok(())
+                },
+            )
+        }
+
+        fn do_update_evaluation(
+            evaluator: <T as frame_system::Config>::AccountId,
+            computation_result: ComputationResult,
+        ) -> DispatchResult {
+            Pallet::<T, I>::mutate_current_pool(
+                pallet_session::CurrentIndex::<T>::get().wrapping_add(1),
+                |result_pool| {
+                    ensure!(
+                        computation_result.distances.len() == result_pool.0.len(),
+                        Error::<T, I>::WrongResultLength
+                    );
+
+                    if result_pool
+                        .1
+                        .try_insert(evaluator)
+                        .map_err(|_| Error::<T, I>::TooManyEvaluators)?
+                    {
+                        for (distance_value, (_identity, median_acc)) in computation_result
+                            .distances
+                            .into_iter()
+                            .zip(result_pool.0.iter_mut())
+                        {
+                            median_acc.push(distance_value);
+                        }
+
+                        Ok(())
+                    } else {
+                        Err(Error::<T, I>::ManyEvaluationsByAuthor.into())
+                    }
+                },
+            )
+        }
     }
 
     impl<T: Config<I>, I: 'static> pallet_authority_members::OnNewSession for Pallet<T, I> {
@@ -328,7 +340,7 @@ pub mod pallet {
                 <T as frame_system::Config>::AccountId,
                 <T as pallet_certification::Config<I>>::IdtyIndex,
                 <T as Config<I>>::MaxEvaluationsPerSession,
-                <T as Config<I>>::MaxEvaluatorsPerSession,
+                100, //<T as Config<I>>::MaxEvaluatorsPerSession,
             > = Pallet::<T, I>::take_current_pool(index);
             for (idty, median_acc) in current_pool.0.into_iter() {
                 let Some(idty_value) =
@@ -340,7 +352,9 @@ pub mod pallet {
                         MedianResult::Two(m1, m2) => m1 + (m2 - m1) / 2, // Avoid overflow (since max is 1)
                     };
                     if median >= T::MinAccessibleReferees::get() {
-                        IdentitiesDistanceStatus::<T, I>::insert(idty, DistanceStatus::Valid);
+                        IdentitiesDistanceStatus::<T, I>::mutate(idty, |status| {
+                            *status = Some(DistanceStatus::Valid)
+                        });
                         T::Currency::unreserve(
                             &account_id,
                             <T as Config<I>>::EvaluationPrice::get(),
diff --git a/pallets/distance/src/median.rs b/pallets/distance/src/median.rs
index 065efb3119377cea4906e86c45e176f56f1b1941..feab0d863176a4d24e33b85856717346a1ec29a7 100644
--- a/pallets/distance/src/median.rs
+++ b/pallets/distance/src/median.rs
@@ -15,25 +15,38 @@
 // along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>.
 
 use frame_support::pallet_prelude::*;
-use sp_std::{cmp::Ordering, vec::Vec};
+use sp_std::cmp::Ordering;
 
 #[derive(Clone, Debug, Decode, Default, Encode, TypeInfo)]
-pub struct MedianAcc<T: Clone + Decode + Encode + Ord + TypeInfo> {
-    samples: Vec<(T, u32)>,
+pub struct MedianAcc<
+    T: Clone + Decode + Encode + Ord + TypeInfo,
+    const S: u32, /*Get<u32> + TypeInfo*/
+> {
+    samples: BoundedVec<(T, u32), ConstU32<S>>,
     median_index: Option<u32>,
     median_subindex: u32,
 }
 
+/*impl<T: 'static + Clone + Decode + Encode + Ord + TypeInfo, S: 'static + Get<u32>> TypeInfo
+    for MedianAcc<T, S>
+{
+    type Identity = Self;
+
+    fn type_info() -> scale_info::Type<scale_info::form::MetaForm> {}
+}*/
+
 #[derive(Clone, Debug, Eq, PartialEq)]
 pub enum MedianResult<T: Clone + Ord> {
     One(T),
     Two(T, T),
 }
 
-impl<T: Clone + Decode + Encode + Ord + TypeInfo> MedianAcc<T> {
+impl<T: Clone + Decode + Encode + Ord + TypeInfo, const S: u32 /*Get<u32> + TypeInfo*/>
+    MedianAcc<T, S>
+{
     pub fn new() -> Self {
         Self {
-            samples: Vec::new(),
+            samples: BoundedVec::default(),
             median_index: None,
             median_subindex: 0,
         }
@@ -84,7 +97,7 @@ impl<T: Clone + Decode + Encode + Ord + TypeInfo> MedianAcc<T> {
                     }
                 }
                 Err(sample_index) => {
-                    self.samples.insert(sample_index, (sample, 1));
+                    self.samples.try_insert(sample_index, (sample, 1)).ok();
                     if *median_index as usize >= sample_index {
                         if self.median_subindex == 0 {
                             self.median_subindex = self
@@ -115,7 +128,7 @@ impl<T: Clone + Decode + Encode + Ord + TypeInfo> MedianAcc<T> {
                 }
             }
         } else {
-            self.samples.push((sample, 1));
+            self.samples.try_push((sample, 1)).ok();
             self.median_index = Some(0);
         }
     }
diff --git a/pallets/distance/src/types.rs b/pallets/distance/src/types.rs
index 2d3edf946f670bc274f11519046e2a32fb3ea6ea..f5f6589b350b3bdbed34edf9540e54281eac2b2f 100644
--- a/pallets/distance/src/types.rs
+++ b/pallets/distance/src/types.rs
@@ -14,10 +14,12 @@
 // You should have received a copy of the GNU Affero General Public License
 // along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>.
 
+pub use crate::median::*;
 pub use sp_distance::ComputationResult;
 
 use codec::{Decode, Encode};
-use frame_support::pallet_prelude::*;
+use frame_support::{pallet_prelude::*, BoundedBTreeSet};
+use sp_runtime::Perbill;
 
 #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
 pub enum DistanceStatus {
@@ -26,3 +28,16 @@ pub enum DistanceStatus {
     /// Identity respects the distance
     Valid,
 }
+
+pub type EvaluationPool<
+    AccountId,
+    IdtyIndex,
+    MaxEvaluationsPerSession,
+    const MAX_EVALUATORS_PER_SESSION: u32,
+> = (
+    BoundedVec<
+        (IdtyIndex, MedianAcc<Perbill, MAX_EVALUATORS_PER_SESSION>),
+        MaxEvaluationsPerSession,
+    >,
+    BoundedBTreeSet<AccountId, ConstU32<MAX_EVALUATORS_PER_SESSION>>,
+);
diff --git a/resources/metadata.scale b/resources/metadata.scale
index c5d992edbe02769551ed0a8ba738d79232bccfbe..9582cd2af48d15f0121380317bb240fe5e4527a7 100644
Binary files a/resources/metadata.scale and b/resources/metadata.scale differ