ibc_testkit/testapp/ibc/clients/mock/
consensus_state.rs

1use ibc::core::client::context::consensus_state::ConsensusState;
2use ibc::core::client::types::error::ClientError;
3use ibc::core::commitment_types::commitment::CommitmentRoot;
4use ibc::core::host::types::error::DecodingError;
5use ibc::core::primitives::prelude::*;
6use ibc::core::primitives::Timestamp;
7use ibc::primitives::proto::{Any, Protobuf};
8
9use crate::testapp::ibc::clients::mock::header::MockHeader;
10use crate::testapp::ibc::clients::mock::proto::ConsensusState as RawMockConsensusState;
11pub const MOCK_CONSENSUS_STATE_TYPE_URL: &str = "/ibc.mock.ConsensusState";
12
13/// The mock consensus state type used within ibc-testkit for testing situations
14/// when a consensus state is required.
15///
16/// Note, this type slightly differs from the [`RawMockConsensusState`] type exposed by
17/// ibc-proto. It contains a (private) `root` field to easily return a
18/// reference to the mock consensus state's dummy [`CommitmentRoot`].
19#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
20#[derive(Clone, Debug, PartialEq, Eq)]
21pub struct MockConsensusState {
22    pub header: MockHeader,
23    root: CommitmentRoot,
24}
25
26impl MockConsensusState {
27    pub fn new(header: MockHeader) -> Self {
28        Self {
29            header,
30            root: CommitmentRoot::from(vec![0]),
31        }
32    }
33
34    pub fn timestamp(&self) -> Timestamp {
35        self.header.timestamp
36    }
37}
38
39impl Protobuf<RawMockConsensusState> for MockConsensusState {}
40
41impl TryFrom<RawMockConsensusState> for MockConsensusState {
42    type Error = DecodingError;
43
44    fn try_from(raw: RawMockConsensusState) -> Result<Self, Self::Error> {
45        let raw_header = raw.header.ok_or(DecodingError::missing_raw_data(
46            "mock consensus state header",
47        ))?;
48
49        Ok(Self {
50            header: raw_header.try_into()?,
51            root: CommitmentRoot::from(vec![0]),
52        })
53    }
54}
55
56impl From<MockConsensusState> for RawMockConsensusState {
57    fn from(value: MockConsensusState) -> Self {
58        Self {
59            header: Some(value.header.into()),
60        }
61    }
62}
63
64impl Protobuf<Any> for MockConsensusState {}
65
66impl TryFrom<Any> for MockConsensusState {
67    type Error = DecodingError;
68
69    fn try_from(raw: Any) -> Result<Self, Self::Error> {
70        if let MOCK_CONSENSUS_STATE_TYPE_URL = raw.type_url.as_str() {
71            Protobuf::<RawMockConsensusState>::decode(raw.value.as_ref()).map_err(Into::into)
72        } else {
73            Err(DecodingError::MismatchedResourceName {
74                expected: MOCK_CONSENSUS_STATE_TYPE_URL.to_string(),
75                actual: raw.type_url,
76            })
77        }
78    }
79}
80
81impl From<MockConsensusState> for Any {
82    fn from(consensus_state: MockConsensusState) -> Self {
83        Self {
84            type_url: MOCK_CONSENSUS_STATE_TYPE_URL.to_string(),
85            value: Protobuf::<RawMockConsensusState>::encode_vec(consensus_state),
86        }
87    }
88}
89
90impl ConsensusState for MockConsensusState {
91    fn root(&self) -> &CommitmentRoot {
92        &self.root
93    }
94
95    fn timestamp(&self) -> Result<Timestamp, ClientError> {
96        Ok(self.header.timestamp)
97    }
98}