forked from informalsystems/tendermint-rs
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsupervisor.rs
126 lines (101 loc) · 3.86 KB
/
supervisor.rs
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#![cfg(feature = "rust-crypto")]
use std::{collections::HashMap, time::Duration};
use tendermint_light_client::{
components::{
io::{AtHeight, Io},
scheduler,
},
fork_detector::ProdForkDetector,
light_client::LightClient,
peer_list::PeerList,
state::State,
store::{memory::MemoryStore, LightStore},
supervisor::{Handle, Instance, Supervisor},
tests::{LightClientTest, MockClock, MockEvidenceReporter, MockIo, TrustOptions},
verifier::{
options::Options,
types::{LightBlock, PeerId, Status, Time},
ProdVerifier,
},
};
use tendermint_testgen::Tester;
const TEST_FILES_PATH: &str = "./tests/support/";
fn make_instance(peer_id: PeerId, trust_options: TrustOptions, io: MockIo, now: Time) -> Instance {
let trusted_height = trust_options.height;
let trusted_state = io
.fetch_light_block(AtHeight::At(trusted_height))
.expect("could not 'request' light block");
let mut light_store = MemoryStore::new();
light_store.insert(trusted_state, Status::Trusted);
let state = State {
light_store: Box::new(light_store),
verification_trace: HashMap::new(),
};
let options = Options {
trust_threshold: trust_options.trust_level,
trusting_period: trust_options.period.into(),
clock_drift: Duration::from_secs(10),
};
let clock = MockClock { now };
let verifier = ProdVerifier::default();
let scheduler = scheduler::basic_bisecting_schedule;
let light_client = LightClient::new(peer_id, options, clock, scheduler, verifier, io);
Instance::new(light_client, state)
}
fn run_multipeer_test(tc: LightClientTest<LightBlock>) {
let primary = tc.primary.lite_blocks[0].provider;
println!(
"Running Test Case: {}\nwith Primary Peer: {:?}",
tc.description, primary
);
let expects_err = match &tc.expected_output {
Some(eo) => eo.eq("error"),
None => false,
};
let io = MockIo::new(tc.primary.lite_blocks);
let primary_instance = make_instance(primary, tc.trust_options.clone(), io.clone(), tc.now);
let mut peer_list = PeerList::builder();
peer_list.primary(primary, primary_instance);
for provider in tc.witnesses.into_iter() {
let peer_id = provider.value.lite_blocks[0].provider;
println!("Witness: {peer_id}");
let io = MockIo::new(provider.value.lite_blocks);
let instance = make_instance(peer_id, tc.trust_options.clone(), io.clone(), tc.now);
peer_list.witness(peer_id, instance);
}
let supervisor = Supervisor::new(
peer_list.build(),
ProdForkDetector::default(),
MockEvidenceReporter::new(),
);
// TODO: Add method to `Handle` to get a copy of the current peer list
let handle = supervisor.handle();
std::thread::spawn(|| supervisor.run());
let target_height = tc.height_to_verify;
match handle.verify_to_target(target_height) {
Ok(new_state) => {
// Check that the expected state and new_state match
let untrusted_light_block = io
.fetch_light_block(AtHeight::At(target_height))
.expect("header at untrusted height not found");
let expected_state = untrusted_light_block;
assert_eq!(new_state.height(), expected_state.height());
assert_eq!(new_state, expected_state);
// Check the verdict
assert!(!expects_err);
},
Err(e) => {
dbg!(e);
assert!(expects_err);
},
}
// TODO: Check the peer list
// TODO: Check we recorded a fork evidence (or not)
}
#[test]
fn run_multipeer_tests() {
let mut tester = Tester::new("bisection_multi_peer", TEST_FILES_PATH);
tester.add_test("multipeer test", run_multipeer_test);
tester.run_foreach_in_dir("bisection/multi_peer");
tester.finalize();
}