ibc_client_tendermint/
client_state.rs1use ibc_client_tendermint_types::proto::v1::ClientState as RawTmClientState;
12use ibc_client_tendermint_types::ClientState as ClientStateType;
13use ibc_core_host::types::error::DecodingError;
14use ibc_primitives::prelude::*;
15use ibc_primitives::proto::{Any, Protobuf};
16
17mod common;
18mod execution;
19mod misbehaviour;
20mod update_client;
21mod validation;
22
23pub use common::*;
24pub use execution::*;
25pub use misbehaviour::*;
26pub use update_client::*;
27pub use validation::*;
28
29#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
34#[derive(Clone, Debug, PartialEq, derive_more::From)]
35pub struct ClientState(ClientStateType);
36
37impl ClientState {
38 pub fn inner(&self) -> &ClientStateType {
39 &self.0
40 }
41}
42
43impl Protobuf<RawTmClientState> for ClientState {}
44
45impl TryFrom<RawTmClientState> for ClientState {
46 type Error = DecodingError;
47
48 fn try_from(raw: RawTmClientState) -> Result<Self, Self::Error> {
49 Ok(Self(ClientStateType::try_from(raw)?))
50 }
51}
52
53impl From<ClientState> for RawTmClientState {
54 fn from(client_state: ClientState) -> Self {
55 client_state.0.into()
56 }
57}
58
59impl Protobuf<Any> for ClientState {}
60
61impl TryFrom<Any> for ClientState {
62 type Error = DecodingError;
63
64 fn try_from(raw: Any) -> Result<Self, Self::Error> {
65 Ok(Self(ClientStateType::try_from(raw)?))
66 }
67}
68
69impl From<ClientState> for Any {
70 fn from(client_state: ClientState) -> Self {
71 client_state.0.into()
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use core::time::Duration;
78
79 use ibc_client_tendermint_types::{
80 AllowUpdate, ClientState as ClientStateType, TrustThreshold,
81 };
82 use ibc_core_client::types::Height;
83 use ibc_core_commitment_types::specs::ProofSpecs;
84 use ibc_core_host::types::identifiers::ChainId;
85
86 use super::*;
87
88 #[derive(Clone, Debug, PartialEq)]
89 pub struct ClientStateParams {
90 pub id: ChainId,
91 pub trust_level: TrustThreshold,
92 pub trusting_period: Duration,
93 pub unbonding_period: Duration,
94 pub max_clock_drift: Duration,
95 pub latest_height: Height,
96 pub proof_specs: ProofSpecs,
97 pub upgrade_path: Vec<String>,
98 pub allow_update: AllowUpdate,
99 }
100
101 #[test]
102 fn client_state_verify_height() {
103 let default_params: ClientStateParams = ClientStateParams {
105 id: ChainId::new("ibc-1").unwrap(),
106 trust_level: TrustThreshold::ONE_THIRD,
107 trusting_period: Duration::new(64000, 0),
108 unbonding_period: Duration::new(128_000, 0),
109 max_clock_drift: Duration::new(3, 0),
110 latest_height: Height::new(1, 10).expect("Never fails"),
111 proof_specs: ProofSpecs::cosmos(),
112 upgrade_path: Vec::new(),
113 allow_update: AllowUpdate {
114 after_expiry: false,
115 after_misbehaviour: false,
116 },
117 };
118
119 struct Test {
120 name: String,
121 height: Height,
122 setup: Option<Box<dyn FnOnce(ClientState) -> ClientState>>,
123 want_pass: bool,
124 }
125
126 let tests = vec![
127 Test {
128 name: "Successful height verification".to_string(),
129 height: Height::new(1, 8).expect("Never fails"),
130 setup: None,
131 want_pass: true,
132 },
133 Test {
134 name: "Invalid (too large) client height".to_string(),
135 height: Height::new(1, 12).expect("Never fails"),
136 setup: None,
137 want_pass: false,
138 },
139 ];
140
141 for test in tests {
142 let p = default_params.clone();
143 let client_state = ClientStateType::new(
144 p.id,
145 p.trust_level,
146 p.trusting_period,
147 p.unbonding_period,
148 p.max_clock_drift,
149 p.latest_height,
150 p.proof_specs,
151 p.upgrade_path,
152 p.allow_update,
153 )
154 .expect("Never fails");
155 let client_state = match test.setup {
156 Some(setup) => (setup)(ClientState(client_state)),
157 _ => ClientState(client_state),
158 };
159 let res = validate_proof_height(client_state.inner(), test.height);
160
161 assert_eq!(
162 test.want_pass,
163 res.is_ok(),
164 "ClientState::validate_proof_height() failed for test {}, \nmsg{:?} with error {:?}",
165 test.name,
166 test.height,
167 res.err(),
168 );
169 }
170 }
171}