Skip to content

Commit

Permalink
Fix MsgTimeoutOnClose to verify the proof of the channel (#2535)
Browse files Browse the repository at this point in the history
* fix message conversion and replace proof

* add change log

* add a test

* add a test

* fix typo

* fix for clippy
  • Loading branch information
yito88 authored Aug 10, 2022
1 parent 891d3f6 commit 6689313
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .changelog/unreleased/bug/2534-fix-timeout-on-close.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Fix MsgTimeoutOnClose ([#2534](https://github.com/informalsystems/ibc-
rs/issues/2534))
10 changes: 9 additions & 1 deletion modules/src/core/ics04_channel/handler/timeout_on_close.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::core::ics04_channel::{
use crate::events::IbcEvent;
use crate::handler::{HandlerOutput, HandlerResult};
use crate::prelude::*;
use crate::proofs::{ProofError, Proofs};

pub fn process(
ctx: &dyn ChannelReader,
Expand Down Expand Up @@ -75,13 +76,20 @@ pub fn process(
source_channel_end.version().clone(),
);

// The message's proofs have the channel proof as `other_proof`
let proof_close = match msg.proofs.other_proof() {
Some(p) => p.clone(),
None => return Err(Error::invalid_proof(ProofError::empty_proof())),
};
let proofs = Proofs::new(proof_close, None, None, None, msg.proofs.height())
.map_err(Error::invalid_proof)?;
verify_channel_proofs(
ctx,
msg.proofs.height(),
&source_channel_end,
&connection_end,
&expected_channel_end,
&msg.proofs,
&proofs,
)?;

let result = if source_channel_end.order_matches(&Order::Ordered) {
Expand Down
94 changes: 93 additions & 1 deletion modules/src/core/ics04_channel/msgs/timeout_on_close.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ impl TryFrom<RawMsgTimeoutOnClose> for MsgTimeoutOnClose {
.map_err(Error::invalid_proof)?,
None,
None,
None,
Some(
raw_msg
.proof_close
.try_into()
.map_err(Error::invalid_proof)?,
),
raw_msg
.proof_height
.and_then(|raw_height| raw_height.try_into().ok())
Expand Down Expand Up @@ -103,6 +108,93 @@ impl From<MsgTimeoutOnClose> for RawMsgTimeoutOnClose {
}
}

#[cfg(test)]
mod tests {
use crate::prelude::*;
use ibc_proto::ibc::core::channel::v1::MsgTimeoutOnClose as RawMsgTimeoutOnClose;
use test_log::test;

use crate::core::ics04_channel::msgs::timeout_on_close::test_util::get_dummy_raw_msg_timeout_on_close;
use crate::core::ics04_channel::msgs::timeout_on_close::MsgTimeoutOnClose;

#[test]
fn msg_timeout_on_close_try_from_raw() {
let height = 50;
let timeout_timestamp = 5;
let raw = get_dummy_raw_msg_timeout_on_close(height, timeout_timestamp);

let msg = MsgTimeoutOnClose::try_from(raw.clone()).unwrap();
let raw_back = RawMsgTimeoutOnClose::from(msg);
assert_eq!(raw, raw_back);
}

#[test]
fn parse_timeout_on_close_msg() {
struct Test {
name: String,
raw: RawMsgTimeoutOnClose,
want_pass: bool,
}

let height = 50;
let timeout_timestamp = 5;
let default_raw_msg = get_dummy_raw_msg_timeout_on_close(height, timeout_timestamp);

let tests: Vec<Test> = vec![
Test {
name: "Good parameters".to_string(),
raw: default_raw_msg.clone(),
want_pass: true,
},
Test {
name: "Missing packet".to_string(),
raw: RawMsgTimeoutOnClose {
packet: None,
..default_raw_msg.clone()
},
want_pass: false,
},
Test {
name: "Missing proof of unreceived packet".to_string(),
raw: RawMsgTimeoutOnClose {
proof_unreceived: Vec::new(),
..default_raw_msg.clone()
},
want_pass: false,
},
Test {
name: "Missing proof of channel".to_string(),
raw: RawMsgTimeoutOnClose {
proof_close: Vec::new(),
..default_raw_msg.clone()
},
want_pass: false,
},
Test {
name: "Missing proof height".to_string(),
raw: RawMsgTimeoutOnClose {
proof_height: None,
..default_raw_msg
},
want_pass: false,
},
];

for test in tests {
let res_msg = MsgTimeoutOnClose::try_from(test.raw.clone());

assert_eq!(
test.want_pass,
res_msg.is_ok(),
"MsgTimeoutOnClose::try_from raw failed for test {}, \nraw msg {:?} with error {:?}",
test.name,
test.raw,
res_msg.err(),
);
}
}
}

#[cfg(test)]
pub mod test_util {
use ibc_proto::ibc::core::channel::v1::MsgTimeoutOnClose as RawMsgTimeoutOnClose;
Expand Down

0 comments on commit 6689313

Please sign in to comment.