1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use crate::{
store::LightStore,
types::{Height, LightBlock, Status},
};
use contracts::*;
use std::collections::{HashMap, HashSet};
pub type VerificationTrace = HashMap<Height, HashSet<Height>>;
#[derive(Debug)]
pub struct State {
pub light_store: Box<dyn LightStore>,
pub verification_trace: VerificationTrace,
}
impl State {
pub fn new(light_store: impl LightStore + 'static) -> Self {
Self {
light_store: Box::new(light_store),
verification_trace: VerificationTrace::new(),
}
}
#[pre(height <= target_height)]
pub fn trace_block(&mut self, target_height: Height, height: Height) {
self.verification_trace
.entry(target_height)
.or_insert_with(HashSet::new)
.insert(height);
}
pub fn get_trace(&self, target_height: Height) -> Vec<LightBlock> {
let mut trace = self
.verification_trace
.get(&target_height)
.unwrap_or(&HashSet::new())
.iter()
.flat_map(|h| self.light_store.get(*h, Status::Verified))
.collect::<Vec<_>>();
trace.sort_by_key(|lb| lb.height());
trace.reverse();
trace
}
}