Skip to content

Commit a300669

Browse files
committed
scheme height
1 parent 6f6230c commit a300669

File tree

4 files changed

+119
-95
lines changed

4 files changed

+119
-95
lines changed

light-clients/cf-guest-cw/src/contract.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,7 @@ fn query(deps: Deps, env: Env, msg: msg::QueryMsg) -> StdResult<Binary> {
8989
},
9090
msg::QueryMsg::Status(msg::StatusMsg {}) => to_json_binary(&query_status(ctx)?),
9191
msg::QueryMsg::TimestampAtHeight(msg) => {
92-
let height = msg.height.try_into()?;
93-
let state = ctx.consensus_state(height)?;
92+
let state = ctx.consensus_state(msg.height)?;
9493
to_json_binary(&Uint64::from(state.timestamp_ns.get()))
9594
},
9695
msg::QueryMsg::ExportMetadata(msg::ExportMetadataMsg {}) => {
@@ -101,8 +100,7 @@ fn query(deps: Deps, env: Env, msg: msg::QueryMsg) -> StdResult<Binary> {
101100
}
102101

103102
fn query_verify_state_proof(ctx: context::Context, msg: msg::VerifyStateProofMsg) -> StdResult<()> {
104-
let height = msg.height.try_into()?;
105-
let consensus_state = ctx.consensus_state(height)?;
103+
let consensus_state = ctx.consensus_state(msg.height)?;
106104
cf_guest::proof::verify(
107105
&ibc::CommitmentPrefix::default(),
108106
&msg.proof,

light-clients/cf-guest-cw/src/msg.rs

Lines changed: 20 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ use cosmwasm_std::Uint64;
1818

1919
use crate::{
2020
ibc,
21-
serialisation::{AsStr, Base64, OptBase64},
21+
serialisation,
2222
state,
2323
};
2424

2525
#[cw_serde]
2626
pub struct InstantiateMsg {
27-
#[serde(with = "Base64")]
27+
#[serde(with = "serialisation::Base64")]
2828
pub client_state: state::ClientState,
29-
#[serde(with = "Base64")]
29+
#[serde(with = "serialisation::Base64")]
3030
pub consensus_state: state::ConsensusState,
3131
}
3232

@@ -43,25 +43,25 @@ pub enum SudoMsg {
4343

4444
#[cw_serde]
4545
pub struct UpdateStateMsg {
46-
#[serde(with = "Base64")]
46+
#[serde(with = "serialisation::Base64")]
4747
pub header: state::Header,
4848
}
4949

5050
#[cw_serde]
5151
pub struct UpdateStateOnMisbehaviourMsg {
52-
#[serde(with = "Base64")]
52+
#[serde(with = "serialisation::Base64")]
5353
pub misbehaviour_message: state::Misbehaviour,
5454
}
5555

5656
// #[cw_serde]
5757
// pub struct VerifyUpgradeAndUpdateStateMsg {
58-
// #[serde(with = "Base64")]
58+
// #[serde(with = "serialisation::Base64")]
5959
// pub upgrade_client_state: state::ClientState,
60-
// #[serde(with = "Base64")]
60+
// #[serde(with = "serialisation::Base64")]
6161
// pub upgrade_consensus_state: state::ConsensusState,
62-
// #[serde(with = "Base64")]
62+
// #[serde(with = "serialisation::Base64")]
6363
// pub proof_upgrade_client: ibc::CommitmentProofBytes,
64-
// #[serde(with = "Base64")]
64+
// #[serde(with = "serialisation::Base64")]
6565
// pub proof_upgrade_consensus_state: ibc::CommitmentProofBytes,
6666
// }
6767

@@ -101,25 +101,26 @@ pub enum QueryMsg {
101101

102102
#[cw_serde]
103103
pub struct VerifyClientMessageMsg {
104-
#[serde(with = "Base64")]
104+
#[serde(with = "serialisation::Base64")]
105105
pub client_message: Vec<u8>,
106106
}
107107

108108
#[cw_serde]
109109
pub struct CheckForMisbehaviourMsg {
110-
#[serde(with = "Base64")]
110+
#[serde(with = "serialisation::Base64")]
111111
pub client_message: Vec<u8>,
112112
}
113113

114114
#[cw_serde]
115115
pub struct VerifyStateProofMsg {
116-
#[serde(with = "Base64")]
116+
#[serde(with = "serialisation::Base64")]
117117
pub proof: ibc::CommitmentProofBytes,
118-
#[serde(with = "AsStr")]
118+
#[serde(with = "serialisation::AsStr")]
119119
pub path: ibc::path::Path,
120-
#[serde(with = "OptBase64", default, skip_serializing_if = "Option::is_none")]
120+
#[serde(with = "serialisation::OptBase64", default, skip_serializing_if = "Option::is_none")]
121121
pub value: Option<Vec<u8>>,
122-
pub height: Height,
122+
#[serde(with = "serialisation::Height")]
123+
pub height: ibc::Height,
123124
}
124125

125126
#[cw_serde]
@@ -137,71 +138,17 @@ pub struct GetLatestHeightsMsg {}
137138

138139
#[cw_serde]
139140
pub struct TimestampAtHeightMsg {
140-
pub height: Height,
141+
#[serde(with = "serialisation::Height")]
142+
pub height: ibc::Height,
141143
}
142144

143145
#[cw_serde]
144146
pub struct ExportMetadataMsg {}
145147

146148
#[cw_serde]
147149
pub struct ConsensusStateMetadata {
148-
pub height: Height,
150+
#[serde(with = "serialisation::Height")]
151+
pub height: ibc::Height,
149152
pub host_timestamp_ns: Uint64,
150153
pub host_height: Uint64,
151154
}
152-
153-
fn is_zero(num: &Uint64) -> bool {
154-
u64::from(*num) == 0
155-
}
156-
157-
/// IBC height.
158-
///
159-
/// This is essentially a copy of [`ibc::Height`] which we have so that we can
160-
/// implement `JsonSchema` on it without having to enable `schema` feature on
161-
/// `ibc` which pulls in `std` which we don’t want.
162-
#[derive(
163-
Copy,
164-
Clone,
165-
PartialEq,
166-
Eq,
167-
derive_more::Display,
168-
serde::Serialize,
169-
serde::Deserialize,
170-
schemars::JsonSchema,
171-
)]
172-
#[display(fmt = "{}-{}", revision_number, revision_height)]
173-
pub struct Height {
174-
/// Previously known as "epoch"
175-
#[serde(default, skip_serializing_if = "is_zero")]
176-
pub revision_number: Uint64,
177-
178-
/// The height of a block
179-
pub revision_height: Uint64,
180-
}
181-
182-
impl TryFrom<Height> for ibc::Height {
183-
type Error = cosmwasm_std::StdError;
184-
fn try_from(height: Height) -> Result<Self, Self::Error> {
185-
ibc::Height::new(height.revision_number.into(), height.revision_height.into()).map_err(
186-
|_| cosmwasm_std::StdError::ParseErr {
187-
target_type: "Height".into(),
188-
msg: "unexpected zero height".into(),
189-
},
190-
)
191-
}
192-
}
193-
194-
impl From<ibc::Height> for Height {
195-
fn from(height: ibc::Height) -> Self {
196-
Self {
197-
revision_number: height.revision_number().into(),
198-
revision_height: height.revision_height().into(),
199-
}
200-
}
201-
}
202-
203-
impl core::fmt::Debug for Height {
204-
fn fmt(&self, fmtr: &mut core::fmt::Formatter) -> core::fmt::Result {
205-
core::fmt::Display::fmt(self, fmtr)
206-
}
207-
}

light-clients/cf-guest-cw/src/serialisation.rs

Lines changed: 94 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@ pub struct OptBase64;
1919
/// `Display` and deserialises using `FromStr`.
2020
pub struct AsStr;
2121

22+
/// A Serde serialisation implementation for [`ibc::Height`].
23+
///
24+
/// We need it because we the type to implement `JsonSchema`. ibc-rs does
25+
/// support schema with a `schema` feature however that brings in `std` and we
26+
/// don’t want that. So, we need to define our own serialisation for height
27+
/// IBC height.
28+
pub struct Height;
29+
30+
// ==================== Base64 =================================================
31+
2232
impl Base64 {
2333
pub fn serialize<T: BytesConv, S: Serializer>(obj: &T, ser: S) -> Result<S::Ok, S::Error> {
2434
let bytes = obj.to_bytes()?;
@@ -110,6 +120,32 @@ conv_via_any!(state::ConsensusState);
110120
conv_via_any!(state::Header);
111121
conv_via_any!(state::Misbehaviour);
112122

123+
impl schemars::JsonSchema for Base64 {
124+
fn schema_name() -> alloc::string::String {
125+
"Base64".into()
126+
}
127+
fn schema_id() -> alloc::borrow::Cow<'static, str> {
128+
alloc::borrow::Cow::Borrowed("cf_guest::Base64")
129+
}
130+
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
131+
String::json_schema(gen)
132+
}
133+
}
134+
135+
impl schemars::JsonSchema for OptBase64 {
136+
fn schema_name() -> alloc::string::String {
137+
"Nullable_Base64".into()
138+
}
139+
fn schema_id() -> alloc::borrow::Cow<'static, str> {
140+
alloc::borrow::Cow::Borrowed("Option<cf_guest::Base64>")
141+
}
142+
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
143+
<Option<String>>::json_schema(gen)
144+
}
145+
}
146+
147+
// ==================== As String ==============================================
148+
113149
impl AsStr {
114150
pub fn serialize<T: fmt::Display, S: Serializer>(obj: &T, ser: S) -> Result<S::Ok, S::Error> {
115151
ser.serialize_str(&obj.to_string())
@@ -149,38 +185,82 @@ where
149185
}
150186
}
151187

152-
impl schemars::JsonSchema for Base64 {
188+
impl schemars::JsonSchema for AsStr {
153189
fn schema_name() -> alloc::string::String {
154-
"Base64".into()
190+
String::schema_name()
155191
}
156192
fn schema_id() -> alloc::borrow::Cow<'static, str> {
157-
alloc::borrow::Cow::Borrowed("cf_guest::Base64")
193+
String::schema_id()
158194
}
159195
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
160196
String::json_schema(gen)
161197
}
162198
}
163199

