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
use serde_derive::{Deserialize, Serialize};
use tendermint_proto::Protobuf;
use ibc_proto::ibc::mock::Header as RawMockHeader;
use crate::core::ics02_client::client_consensus::AnyConsensusState;
use crate::core::ics02_client::client_type::ClientType;
use crate::core::ics02_client::error::Error;
use crate::core::ics02_client::header::AnyHeader;
use crate::core::ics02_client::header::Header;
use crate::mock::client_state::MockConsensusState;
use crate::timestamp::Timestamp;
use crate::Height;
#[derive(Copy, Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
pub struct MockHeader {
pub height: Height,
pub timestamp: Timestamp,
}
impl Default for MockHeader {
fn default() -> Self {
Self {
height: Height::new(0, 1).unwrap(),
timestamp: Default::default(),
}
}
}
impl Protobuf<RawMockHeader> for MockHeader {}
impl TryFrom<RawMockHeader> for MockHeader {
type Error = Error;
fn try_from(raw: RawMockHeader) -> Result<Self, Self::Error> {
Ok(MockHeader {
height: raw
.height
.and_then(|raw_height| raw_height.try_into().ok())
.ok_or_else(Error::missing_raw_header)?,
timestamp: Timestamp::from_nanoseconds(raw.timestamp)
.map_err(Error::invalid_packet_timestamp)?,
})
}
}
impl From<MockHeader> for RawMockHeader {
fn from(value: MockHeader) -> Self {
RawMockHeader {
height: Some(value.height.into()),
timestamp: value.timestamp.nanoseconds(),
}
}
}
impl MockHeader {
pub fn height(&self) -> Height {
self.height
}
pub fn new(height: Height) -> Self {
Self {
height,
timestamp: Timestamp::now(),
}
}
pub fn with_timestamp(self, timestamp: Timestamp) -> Self {
Self { timestamp, ..self }
}
}
impl From<MockHeader> for AnyHeader {
fn from(mh: MockHeader) -> Self {
Self::Mock(mh)
}
}
impl Header for MockHeader {
fn client_type(&self) -> ClientType {
ClientType::Mock
}
fn height(&self) -> Height {
self.height
}
fn timestamp(&self) -> Timestamp {
self.timestamp
}
fn wrap_any(self) -> AnyHeader {
AnyHeader::Mock(self)
}
}
impl From<MockHeader> for AnyConsensusState {
fn from(h: MockHeader) -> Self {
AnyConsensusState::Mock(MockConsensusState::new(h))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn encode_any() {
let header = MockHeader::new(Height::new(1, 10).unwrap()).with_timestamp(Timestamp::none());
let bytes = header.wrap_any().encode_vec().unwrap();
assert_eq!(
&bytes,
&[
10, 16, 47, 105, 98, 99, 46, 109, 111, 99, 107, 46, 72, 101, 97, 100, 101, 114, 18,
6, 10, 4, 8, 1, 16, 10
]
);
}
}