Skip to content

Commit dc116da

Browse files
rnbguyseanchen1991
andauthored
imp(ibc-client): rm TryFrom<Error = ClientError> restriction (informalsystems#1204)
* rm concrete Error type * update ibc-core * update tm client * update cw-context * Convertible in reverse direction * update code * use Convertible<Any> * rm redundant bound --------- Co-authored-by: Sean Chen <[email protected]>
1 parent ed4f8cd commit dc116da

File tree

17 files changed

+127
-67
lines changed

17 files changed

+127
-67
lines changed

ibc-clients/cw-context/src/api.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ use crate::context::Context;
88
/// Enables users to integrate their implemented light client by introducing
99
/// their client state and consensus state types into the generic [`Context`]
1010
/// object.
11-
pub trait ClientType<'a>: Sized {
11+
pub trait ClientType<'a>: Sized
12+
where
13+
<Self::ClientState as TryFrom<Any>>::Error: Into<ClientError>,
14+
<Self::ConsensusState as TryFrom<Any>>::Error: Into<ClientError>,
15+
{
1216
type ClientState: ClientStateExecution<Context<'a, Self>> + Clone;
13-
type ConsensusState: ConsensusStateTrait + Into<Any> + TryFrom<Any, Error = ClientError>;
17+
type ConsensusState: ConsensusStateTrait;
1418
}

ibc-clients/cw-context/src/context/client_ctx.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ use crate::api::ClientType;
1616
use crate::context::CONSENSUS_STATE_HEIGHT_MAP;
1717
use crate::utils::AnyCodec;
1818

19-
impl<'a, C: ClientType<'a>> ClientValidationContext for Context<'a, C> {
19+
impl<'a, C: ClientType<'a>> ClientValidationContext for Context<'a, C>
20+
where
21+
<C::ClientState as TryFrom<Any>>::Error: Into<ClientError>,
22+
<C::ConsensusState as TryFrom<Any>>::Error: Into<ClientError>,
23+
{
2024
type ClientStateRef = C::ClientState;
2125
type ConsensusStateRef = C::ConsensusState;
2226

@@ -83,7 +87,11 @@ impl<'a, C: ClientType<'a>> ClientValidationContext for Context<'a, C> {
8387
}
8488
}
8589

