cometbft_light_client_verifier/
types.rs1use cometbft::{
4 account::Id as TMAccountId,
5 block::{
6 header::Header as TMHeader, signed_header::SignedHeader as TMSignedHeader,
7 Commit as TMCommit,
8 },
9 chain::Id as ChainId,
10 trust_threshold::TrustThresholdFraction,
11 validator::{Info as TMValidatorInfo, Set as TMValidatorSet},
12};
13pub use cometbft::{block::Height, hash::Hash, time::Time};
14use derive_more::Display;
15use serde::{Deserialize, Serialize};
16
17use crate::prelude::*;
18
19pub type PeerId = cometbft::node::Id;
21
22pub type TrustThreshold = TrustThresholdFraction;
26
27pub type Header = TMHeader;
31
32pub type ValidatorSet = TMValidatorSet;
34
35pub type Validator = TMValidatorInfo;
37
38pub type ValidatorAddress = TMAccountId;
40
41pub type Commit = TMCommit;
44
45pub type SignedHeader = TMSignedHeader;
47
48pub type TrustedState = LightBlock;
50
51#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
53pub enum Status {
54 Failed,
56 Unverified,
58 Verified,
60 Trusted,
62}
63
64impl Status {
65 pub fn iter() -> &'static [Self] {
67 use Status::*;
68 static ALL: &[Status] = &[Unverified, Verified, Trusted, Failed];
69 ALL
70 }
71
72 pub fn most_trusted(a: Self, b: Self) -> Self {
76 core::cmp::max(a, b)
77 }
78}
79
80pub struct TrustedBlockState<'a> {
82 pub chain_id: &'a ChainId,
83 pub header_time: Time,
84 pub height: Height,
85 pub next_validators: &'a ValidatorSet,
86 pub next_validators_hash: Hash,
87}
88
89pub struct UntrustedBlockState<'a> {
91 pub signed_header: &'a SignedHeader,
92 pub validators: &'a ValidatorSet,
93 pub next_validators: Option<&'a ValidatorSet>,
94}
95
96impl<'a> UntrustedBlockState<'a> {
97 pub fn height(&self) -> Height {
99 self.signed_header.header.height
100 }
101}
102
103#[derive(Clone, Debug, Display, PartialEq, Eq, Serialize, Deserialize)]
106#[display(fmt = "{self:?}")]
107pub struct LightBlock {
108 pub signed_header: SignedHeader,
110 #[serde(rename = "validator_set")]
112 pub validators: ValidatorSet,
113 #[serde(rename = "next_validator_set")]
115 pub next_validators: ValidatorSet,
116 pub provider: PeerId,
118}
119
120impl LightBlock {
121 pub fn new(
123 signed_header: SignedHeader,
124 validators: ValidatorSet,
125 next_validators: ValidatorSet,
126 provider: PeerId,
127 ) -> LightBlock {
128 Self {
129 signed_header,
130 validators,
131 next_validators,
132 provider,
133 }
134 }
135
136 pub fn height(&self) -> Height {
141 self.signed_header.header.height
142 }
143
144 pub fn time(&self) -> Time {
149 self.signed_header.header.time
150 }
151
152 pub fn as_trusted_state(&self) -> TrustedBlockState<'_> {
155 TrustedBlockState {
156 chain_id: &self.signed_header.header.chain_id,
157 header_time: self.signed_header.header.time,
158 height: self.signed_header.header.height,
159 next_validators: &self.next_validators,
160 next_validators_hash: self.signed_header.header.next_validators_hash,
161 }
162 }
163
164 pub fn as_untrusted_state(&self) -> UntrustedBlockState<'_> {
167 UntrustedBlockState {
168 signed_header: &self.signed_header,
169 validators: &self.validators,
170 next_validators: Some(&self.next_validators),
171 }
172 }
173}
174
175#[derive(Clone, Debug, Display, PartialEq, Eq, Serialize, Deserialize)]
178#[display(fmt = "{self:?}")]
179pub struct LatestStatus {
180 pub height: Option<u64>,
182 #[serde(with = "cometbft::serializers::option_hash")]
184 pub block_hash: Option<Hash>,
185 #[serde(with = "cometbft::serializers::option_hash")]
188 pub valset_hash: Option<Hash>,
189 pub connected_nodes: Vec<PeerId>,
191}
192
193impl LatestStatus {
194 pub fn new(
196 height: Option<u64>,
197 block_hash: Option<Hash>,
198 valset_hash: Option<Hash>,
199 connected_nodes: Vec<PeerId>,
200 ) -> Self {
201 Self {
202 height,
203 block_hash,
204 valset_hash,
205 connected_nodes,
206 }
207 }
208}
209
210#[cfg(test)]
211mod tests {
212
213 mod status {
214 use Status::*;
215
216 use crate::{prelude::*, types::Status};
217
218 #[test]
219 fn ord_impl() {
220 assert!(Trusted > Verified);
221 assert!(Verified > Unverified);
222 assert!(Unverified > Failed);
223 }
224
225 #[test]
226 fn most_trusted() {
227 for (a, b) in cross(Status::iter()) {
228 if a > b {
229 assert_eq!(Status::most_trusted(a, b), a);
230 } else {
231 assert_eq!(Status::most_trusted(a, b), b);
232 }
233 }
234 }
235
236 fn cross<T>(xs: &[T]) -> Vec<(T, T)>
237 where
238 T: Copy,
239 {
240 xs.iter()
241 .copied()
242 .flat_map(|y| xs.iter().copied().map(move |x| (x, y)))
243 .collect()
244 }
245 }
246}