Skip to main content

openrank_common/runners/
mod.rs

1use crate::{
2    merkle::{self, hash_leaf, hash_two, incremental::DenseIncrementalMerkleTree, Hash},
3    tx::trust::{OwnedNamespace, ScoreEntry, TrustEntry},
4    Domain, DomainHash,
5};
6use getset::Getters;
7use serde::{Deserialize, Serialize};
8use sha3::Keccak256;
9use std::collections::BTreeMap;
10use std::collections::HashMap;
11use tracing::info;
12
13pub mod compute_runner;
14pub mod verification_runner;
15
16/// Local trust object.
17///
18/// The local trust object stores the trust values that a node assigns to its
19/// peers.
20///
21/// It also stores the sum of the trust values assigned to all peers.
22#[derive(Debug, Clone, Serialize, Deserialize, Getters)]
23#[getset(get = "pub")]
24pub struct OutboundLocalTrust {
25    /// The trust values that a node assigns to its peers.
26    ///
27    /// The `outbound_trust_scores` vector stores the trust values that a node
28    /// assigns to its peers. The trust values are represented as a vector of
29    /// floats, where each element in the vector corresponds to the trust value
30    /// assigned to a particular peer.
31    outbound_trust_scores: BTreeMap<u64, f32>,
32    /// The sum of the trust values assigned to all peers.
33    ///
34    /// The `outbound_sum` value stores the sum of the trust values assigned to
35    /// all peers. The sum is used to normalize the trust values such that they
36    /// add up to 1.
37    outbound_sum: f32,
38}
39
40impl Default for OutboundLocalTrust {
41    fn default() -> Self {
42        Self::new()
43    }
44}
45
46impl OutboundLocalTrust {
47    pub fn new() -> Self {
48        Self {
49            outbound_trust_scores: BTreeMap::new(),
50            outbound_sum: 0.0,
51        }
52    }
53
54    pub fn set_outbound_trust_scores(&mut self, outbound_trust_scores: BTreeMap<u64, f32>) {
55        self.outbound_trust_scores = outbound_trust_scores;
56        self.outbound_sum = self.outbound_trust_scores.values().sum();
57    }
58
59    pub fn from_score_map(score_map: &BTreeMap<u64, f32>) -> Self {
60        let outbound_trust_scores = score_map.clone();
61        let outbound_sum = outbound_trust_scores.values().sum();
62        Self {
63            outbound_trust_scores,
64            outbound_sum,
65        }
66    }
67
68    pub fn norm(&self) -> Self {
69        let mut outbound_trust_scores = self.outbound_trust_scores.clone();
70        for (_, score) in outbound_trust_scores.iter_mut() {
71            *score /= self.outbound_sum;
72        }
73        let outbound_sum = 1.0;
74        OutboundLocalTrust {
75            outbound_trust_scores,
76            outbound_sum,
77        }
78    }
79
80    /*----------------- BTreeMap similar utils -----------------*/
81    pub fn get(&self, peer_id: &u64) -> Option<f32> {
82        self.outbound_trust_scores.get(peer_id).copied()
83    }
84
85    pub fn contains_key(&self, peer_id: &u64) -> bool {
86        self.outbound_trust_scores.contains_key(peer_id)
87    }
88
89    pub fn remove(&mut self, peer_id: &u64) {
90        let to_be_removed = self
91            .outbound_trust_scores
92            .get(peer_id)
93            .copied()
94            .unwrap_or(0.0);
95        self.outbound_sum -= to_be_removed;
96        self.outbound_trust_scores.remove(peer_id);
97    }
98
99    pub fn insert(&mut self, peer_id: u64, value: f32) {
100        let prev_value = self
101            .outbound_trust_scores
102            .get(&peer_id)
103            .copied()
104            .unwrap_or(0.0);
105        self.outbound_sum -= prev_value;
106        self.outbound_sum += value;
107        self.outbound_trust_scores.insert(peer_id, value);
108    }
109}
110
111#[derive(Getters)]
112#[getset(get = "pub")]
113pub struct BaseRunner {
114    count: HashMap<DomainHash, u64>,
115    indices: HashMap<DomainHash, HashMap<String, u64>>,
116    rev_indices: HashMap<DomainHash, HashMap<u64, String>>,
117    local_trust: HashMap<OwnedNamespace, BTreeMap<u64, OutboundLocalTrust>>,
118    seed_trust: HashMap<OwnedNamespace, BTreeMap<u64, f32>>,
119    lt_sub_trees: HashMap<DomainHash, HashMap<u64, DenseIncrementalMerkleTree<Keccak256>>>,
120    lt_master_tree: HashMap<DomainHash, DenseIncrementalMerkleTree<Keccak256>>,
121    st_master_tree: HashMap<DomainHash, DenseIncrementalMerkleTree<Keccak256>>,
122}
123
124impl BaseRunner {
125    pub fn new(domains: &[Domain]) -> Self {
126        let mut count = HashMap::new();
127        let mut indices = HashMap::new();
128        let mut rev_indices = HashMap::new();
129        let mut local_trust = HashMap::new();
130        let mut seed_trust = HashMap::new();
131        let mut lt_sub_trees = HashMap::new();
132        let mut lt_master_tree = HashMap::new();
133        let mut st_master_tree = HashMap::new();
134        let mut compute_results = HashMap::new();
135        for domain in domains {
136            let domain_hash = domain.to_hash();
137            count.insert(domain_hash, 0);
138            indices.insert(domain_hash, HashMap::new());
139            rev_indices.insert(domain_hash, HashMap::new());
140            local_trust.insert(domain.trust_namespace(), BTreeMap::new());
141            seed_trust.insert(domain.trust_namespace(), BTreeMap::new());
142            lt_sub_trees.insert(domain_hash, HashMap::new());
143            lt_master_tree.insert(
144                domain_hash,
145                DenseIncrementalMerkleTree::<Keccak256>::new(32),
146            );
147            st_master_tree.insert(
148                domain_hash,
149                DenseIncrementalMerkleTree::<Keccak256>::new(32),
150            );
151            compute_results.insert(domain_hash, Vec::<f32>::new());
152        }
153        Self {
154            count,
155            indices,
156            rev_indices,
157            local_trust,
158            seed_trust,
159            lt_sub_trees,
160            lt_master_tree,
161            st_master_tree,
162        }
163    }
164
165    pub fn update_trust(
166        &mut self,
167        domain: Domain,
168        trust_entries: Vec<TrustEntry>,
169    ) -> Result<(), Error> {
170        let domain_indices = self
171            .indices
172            .get_mut(&domain.to_hash())
173            .ok_or::<Error>(Error::IndicesNotFound(domain.to_hash()))?;
174        let rev_domain_indices = self
175            .rev_indices
176            .get_mut(&domain.to_hash())
177            .ok_or::<Error>(Error::ReverseIndicesNotFound(domain.to_hash()))?;
178        let count = self
179            .count
180            .get_mut(&domain.to_hash())
181            .ok_or::<Error>(Error::CountNotFound(domain.to_hash()))?;
182        let lt_sub_trees = self
183            .lt_sub_trees
184            .get_mut(&domain.to_hash())
185            .ok_or::<Error>(Error::LocalTrustSubTreesNotFoundWithDomain(
186                domain.to_hash(),
187            ))?;
188        let lt_master_tree = self
189            .lt_master_tree
190            .get_mut(&domain.to_hash())
191            .ok_or::<Error>(Error::LocalTrustMasterTreeNotFound(domain.to_hash()))?;
192        let lt = self
193            .local_trust
194            .get_mut(&domain.trust_namespace())
195            .ok_or::<Error>(Error::LocalTrustNotFound(domain.trust_namespace()))?;
196        let default_sub_tree = DenseIncrementalMerkleTree::<Keccak256>::new(32);
197        for entry in trust_entries {
198            let from_index = if let Some(i) = domain_indices.get(entry.from()) {
199                *i
200            } else {
201                let curr_count = *count;
202                domain_indices.insert(entry.from().clone(), curr_count);
203                rev_domain_indices.insert(curr_count, entry.from().clone());
204                *count += 1;
205                curr_count
206            };
207            let to_index = if let Some(i) = domain_indices.get(entry.to()) {
208                *i
209            } else {
210                let curr_count = *count;
211                domain_indices.insert(entry.to().clone(), curr_count);
212                rev_domain_indices.insert(curr_count, entry.to().clone());
213                *count += 1;
214                curr_count
215            };
216
217            let from_map = lt.entry(from_index).or_insert(OutboundLocalTrust::new());
218            let is_zero = entry.value() == &0.0;
219            let exists = from_map.contains_key(&to_index);
220            if is_zero && exists {
221                from_map.remove(&to_index);
222            } else if !is_zero {
223                from_map.insert(to_index, *entry.value());
224            }
225
226            lt_sub_trees
227                .entry(from_index)
228                .or_insert_with(|| default_sub_tree.clone());
229            let sub_tree = lt_sub_trees
230                .get_mut(&from_index)
231                .ok_or(Error::LocalTrustSubTreesNotFoundWithIndex(from_index))?;
232
233            let leaf = hash_leaf::<Keccak256>(entry.value().to_be_bytes().to_vec());
234            sub_tree.insert_leaf(to_index, leaf);
235
236            let sub_tree_root = sub_tree.root().map_err(Error::Merkle)?;
237
238            let leaf = hash_leaf::<Keccak256>(sub_tree_root.inner().to_vec());
239            lt_master_tree.insert_leaf(from_index, leaf);
240        }
241        let lt_root = lt_master_tree.root().map_err(Error::Merkle)?;
242        info!(
243            "LT_UPDATE, DOMAIN: {}, NEW_MERKLE_ROOT: {}",
244            domain.to_hash(),
245            lt_root,
246        );
247
248        Ok(())
249    }
250
251    pub fn update_trust_map(
252        &mut self,
253        domain: Domain,
254        trust_entries: Vec<TrustEntry>,
255    ) -> Result<(), Error> {
256        let domain_indices = self
257            .indices
258            .get_mut(&domain.to_hash())
259            .ok_or::<Error>(Error::IndicesNotFound(domain.to_hash()))?;
260        let rev_domain_indices = self
261            .rev_indices
262            .get_mut(&domain.to_hash())
263            .ok_or::<Error>(Error::ReverseIndicesNotFound(domain.to_hash()))?;
264        let count = self
265            .count
266            .get_mut(&domain.to_hash())
267            .ok_or::<Error>(Error::CountNotFound(domain.to_hash()))?;
268        let lt = self
269            .local_trust
270            .get_mut(&domain.trust_namespace())
271            .ok_or::<Error>(Error::LocalTrustNotFound(domain.trust_namespace()))?;
272        for entry in trust_entries {
273            let from_index = if let Some(i) = domain_indices.get(entry.from()) {
274                *i
275            } else {
276                let curr_count = *count;
277                domain_indices.insert(entry.from().clone(), curr_count);
278                rev_domain_indices.insert(curr_count, entry.from().clone());
279                *count += 1;
280                curr_count
281            };
282            let to_index = if let Some(i) = domain_indices.get(entry.to()) {
283                *i
284            } else {
285                let curr_count = *count;
286                domain_indices.insert(entry.to().clone(), curr_count);
287                rev_domain_indices.insert(curr_count, entry.to().clone());
288                *count += 1;
289                curr_count
290            };
291
292            let from_map = lt.entry(from_index).or_insert(OutboundLocalTrust::new());
293            let is_zero = entry.value() == &0.0;
294            let exists = from_map.contains_key(&to_index);
295            if is_zero && exists {
296                from_map.remove(&to_index);
297            } else if !is_zero {
298                from_map.insert(to_index, *entry.value());
299            }
300        }
301        info!("LT_MAP_UPDATE, DOMAIN: {}", domain.to_hash(),);
302
303        Ok(())
304    }
305
306    pub fn update_seed(
307        &mut self,
308        domain: Domain,
309        seed_entries: Vec<ScoreEntry>,
310    ) -> Result<(), Error> {
311        let domain_indices = self
312            .indices
313            .get_mut(&domain.to_hash())
314            .ok_or::<Error>(Error::IndicesNotFound(domain.to_hash()))?;
315        let rev_domain_indices = self
316            .rev_indices
317            .get_mut(&domain.to_hash())
318            .ok_or::<Error>(Error::ReverseIndicesNotFound(domain.to_hash()))?;
319        let count = self
320            .count
321            .get_mut(&domain.to_hash())
322            .ok_or::<Error>(Error::CountNotFound(domain.to_hash()))?;
323        let st_master_tree = self
324            .st_master_tree
325            .get_mut(&domain.to_hash())
326            .ok_or::<Error>(Error::SeedTrustMasterTreeNotFound(domain.to_hash()))?;
327        let seed = self
328            .seed_trust
329            .get_mut(&domain.seed_namespace())
330            .ok_or::<Error>(Error::SeedTrustNotFound(domain.seed_namespace()))?;
331        for entry in seed_entries {
332            let index = if let Some(i) = domain_indices.get(entry.id()) {
333                *i
334            } else {
335                let curr_count = *count;
336                domain_indices.insert(entry.id().clone(), curr_count);
337                rev_domain_indices.insert(curr_count, entry.id().clone());
338                *count += 1;
339                curr_count
340            };
341            let is_zero = entry.value() == &0.0;
342            let exists = seed.contains_key(&index);
343            if is_zero && exists {
344                seed.remove(&index);
345            } else if !is_zero {
346                seed.insert(index, *entry.value());
347            }
348
349            let leaf = hash_leaf::<Keccak256>(entry.value().to_be_bytes().to_vec());
350            st_master_tree.insert_leaf(index, leaf);
351        }
352        let st_root = st_master_tree.root().map_err(Error::Merkle)?;
353        info!(
354            "ST_UPDATE, DOMAIN: {}, NEW_MERKLE_ROOT: {}",
355            domain.to_hash(),
356            st_root,
357        );
358
359        Ok(())
360    }
361
362    pub fn update_seed_map(
363        &mut self,
364        domain: Domain,
365        seed_entries: Vec<ScoreEntry>,
366    ) -> Result<(), Error> {
367        let domain_indices = self
368            .indices
369            .get_mut(&domain.to_hash())
370            .ok_or::<Error>(Error::IndicesNotFound(domain.to_hash()))?;
371        let rev_domain_indices = self
372            .rev_indices
373            .get_mut(&domain.to_hash())
374            .ok_or::<Error>(Error::ReverseIndicesNotFound(domain.to_hash()))?;
375        let count = self
376            .count
377            .get_mut(&domain.to_hash())
378            .ok_or::<Error>(Error::CountNotFound(domain.to_hash()))?;
379        let seed = self
380            .seed_trust
381            .get_mut(&domain.seed_namespace())
382            .ok_or::<Error>(Error::SeedTrustNotFound(domain.seed_namespace()))?;
383        for entry in seed_entries {
384            let index = if let Some(i) = domain_indices.get(entry.id()) {
385                *i
386            } else {
387                let curr_count = *count;
388                domain_indices.insert(entry.id().clone(), curr_count);
389                rev_domain_indices.insert(curr_count, entry.id().clone());
390                *count += 1;
391                curr_count
392            };
393            let is_zero = entry.value() == &0.0;
394            let exists = seed.contains_key(&index);
395            if is_zero && exists {
396                seed.remove(&index);
397            } else if !is_zero {
398                seed.insert(index, *entry.value());
399            }
400        }
401        info!("ST_MAP_UPDATE, DOMAIN: {}", domain.to_hash(),);
402
403        Ok(())
404    }
405
406    pub fn get_base_root_hashes(&self, domain: &Domain) -> Result<Hash, Error> {
407        let lt_tree = self
408            .lt_master_tree
409            .get(&domain.to_hash())
410            .ok_or::<Error>(Error::LocalTrustMasterTreeNotFound(domain.to_hash()))?;
411        let st_tree = self
412            .st_master_tree
413            .get(&domain.to_hash())
414            .ok_or::<Error>(Error::SeedTrustMasterTreeNotFound(domain.to_hash()))?;
415        let lt_tree_root = lt_tree.root().map_err(Error::Merkle)?;
416        let st_tree_root = st_tree.root().map_err(Error::Merkle)?;
417        let tree_roots = hash_two::<Keccak256>(lt_tree_root, st_tree_root);
418        Ok(tree_roots)
419    }
420}
421
422#[derive(thiserror::Error, Debug)]
423pub enum Error {
424    #[error("'indices' not found for domain: {0}")]
425    IndicesNotFound(DomainHash),
426    #[error("'rev_indices' not found for domain: {0}")]
427    ReverseIndicesNotFound(DomainHash),
428    #[error("'count' not found for domain: {0}")]
429    CountNotFound(DomainHash),
430    #[error("'local_trust_sub_trees' not found for domain: {0}")]
431    LocalTrustSubTreesNotFoundWithDomain(DomainHash),
432    #[error("'local_trust_sub_trees' not found for index: {0}")]
433    LocalTrustSubTreesNotFoundWithIndex(u64),
434    #[error("'local_trust_master_tree' not found for domain: {0}")]
435    LocalTrustMasterTreeNotFound(DomainHash),
436    #[error("'seed_trust_master_tree' not found for domain: {0}")]
437    SeedTrustMasterTreeNotFound(DomainHash),
438    #[error("'local_trust' not found for domain: {0}")]
439    LocalTrustNotFound(OwnedNamespace),
440    #[error("'seed_trust' not found for domain: {0}")]
441    SeedTrustNotFound(OwnedNamespace),
442    #[error("'domain_index' not found for address: {0}")]
443    DomainIndexNotFound(String),
444    #[error("Merkle Error: {0}")]
445    Merkle(merkle::Error),
446    #[error("Misc Error: {0}")]
447    Misc(String),
448}