86-
impl<'a, C: ClientType<'a>> ClientExecutionContext for Context<'a, C> {
90+
impl<'a, C: ClientType<'a>> ClientExecutionContext for Context<'a, C>
91+
where
92+
<C::ClientState as TryFrom<Any>>::Error: Into<ClientError>,
93+
<C::ConsensusState as TryFrom<Any>>::Error: Into<ClientError>,
94+
{
8795
type ClientStateMut = C::ClientState;
8896

8997
fn store_client_state(

ibc-clients/cw-context/src/context/custom_ctx.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,18 @@ use ibc_core::client::types::Height;
66
use ibc_core::handler::types::error::ContextError;
77
use ibc_core::host::types::identifiers::ClientId;
88
use ibc_core::host::types::path::ClientConsensusStatePath;
9+
use ibc_core::primitives::proto::Any;
910
use ibc_core::primitives::Timestamp;
1011

1112
use super::Context;
1213
use crate::api::ClientType;
1314
use crate::types::HeightTravel;
1415

15-
impl<'a, C: ClientType<'a>> ExtClientValidationContext for Context<'a, C> {
16+
impl<'a, C: ClientType<'a>> ExtClientValidationContext for Context<'a, C>
17+
where
18+
<C::ClientState as TryFrom<Any>>::Error: Into<ClientError>,
19+
<C::ConsensusState as TryFrom<Any>>::Error: Into<ClientError>,
20+
{
1621
fn host_timestamp(&self) -> Result<Timestamp, ContextError> {
1722
let time = self.env().block.time;
1823

ibc-clients/cw-context/src/context/mod.rs

+20-4
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ pub const CONSENSUS_STATE_HEIGHT_MAP: Map<'_, (u64, u64), Empty> =
3333

3434
/// Context is a wrapper around the deps and env that gives access to the
3535
/// methods under the ibc-rs Validation and Execution traits.
36-
pub struct Context<'a, C: ClientType<'a>> {
36+
pub struct Context<'a, C: ClientType<'a>>
37+
where
38+
<C::ClientState as TryFrom<Any>>::Error: Into<ClientError>,
39+
<C::ConsensusState as TryFrom<Any>>::Error: Into<ClientError>,
40+
{
3741
deps: Option<Deps<'a>>,
3842
deps_mut: Option<DepsMut<'a>>,
3943
env: Env,
@@ -43,7 +47,11 @@ pub struct Context<'a, C: ClientType<'a>> {
4347
client_type: std::marker::PhantomData<C>,
4448
}
4549

46-
impl<'a, C: ClientType<'a>> Context<'a, C> {
50+
impl<'a, C: ClientType<'a>> Context<'a, C>
51+
where
52+
<C::ClientState as TryFrom<Any>>::Error: Into<ClientError>,
53+
<C::ConsensusState as TryFrom<Any>>::Error: Into<ClientError>,
54+
{
4755
/// Constructs a new Context object with the given deps and env.
4856
pub fn new_ref(deps: Deps<'a>, env: Env) -> Result<Self, ContractError> {
4957
let client_id = ClientId::from_str(env.contract.address.as_str())?;
@@ -303,7 +311,11 @@ pub trait StorageRef {
303311
fn storage_ref(&self) -> &dyn Storage;
304312
}
305313

306-
impl<'a, C: ClientType<'a>> StorageRef for Context<'a, C> {
314+
impl<'a, C: ClientType<'a>> StorageRef for Context<'a, C>
315+
where
316+
<C::ClientState as TryFrom<Any>>::Error: Into<ClientError>,
317+
<C::ConsensusState as TryFrom<Any>>::Error: Into<ClientError>,
318+
{
307319
fn storage_ref(&self) -> &dyn Storage {
308320
match self.deps {
309321
Some(ref deps) => deps.storage,
@@ -319,7 +331,11 @@ pub trait StorageMut: StorageRef {
319331
fn storage_mut(&mut self) -> &mut dyn Storage;
320332
}
321333

322-
impl<'a, C: ClientType<'a>> StorageMut for Context<'a, C> {
334+
impl<'a, C: ClientType<'a>> StorageMut for Context<'a, C>
335+
where
336+
<C::ClientState as TryFrom<Any>>::Error: Into<ClientError>,
337+
<C::ConsensusState as TryFrom<Any>>::Error: Into<ClientError>,
338+
{
323339
fn storage_mut(&mut self) -> &mut dyn Storage {
324340
match self.deps_mut {
325341
Some(ref mut deps) => deps.storage,

ibc-clients/cw-context/src/handlers.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use cosmwasm_std::{to_json_binary, Binary};
22
use ibc_core::client::context::prelude::*;
3+
use ibc_core::client::types::error::ClientError;
34
use ibc_core::host::types::path::ClientConsensusStatePath;
45
use ibc_core::primitives::proto::Any;
56
use prost::Message;
@@ -13,12 +14,16 @@ use crate::types::{
1314
VerifyUpgradeAndUpdateStateMsg,
1415
};
1516

16-
impl<'a, C: ClientType<'a>> Context<'a, C> {
17+
impl<'a, C: ClientType<'a>> Context<'a, C>
18+
where
19+
<C::ClientState as TryFrom<Any>>::Error: Into<ClientError>,
20+
<C::ConsensusState as TryFrom<Any>>::Error: Into<ClientError>,
21+
{
1722
/// Instantiates a new client with the given [`InstantiateMsg`] message.
1823
pub fn instantiate(&mut self, msg: InstantiateMsg) -> Result<Binary, ContractError> {
1924
let any = Any::decode(&mut msg.client_state.as_slice())?;
2025

21-
let client_state = C::ClientState::try_from(any)?;
26+
let client_state = C::ClientState::try_from(any).map_err(Into::into)?;
2227

2328
let any_consensus_state = Any::decode(&mut msg.consensus_state.as_slice())?;
2429

ibc-clients/cw-context/src/utils/codec.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ use prost::Message;
77
pub trait AnyCodec {
88
fn decode_any_vec<C>(data: Vec<u8>) -> Result<C, ClientError>
99
where
10-
C: TryFrom<Any, Error = ClientError>,
10+
C: TryFrom<Any>,
11+
<C as TryFrom<Any>>::Error: Into<ClientError>,
1112
{
1213
let raw = Any::decode(&mut data.as_slice()).map_err(|e| ClientError::Other {
1314
description: e.to_string(),
1415
})?;
1516

16-
C::try_from(raw)
17+
C::try_from(raw).map_err(Into::into)
1718
}
1819

1920
fn encode_to_any_vec<C>(value: C) -> Vec<u8>
@@ -24,4 +25,4 @@ pub trait AnyCodec {
2425
}
2526
}
2627

27-
impl<T> AnyCodec for T where T: TryFrom<Any, Error = ClientError> + Into<Any> {}
28+
impl<T> AnyCodec for T where T: TryFrom<Any> + Into<Any> {}

ibc-clients/ics07-tendermint/src/client_state/execution.rs

+14-10
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ impl<E> ClientStateExecution<E> for ClientState
1515
where
1616
E: ExtClientExecutionContext,
1717
E::ClientStateRef: From<ClientStateType>,
18-
E::ConsensusStateRef: Convertible<ConsensusStateType, ClientError>,
18+
ConsensusStateType: Convertible<E::ConsensusStateRef>,
19+
<ConsensusStateType as TryFrom<E::ConsensusStateRef>>::Error: Into<ClientError>,
1920
{
2021
fn initialise(
2122
&self,
@@ -93,12 +94,12 @@ pub fn initialise<E>(
9394
where
9495
E: ExtClientExecutionContext,
9596
E::ClientStateRef: From<ClientStateType>,
96-
E::ConsensusStateRef: Convertible<ConsensusStateType, ClientError>,
97+
ConsensusStateType: Convertible<E::ConsensusStateRef>,
9798
{
9899
let host_timestamp = ExtClientValidationContext::host_timestamp(ctx)?;
99100
let host_height = ExtClientValidationContext::host_height(ctx)?;
100101

101-
let tm_consensus_state = ConsensusStateType::try_from(consensus_state)?;
102+
let tm_consensus_state: ConsensusStateType = consensus_state.try_into()?;
102103

103104
ctx.store_client_state(
104105
ClientStatePath::new(client_id.clone()),
@@ -138,7 +139,8 @@ pub fn update_state<E>(
138139
where
139140
E: ExtClientExecutionContext,
140141
E::ClientStateRef: From<ClientStateType>,
141-
E::ConsensusStateRef: Convertible<ConsensusStateType, ClientError>,
142+
ConsensusStateType: Convertible<E::ConsensusStateRef>,
143+
<ConsensusStateType as TryFrom<E::ConsensusStateRef>>::Error: Into<ClientError>,
142144
{
143145
let header = TmHeader::try_from(header)?;
144146
let header_height = header.height();
@@ -237,10 +239,10 @@ pub fn update_on_upgrade<E>(
237239
where
238240
E: ExtClientExecutionContext,
239241
E::ClientStateRef: From<ClientStateType>,
240-
E::ConsensusStateRef: Convertible<ConsensusStateType, ClientError>,
242+
ConsensusStateType: Convertible<E::ConsensusStateRef>,
241243
{
242244
let mut upgraded_tm_client_state = ClientState::try_from(upgraded_client_state)?;
243-
let upgraded_tm_cons_state = ConsensusStateType::try_from(upgraded_consensus_state)?;
245+
let upgraded_tm_cons_state: ConsensusStateType = upgraded_consensus_state.try_into()?;
244246

245247
upgraded_tm_client_state.0.zero_custom_fields();
246248

@@ -317,7 +319,8 @@ pub fn prune_oldest_consensus_state<E>(
317319
where
318320
E: ClientExecutionContext + ExtClientValidationContext,
319321
E::ClientStateRef: From<ClientStateType>,
320-
E::ConsensusStateRef: Convertible<ConsensusStateType, ClientError>,
322+
ConsensusStateType: Convertible<E::ConsensusStateRef>,
323+
<ConsensusStateType as TryFrom<E::ConsensusStateRef>>::Error: Into<ClientError>,
321324
{
322325
let mut heights = ctx.consensus_state_heights(client_id)?;
323326

@@ -330,7 +333,8 @@ where
330333
height.revision_height(),
331334
);
332335
let consensus_state = ctx.consensus_state(&client_consensus_state_path)?;
333-
let tm_consensus_state = consensus_state.try_into()?;
336+
let tm_consensus_state: ConsensusStateType =
337+
consensus_state.try_into().map_err(Into::into)?;
334338

335339
let host_timestamp =
336340
ctx.host_timestamp()?
@@ -380,7 +384,7 @@ pub fn update_on_recovery<E>(
380384
where
381385
E: ExtClientExecutionContext,
382386
E::ClientStateRef: From<ClientStateType>,
383-
E::ConsensusStateRef: Convertible<ConsensusStateType, ClientError>,
387+
ConsensusStateType: Convertible<E::ConsensusStateRef>,
384388
{
385389
let substitute_client_state = ClientState::try_from(substitute_client_state)?
386390
.inner()
@@ -401,7 +405,7 @@ where
401405
let host_timestamp = E::host_timestamp(ctx)?;
402406
let host_height = E::host_height(ctx)?;
403407

404-
let tm_consensus_state = ConsensusStateType::try_from(substitute_consensus_state)?;
408+
let tm_consensus_state: ConsensusStateType = substitute_consensus_state.try_into()?;
405409

406410
ctx.store_consensus_state(
407411
ClientConsensusStatePath::new(

ibc-clients/ics07-tendermint/src/client_state/misbehaviour.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -28,33 +28,34 @@ pub fn verify_misbehaviour<V, H>(
2828
) -> Result<(), ClientError>
2929
where
3030
V: ExtClientValidationContext,
31-
V::ConsensusStateRef: Convertible<ConsensusStateType, ClientError>,
31+
ConsensusStateType: Convertible<V::ConsensusStateRef>,
32+
<ConsensusStateType as TryFrom<V::ConsensusStateRef>>::Error: Into<ClientError>,
3233
H: MerkleHash + Sha256 + Default,
3334
{
3435
misbehaviour.validate_basic::<H>()?;
3536

3637
let header_1 = misbehaviour.header1();
37-
let trusted_consensus_state_1 = {
38+
let trusted_consensus_state_1: ConsensusStateType = {
3839
let consensus_state_path = ClientConsensusStatePath::new(
3940
client_id.clone(),
4041
header_1.trusted_height.revision_number(),
4142
header_1.trusted_height.revision_height(),
4243
);
4344
let consensus_state = ctx.consensus_state(&consensus_state_path)?;
4445

45-
consensus_state.try_into()?
46+
consensus_state.try_into().map_err(Into::into)?
4647
};
4748

4849
let header_2 = misbehaviour.header2();
49-
let trusted_consensus_state_2 = {
50+
let trusted_consensus_state_2: ConsensusStateType = {
5051
let consensus_state_path = ClientConsensusStatePath::new(
5152
client_id.clone(),
5253
header_2.trusted_height.revision_number(),
5354
header_2.trusted_height.revision_height(),
5455
);
5556
let consensus_state = ctx.consensus_state(&consensus_state_path)?;
5657

57-
consensus_state.try_into()?
58+
consensus_state.try_into().map_err(Into::into)?
5859
};
5960

6061
let current_timestamp = ctx.host_timestamp()?;

ibc-clients/ics07-tendermint/src/client_state/update_client.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ pub fn verify_header<V, H>(
2222
) -> Result<(), ClientError>
2323
where
2424
V: ExtClientValidationContext,
25-
V::ConsensusStateRef: Convertible<ConsensusStateType, ClientError>,
25+
ConsensusStateType: Convertible<V::ConsensusStateRef>,
26+
<ConsensusStateType as TryFrom<V::ConsensusStateRef>>::Error: Into<ClientError>,
2627
H: MerkleHash + Sha256 + Default,
2728
{
2829
// Checks that the header fields are valid.
@@ -41,9 +42,10 @@ where
4142
header.trusted_height.revision_number(),
4243
header.trusted_height.revision_height(),
4344
);
44-
let trusted_consensus_state = ctx
45+
let trusted_consensus_state: ConsensusStateType = ctx
4546
.consensus_state(&trusted_client_cons_state_path)?
46-
.try_into()?;
47+
.try_into()
48+
.map_err(Into::into)?;
4749

4850
header.check_trusted_next_validator_set::<H>(
4951
&trusted_consensus_state.next_validators_hash,
@@ -107,7 +109,8 @@ pub fn check_for_misbehaviour_on_update<V>(
107109
) -> Result<bool, ClientError>
108110
where
109111
V: ExtClientValidationContext,
110-
V::ConsensusStateRef: Convertible<ConsensusStateType, ClientError>,
112+
ConsensusStateType: Convertible<V::ConsensusStateRef>,
113+
<ConsensusStateType as TryFrom<V::ConsensusStateRef>>::Error: Into<ClientError>,
111114
{
112115
let maybe_existing_consensus_state = {
113116
let path_at_header_height = ClientConsensusStatePath::new(
@@ -120,7 +123,8 @@ where
120123
};
121124

122125
if let Some(existing_consensus_state) = maybe_existing_consensus_state {
123-
let existing_consensus_state = existing_consensus_state.try_into()?;
126+
let existing_consensus_state: ConsensusStateType =
127+
existing_consensus_state.try_into().map_err(Into::into)?;
124128

125129
let header_consensus_state = ConsensusStateType::from(header);
126130

@@ -138,7 +142,7 @@ where
138142
if let Some(prev_cs) = maybe_prev_cs {
139143
// New header timestamp cannot occur *before* the
140144
// previous consensus state's height
141-
let prev_cs = prev_cs.try_into()?;
145+
let prev_cs: ConsensusStateType = prev_cs.try_into().map_err(Into::into)?;
142146

143147
if header.signed_header.header().time <= prev_cs.timestamp() {
144148
return Ok(true);
@@ -154,7 +158,7 @@ where
154158
if let Some(next_cs) = maybe_next_cs {
155159
// New (untrusted) header timestamp cannot occur *after* next
156160
// consensus state's height
157-
let next_cs = next_cs.try_into()?;
161+
let next_cs: ConsensusStateType = next_cs.try_into().map_err(Into::into)?;
158162

159163
if header.signed_header.header().time >= next_cs.timestamp() {
160164
return Ok(true);

0 commit comments

Comments
 (0)