164-
impl schemars::JsonSchema for OptBase64 {
165-
fn schema_name() -> alloc::string::String {
166-
"Nullable_Base64".into()
200+
// ==================== IBC Height =============================================
201+
202+
impl Height {
203+
pub fn serialize<S: Serializer>(height: &ibc::Height, ser: S) -> Result<S::Ok, S::Error> {
204+
RawHeight::from(*height).serialize(ser)
167205
}
168-
fn schema_id() -> alloc::borrow::Cow<'static, str> {
169-
alloc::borrow::Cow::Borrowed("Option<cf_guest::Base64>")
206+
207+
pub fn deserialize<'de, D: Deserializer<'de>>(de: D) -> Result<ibc::Height, D::Error> {
208+
use serde::de::Error;
209+
let height = <RawHeight as Deserialize>::deserialize(de)?;
210+
ibc::Height::try_from(height).map_err(|_| {
211+
D::Error::invalid_value(
212+
serde::de::Unexpected::Unsigned(0),
213+
&"height with non-zero revision_height",
214+
)
215+
})
170216
}
171-
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
172-
<Option<String>>::json_schema(gen)
217+
}
218+
219+
/// The core IBC height type, which represents the height of a chain, which
220+
/// typically is the number of blocks since genesis (or more generally, since
221+
/// the last revision/hard upgrade).
222+
#[derive(
223+
serde::Serialize,
224+
serde::Deserialize,
225+
schemars::JsonSchema,
226+
)]
227+
pub struct RawHeight {
228+
/// Previously known as "epoch"
229+
#[serde(default, skip_serializing_if = "is_zero")]
230+
pub revision_number: cosmwasm_std::Uint64,
231+
232+
/// The height of a block
233+
pub revision_height: cosmwasm_std::Uint64,
234+
}
235+
236+
impl TryFrom<RawHeight> for ibc::Height {
237+
type Error = ibc::ClientError;
238+
fn try_from(height: RawHeight) -> Result<Self, Self::Error> {
239+
Self::new(height.revision_number.into(), height.revision_height.into())
173240
}
174241
}
175242

