openrank_common/runners/
compute_runner.rs1use crate::{
2 algos::et::positive_run,
3 merkle::{self, fixed::DenseMerkleTree, hash_leaf, Hash},
4 tx::trust::{ScoreEntry, TrustEntry},
5 Domain, DomainHash,
6};
7use getset::Getters;
8use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
9use sha3::Keccak256;
10use std::collections::HashMap;
11use tracing::info;
12
13use super::{BaseRunner, Error as BaseError};
14
15#[derive(Getters)]
16#[getset(get = "pub")]
17pub struct ComputeRunner {
19 base: BaseRunner,
20 compute_results: HashMap<DomainHash, Vec<(u64, f32)>>,
21 compute_tree: HashMap<DomainHash, DenseMerkleTree<Keccak256>>,
22}
23
24impl ComputeRunner {
25 pub fn new(domains: &[Domain]) -> Self {
26 let base = BaseRunner::new(domains);
27 let mut compute_results = HashMap::new();
28 for domain in domains {
29 let domain_hash = domain.to_hash();
30 compute_results.insert(domain_hash, Vec::<(u64, f32)>::new());
31 }
32 Self {
33 base,
34 compute_results,
35 compute_tree: HashMap::new(),
36 }
37 }
38
39 pub fn update_trust(
41 &mut self,
42 domain: Domain,
43 trust_entries: Vec<TrustEntry>,
44 ) -> Result<(), Error> {
45 self.base
46 .update_trust(domain, trust_entries)
47 .map_err(Error::Base)
48 }
49
50 pub fn update_trust_map(
51 &mut self,
52 domain: Domain,
53 trust_entries: Vec<TrustEntry>,
54 ) -> Result<(), Error> {
55 self.base
56 .update_trust_map(domain, trust_entries)
57 .map_err(Error::Base)
58 }
59
60 pub fn update_seed(
62 &mut self,
63 domain: Domain,
64 seed_entries: Vec<ScoreEntry>,
65 ) -> Result<(), Error> {
66 self.base
67 .update_seed(domain, seed_entries)
68 .map_err(Error::Base)
69 }
70
71 pub fn update_seed_map(
72 &mut self,
73 domain: Domain,
74 seed_entries: Vec<ScoreEntry>,
75 ) -> Result<(), Error> {
76 self.base
77 .update_seed_map(domain, seed_entries)
78 .map_err(Error::Base)
79 }
80
81 pub fn compute(&mut self, domain: Domain) -> Result<(), Error> {
83 info!("COMPUTE_RUN: {}", domain.to_hash());
84 let lt = self
85 .base
86 .local_trust
87 .get(&domain.trust_namespace())
88 .ok_or::<Error>(BaseError::LocalTrustNotFound(domain.trust_namespace()).into())?;
89 let seed = self
90 .base
91 .seed_trust
92 .get(&domain.seed_namespace())
93 .ok_or::<Error>(BaseError::SeedTrustNotFound(domain.seed_namespace()).into())?;
94 let count = self
95 .base
96 .count
97 .get(&domain.to_hash())
98 .ok_or::<Error>(BaseError::CountNotFound(domain.to_hash()).into())?;
99 let res = positive_run(lt.clone(), seed.clone(), *count);
100 self.compute_results.insert(domain.to_hash(), res);
101 Ok(())
102 }
103
104 pub fn create_compute_tree(&mut self, domain: Domain) -> Result<(), Error> {
106 info!("CREATE_COMPUTE_TREE: {}", domain.to_hash());
107 let scores = self
108 .compute_results
109 .get(&domain.to_hash())
110 .ok_or(Error::ComputeResultsNotFound(domain.to_hash()))?;
111 let score_hashes: Vec<Hash> = scores
112 .par_iter()
113 .map(|(_, x)| hash_leaf::<Keccak256>(x.to_be_bytes().to_vec()))
114 .collect();
115 let compute_tree =
116 DenseMerkleTree::<Keccak256>::new(score_hashes).map_err(Error::Merkle)?;
117 info!(
118 "COMPUTE_TREE_ROOT_HASH: {}",
119 compute_tree.root().map_err(Error::Merkle)?
120 );
121 self.compute_tree.insert(domain.to_hash(), compute_tree);
122 Ok(())
123 }
124
125 pub fn get_compute_scores(&self, domain: Domain) -> Result<Vec<ScoreEntry>, Error> {
127 let domain_indices = self
128 .base
129 .indices
130 .get(&domain.to_hash())
131 .ok_or::<Error>(BaseError::IndicesNotFound(domain.to_hash()).into())?;
132 let scores = self
133 .compute_results
134 .get(&domain.to_hash())
135 .ok_or(Error::ComputeResultsNotFound(domain.to_hash()))?;
136 let index_to_address: HashMap<&u64, &String> =
137 domain_indices.iter().map(|(k, v)| (v, k)).collect();
138
139 let mut entries = Vec::new();
140 for (index, val) in scores {
141 let address = index_to_address
142 .get(&index)
143 .ok_or(Error::IndexToAddressNotFound(*index))?;
144 let score_entry = ScoreEntry::new((*address).clone(), *val);
145 entries.push(score_entry);
146 }
147 Ok(entries)
148 }
149
150 pub fn get_root_hashes(&self, domain: Domain) -> Result<(Hash, Hash), Error> {
152 let tree_roots = self.base.get_base_root_hashes(&domain)?;
153
154 let compute_tree = self
155 .compute_tree
156 .get(&domain.to_hash())
157 .ok_or(Error::ComputeTreeNotFound(domain.to_hash()))?;
158 let ct_tree_root = compute_tree.root().map_err(Error::Merkle)?;
159
160 Ok((tree_roots, ct_tree_root))
161 }
162}
163
164#[derive(thiserror::Error, Debug)]
165pub enum Error {
167 #[error("Base Error: {0}")]
168 Base(BaseError),
169 #[error("ComputeResultsNotFound Error: {0}")]
171 ComputeResultsNotFound(DomainHash),
172 #[error("IndexToAddressNotFound Error: {0}")]
174 IndexToAddressNotFound(u64),
175 #[error("ComputeTreeNotFound Error: {0}")]
177 ComputeTreeNotFound(DomainHash),
178 #[error("Merkle Error: {0}")]
180 Merkle(merkle::Error),
181}
182
183impl From<BaseError> for Error {
184 fn from(err: BaseError) -> Self {
185 Self::Base(err)
186 }
187}