Skip to content

Commit 522aef1

Browse files
Implement upgrade client proposal handler (#680)
* Abstract upgrade client proposal handler * Replace all upgrade-related abstractions under tendermint host * Adjust encapsulation * Move handler & helper functions to basecoin * Add unclog * Refine upgrade client errors * Reorganize some types * Add docstring for upgrade client types * Re-add upgrade_client_proposal_handler * Make zero_custom_fields public * upgrade_client_proposal_handler not needed to return Vec<Event> * upgrade_proposal module dosctring --------- Co-authored-by: Philippe Laferriere <[email protected]>
1 parent 304cf0e commit 522aef1

File tree

24 files changed

+593
-54
lines changed

24 files changed

+593
-54
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- Support for upgrade client proposal by featuring helper contexts and domain types
2+
([#420](https://github.com/cosmos/ibc-rs/issues/420))
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- Clarify usage of `upgrade_path` for handling upgrade proposals
2+
([#141](https://github.com/cosmos/ibc-rs/issues/141))

crates/ibc/src/applications/transfer/context.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
//! Defines the main context traits and IBC module callbacks
2-
3-
use crate::core::router::ModuleExtras;
4-
use crate::core::ContextError;
52
use crate::prelude::*;
63

74
use sha2::{Digest, Sha256};
@@ -22,6 +19,8 @@ use crate::core::ics04_channel::context::{
2219
use crate::core::ics04_channel::packet::{Acknowledgement, Packet};
2320
use crate::core::ics04_channel::Version;
2421
use crate::core::ics24_host::identifier::{ChannelId, ConnectionId, PortId};
22+
use crate::core::router::ModuleExtras;
23+
use crate::core::ContextError;
2524
use crate::signer::Signer;
2625

2726
/// Methods required in token transfer validation, to be implemented by the host

crates/ibc/src/clients/ics07_tendermint/client_state.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use crate::core::ics02_client::client_state::{
3232
};
3333
use crate::core::ics02_client::client_type::ClientType;
3434
use crate::core::ics02_client::consensus_state::ConsensusState;
35-
use crate::core::ics02_client::error::ClientError;
35+
use crate::core::ics02_client::error::{ClientError, UpgradeClientError};
3636
use crate::core::ics23_commitment::commitment::{
3737
CommitmentPrefix, CommitmentProofBytes, CommitmentRoot,
3838
};
@@ -251,7 +251,7 @@ impl ClientState {
251251
}
252252

253253
// Resets custom fields to zero values (used in `update_client`)
254-
fn zero_custom_fields(&mut self) {
254+
pub fn zero_custom_fields(&mut self) {
255255
self.trusting_period = ZERO_DURATION;
256256
self.trust_level = TrustThreshold::ZERO;
257257
self.allow_update.after_expiry = false;
@@ -436,10 +436,10 @@ impl Ics2ClientState for ClientState {
436436
// the upgrade height This condition checks both the revision number and
437437
// the height
438438
if self.latest_height() >= upgraded_tm_client_state.latest_height() {
439-
return Err(ClientError::LowUpgradeHeight {
439+
return Err(UpgradeClientError::LowUpgradeHeight {
440440
upgraded_height: self.latest_height(),
441441
client_height: upgraded_tm_client_state.latest_height(),
442-
});
442+
})?;
443443
}
444444

445445
// Check to see if the upgrade path is set

crates/ibc/src/core/context.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
use crate::prelude::*;
2+
3+
use crate::signer::Signer;
4+
use alloc::string::String;
15
use core::time::Duration;
26
use displaydoc::Display;
37
use ibc_proto::google::protobuf::Any;
48

5-
use crate::prelude::*;
6-
use crate::signer::Signer;
7-
89
use crate::core::events::IbcEvent;
910
use crate::core::ics02_client::client_state::ClientState;
1011
use crate::core::ics02_client::consensus_state::ConsensusState;
@@ -17,7 +18,8 @@ use crate::core::ics03_connection::version::{
1718
use crate::core::ics04_channel::channel::ChannelEnd;
1819
use crate::core::ics04_channel::commitment::{AcknowledgementCommitment, PacketCommitment};
1920
use crate::core::ics04_channel::context::calculate_block_delay;
20-
use crate::core::ics04_channel::error::{ChannelError, PacketError};
21+
use crate::core::ics04_channel::error::ChannelError;
22+
use crate::core::ics04_channel::error::PacketError;
2123
use crate::core::ics04_channel::packet::{Receipt, Sequence};
2224
use crate::core::ics23_commitment::commitment::CommitmentPrefix;
2325
use crate::core::ics24_host::identifier::ClientId;

crates/ibc/src/core/handler.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use super::context::RouterError;
12
use super::ics02_client::handler::{create_client, update_client, upgrade_client};
23
use super::ics02_client::msgs::{ClientMsg, MsgUpdateOrMisbehaviour};
34
use super::ics03_connection::handler::{
@@ -28,7 +29,7 @@ use super::ics04_channel::handler::timeout::{
2829
};
2930
use super::ics04_channel::msgs::{ChannelMsg, PacketMsg};
3031
use super::ContextError;
31-
use super::{msgs::MsgEnvelope, ExecutionContext, RouterError, ValidationContext};
32+
use super::{msgs::MsgEnvelope, ExecutionContext, ValidationContext};
3233

3334
/// Entrypoint which performs both validation and message execution
3435
pub fn dispatch(ctx: &mut impl ExecutionContext, msg: MsgEnvelope) -> Result<(), RouterError> {

crates/ibc/src/core/ics02_client/error.rs

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! Defines the client error type
22
3-
use crate::core::ContextError;
43
use crate::prelude::*;
54

65
use displaydoc::Display;
@@ -10,11 +9,14 @@ use crate::core::ics02_client::client_type::ClientType;
109
use crate::core::ics23_commitment::error::CommitmentError;
1110
use crate::core::ics24_host::identifier::{ClientId, IdentifierError};
1211
use crate::core::timestamp::Timestamp;
12+
use crate::core::ContextError;
1313
use crate::Height;
1414

1515
/// Encodes all the possible client errors
1616
#[derive(Debug, Display)]
1717
pub enum ClientError {
18+
/// upgrade client error: `{0}`
19+
Upgrade(UpgradeClientError),
1820
/// Client identifier constructor failed for type `{client_type}` with counter `{counter}`, validation error: `{validation_error}`
1921
ClientIdentifierConstructor {
2022
client_type: ClientType,
@@ -76,10 +78,6 @@ pub enum ClientError {
7678
latest_height: Height,
7779
proof_height: Height,
7880
},
79-
/// invalid proof for the upgraded client state error: `{0}`
80-
InvalidUpgradeClientProof(CommitmentError),
81-
/// invalid proof for the upgraded consensus state error: `{0}`
82-
InvalidUpgradeConsensusStateProof(CommitmentError),
8381
/// invalid commitment proof bytes error: `{0}`
8482
InvalidCommitmentProof(CommitmentError),
8583
/// invalid packet timeout timestamp value error: `{0}`
@@ -91,11 +89,6 @@ pub enum ClientError {
9189
header_height: Height,
9290
latest_height: Height,
9391
},
94-
/// upgraded client height `{upgraded_height}` must be at greater than current client height `{client_height}`
95-
LowUpgradeHeight {
96-
upgraded_height: Height,
97-
client_height: Height,
98-
},
9992
/// timestamp is invalid or missing, timestamp=`{time1}`, now=`{time2}`
10093
InvalidConsensusStateTimestamp { time1: Timestamp, time2: Timestamp },
10194
/// header not within trusting period: expires_at=`{latest_time}` now=`{update_time}`
@@ -140,12 +133,47 @@ impl std::error::Error for ClientError {
140133
Self::InvalidClientIdentifier(e) => Some(e),
141134
Self::InvalidRawHeader(e) => Some(e),
142135
Self::InvalidRawMisbehaviour(e) => Some(e),
143-
Self::InvalidUpgradeClientProof(e) => Some(e),
144-
Self::InvalidUpgradeConsensusStateProof(e) => Some(e),
145136
Self::InvalidCommitmentProof(e) => Some(e),
146137
Self::InvalidPacketTimestamp(e) => Some(e),
147138
Self::Ics23Verification(e) => Some(e),
148139
_ => None,
149140
}
150141
}
151142
}
143+
144+
/// Encodes all the possible upgrade client errors
145+
#[derive(Debug, Display)]
146+
pub enum UpgradeClientError {
147+
/// invalid proof for the upgraded client state error: `{0}`
148+
InvalidUpgradeClientProof(CommitmentError),
149+
/// invalid proof for the upgraded consensus state error: `{0}`
150+
InvalidUpgradeConsensusStateProof(CommitmentError),
151+
/// upgraded client height `{upgraded_height}` must be at greater than current client height `{client_height}`
152+
LowUpgradeHeight {
153+
upgraded_height: Height,
154+
client_height: Height,
155+
},
156+
/// invalid upgrade proposal: `{reason}`
157+
InvalidUpgradeProposal { reason: String },
158+
/// invalid upgrade plan: `{reason}`
159+
InvalidUpgradePlan { reason: String },
160+
/// other upgrade client error: `{reason}`
161+
Other { reason: String },
162+
}
163+
164+
impl From<UpgradeClientError> for ClientError {
165+
fn from(e: UpgradeClientError) -> Self {
166+
ClientError::Upgrade(e)
167+
}
168+
}
169+
170+
#[cfg(feature = "std")]
171+
impl std::error::Error for UpgradeClientError {
172+
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
173+
match &self {
174+
Self::InvalidUpgradeClientProof(e) => Some(e),
175+
Self::InvalidUpgradeConsensusStateProof(e) => Some(e),
176+
_ => None,
177+
}
178+
}
179+
}

crates/ibc/src/core/ics02_client/handler/upgrade_client.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ mod tests {
106106
use crate::clients::ics07_tendermint::client_type;
107107
use crate::clients::ics07_tendermint::header::test_util::get_dummy_tendermint_header;
108108

109+
use crate::core::ics02_client::error::UpgradeClientError;
109110
use crate::core::ics03_connection::handler::test_util::{Expect, Fixture};
110111
use crate::core::ics24_host::identifier::ClientId;
111112
use crate::downcast;
@@ -233,12 +234,14 @@ mod tests {
233234

234235
#[test]
235236
fn upgrade_client_fail_low_upgrade_height() {
236-
let fxt = msg_upgrade_client_fixture(Ctx::WithClient, Msg::LowUpgradeHeight);
237-
let expected_err = ContextError::ClientError(ClientError::LowUpgradeHeight {
237+
let fxt: Fixture<MsgUpgradeClient> =
238+
msg_upgrade_client_fixture(Ctx::WithClient, Msg::LowUpgradeHeight);
239+
let expected_err: ClientError = UpgradeClientError::LowUpgradeHeight {
238240
upgraded_height: Height::new(0, 26).unwrap(),
239241
client_height: fxt.ctx.latest_height(),
240-
});
241-
upgrade_client_validate(&fxt, Expect::Failure(Some(expected_err)));
242+
}
243+
.into();
244+
upgrade_client_validate(&fxt, Expect::Failure(Some(expected_err.into())));
242245
}
243246

244247
#[test]

crates/ibc/src/core/ics02_client/msgs/upgrade_client.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use ibc_proto::ibc::core::client::v1::MsgUpgradeClient as RawMsgUpgradeClient;
99
use ibc_proto::ibc::core::commitment::v1::MerkleProof as RawMerkleProof;
1010
use ibc_proto::protobuf::Protobuf;
1111

12-
use crate::core::ics02_client::error::ClientError;
12+
use crate::core::ics02_client::error::{ClientError, UpgradeClientError};
1313
use crate::core::ics23_commitment::commitment::CommitmentProofBytes;
1414
use crate::core::ics23_commitment::error::CommitmentError;
1515
use crate::core::ics24_host::identifier::ClientId;
@@ -78,11 +78,13 @@ impl TryFrom<RawMsgUpgradeClient> for MsgUpgradeClient {
7878

7979
let c_bytes =
8080
CommitmentProofBytes::try_from(proto_msg.proof_upgrade_client).map_err(|_| {
81-
ClientError::InvalidUpgradeClientProof(CommitmentError::EmptyMerkleProof)
81+
UpgradeClientError::InvalidUpgradeClientProof(CommitmentError::EmptyMerkleProof)
8282
})?;
8383
let cs_bytes = CommitmentProofBytes::try_from(proto_msg.proof_upgrade_consensus_state)
8484
.map_err(|_| {
85-
ClientError::InvalidUpgradeConsensusStateProof(CommitmentError::EmptyMerkleProof)
85+
UpgradeClientError::InvalidUpgradeConsensusStateProof(
86+
CommitmentError::EmptyMerkleProof,
87+
)
8688
})?;
8789

8890
Ok(MsgUpgradeClient {
@@ -91,9 +93,9 @@ impl TryFrom<RawMsgUpgradeClient> for MsgUpgradeClient {
9193
client_state: raw_client_state,
9294
consensus_state: raw_consensus_state,
9395
proof_upgrade_client: RawMerkleProof::try_from(c_bytes)
94-
.map_err(ClientError::InvalidUpgradeClientProof)?,
96+
.map_err(UpgradeClientError::InvalidUpgradeClientProof)?,
9597
proof_upgrade_consensus_state: RawMerkleProof::try_from(cs_bytes)
96-
.map_err(ClientError::InvalidUpgradeConsensusStateProof)?,
98+
.map_err(UpgradeClientError::InvalidUpgradeConsensusStateProof)?,
9799
signer: proto_msg.signer.into(),
98100
})
99101
}

crates/ibc/src/core/ics04_channel/handler/acknowledgement.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ use crate::core::ics24_host::path::Path;
1212
use crate::core::ics24_host::path::{
1313
AckPath, ChannelEndPath, ClientConsensusStatePath, CommitmentPath, SeqAckPath,
1414
};
15-
use crate::core::{events::IbcEvent, ics04_channel::events::AcknowledgePacket, router::ModuleId};
15+
use crate::core::router::ModuleId;
16+
use crate::core::{events::IbcEvent, ics04_channel::events::AcknowledgePacket};
1617
use crate::core::{ContextError, ExecutionContext, ValidationContext};
1718

1819
pub(crate) fn acknowledgement_packet_validate<ValCtx>(

crates/ibc/src/core/ics04_channel/handler/timeout.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::prelude::*;
22
use prost::Message;
33

4+
use crate::core::events::IbcEvent;
45
use crate::core::events::MessageEvent;
56
use crate::core::ics03_connection::delay::verify_conn_delay_passed;
67
use crate::core::ics04_channel::channel::State;
@@ -11,15 +12,12 @@ use crate::core::ics04_channel::error::PacketError;
1112
use crate::core::ics04_channel::events::ChannelClosed;
1213
use crate::core::ics04_channel::msgs::timeout::MsgTimeout;
1314
use crate::core::ics04_channel::msgs::timeout_on_close::MsgTimeoutOnClose;
15+
use crate::core::ics04_channel::{events::TimeoutPacket, handler::timeout_on_close};
1416
use crate::core::ics24_host::path::Path;
1517
use crate::core::ics24_host::path::{
1618
ChannelEndPath, ClientConsensusStatePath, CommitmentPath, ReceiptPath, SeqRecvPath,
1719
};
18-
use crate::core::{
19-
events::IbcEvent,
20-
ics04_channel::{events::TimeoutPacket, handler::timeout_on_close},
21-
router::ModuleId,
22-
};
20+
use crate::core::router::ModuleId;
2321
use crate::core::{ContextError, ExecutionContext, ValidationContext};
2422

2523
pub(crate) enum TimeoutMsgType {

crates/ibc/src/core/msgs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use crate::core::RouterError;
21
use crate::prelude::*;
32

43
use ibc_proto::google::protobuf::Any;
54

5+
use crate::core::context::RouterError;
66
use crate::core::ics02_client::msgs::{
77
create_client, misbehaviour, update_client, upgrade_client, ClientMsg,
88
};

crates/ibc/src/core/router.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
//! Defines the `Router`, which binds modules to ports
22
3-
use crate::{core::events::ModuleEvent, prelude::*};
4-
3+
use crate::prelude::*;
54
use alloc::borrow::Borrow;
65
use core::fmt::{Debug, Display, Error as FmtError, Formatter};
76

7+
use crate::core::events::ModuleEvent;
88
use crate::core::ics04_channel::channel::{Counterparty, Order};
9-
use crate::core::ics04_channel::error::{ChannelError, PacketError, PortError::UnknownPort};
9+
use crate::core::ics04_channel::error::PortError::UnknownPort;
10+
use crate::core::ics04_channel::error::{ChannelError, PacketError};
1011
use crate::core::ics04_channel::msgs::ChannelMsg;
12+
use crate::core::ics04_channel::msgs::PacketMsg;
1113
use crate::core::ics04_channel::packet::{Acknowledgement, Packet};
1214
use crate::core::ics04_channel::Version;
13-
use crate::core::ics24_host::identifier::{ChannelId, ConnectionId, PortId};
15+
use crate::core::ics24_host::identifier::PortId;
16+
use crate::core::ics24_host::identifier::{ChannelId, ConnectionId};
1417
use crate::signer::Signer;
1518

16-
use super::ics04_channel::msgs::PacketMsg;
17-
1819
/// Router as defined in ICS-26, which binds modules to ports.
1920
pub trait Router {
2021
/// Returns a reference to a `Module` registered against the specified `ModuleId`

crates/ibc/src/hosts/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
//! Provides convenience implementations for various hosts
2-
32
pub mod tendermint;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//! Provides convenience implementations for Tendermint-based hosts
2+
3+
pub mod upgrade_proposal;
4+
5+
mod validate_self_client;
6+
pub use validate_self_client::ValidateSelfClientContext;
7+
8+
/// ABCI store/query path for the IBC sub-store
9+
pub const IBC_QUERY_PATH: &str = "store/ibc/key";
10+
11+
/// ABCI store/query path for the upgrade sub-store
12+
pub const SDK_UPGRADE_QUERY_PATH: &str = "store/upgrade/key";

0 commit comments

Comments
 (0)