176-
impl schemars::JsonSchema for AsStr {
243+
impl From<ibc::Height> for RawHeight {
244+
fn from(height: ibc::Height) -> Self {
245+
Self {
246+
revision_number: height.revision_number().into(),
247+
revision_height: height.revision_height().into(),
248+
}
249+
}
250+
}
251+
252+
impl schemars::JsonSchema for Height {
177253
fn schema_name() -> alloc::string::String {
178-
String::schema_name()
254+
"Height".into()
179255
}
180256
fn schema_id() -> alloc::borrow::Cow<'static, str> {
181-
String::schema_id()
257+
alloc::borrow::Cow::Borrowed("cf_guest::IbcHeight")
182258
}
183259
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
184-
String::json_schema(gen)
260+
<RawHeight>::json_schema(gen)
185261
}
186262
}
263+
264+
fn is_zero(num: &cosmwasm_std::Uint64) -> bool {
265+
num.u64() == 0
266+
}

light-clients/cf-guest-cw/src/state.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,10 @@ impl ConsensusStates {
149149
for record in self.all() {
150150
let (key, _state, metadata) = record?;
151151
let key = &key[key.len() - 16..];
152+
let revision_number = u64::from_be_bytes(key[..8].try_into().unwrap());
153+
let revision_height = u64::from_be_bytes(key[8..].try_into().unwrap());
152154
records.push(crate::msg::ConsensusStateMetadata {
153-
height: crate::msg::Height {
154-
revision_number: u64::from_be_bytes(key[..8].try_into().unwrap()).into(),
155-
revision_height: u64::from_be_bytes(key[8..].try_into().unwrap()).into(),
156-
},
155+
height: ibc::Height::new(revision_number, revision_height).unwrap(),
157156
host_timestamp_ns: metadata.host_timestamp_ns.into(),
158157
host_height: metadata.host_height.into(),
159158
})

0 commit comments

Comments
 (0)