Repository: CosmWasm/cosmwasm (rust)

Issue:
Implement From<IbcTimeoutBlock> for IbcTimeout

Pull request:
Change IbcTimeout back to struct
Closes #904 among other problems

Let's merge #906 first. Then I will rebase and recompile the dev contract.

Patch:
diff --git a/IBC.md b/IBC.md
index a700ff0ef..7d88c41b8 100644
--- a/IBC.md
+++ b/IBC.md
@@ -42,18 +42,9 @@ pub enum IbcMsg {
 /// two timeout fields we ensure that at least one timeout is set.
 #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
 #[serde(rename_all = "snake_case")]
-pub enum IbcTimeout {
-    /// Block timestamp (nanoseconds since UNIX epoch) after which the packet times out
-    /// (measured on the remote chain).
-    Timestamp(Timestamp),
-    /// Block after which the packet times out (measured on remote chain).
-    Block(IbcTimeoutBlock),
-    /// Use this to set both timestamp and block timeout. The package then times out once
-    /// the first of both timeouts is hit.
-    Both {
-        timestamp: Timestamp,
-        block: IbcTimeoutBlock,
-    },
+pub struct IbcTimeout {
+    block: Option<IbcTimeoutBlock>,
+    timestamp: Option<Timestamp>,
 }
 ```
 
@@ -309,13 +300,7 @@ pub struct IbcPacket {
     pub dest: IbcEndpoint,
     /// The sequence number of the packet on the given channel
     pub sequence: u64,
-    /// block height after which the packet times out.
-    /// at least one of timeout_block, timeout_timestamp is required
-    pub timeout_block: Option<IbcTimeoutBlock>,
-    /// block timestamp (nanoseconds since UNIX epoch) after which the packet times out.
-    /// See https://golang.org/pkg/time/#Time.UnixNano
-    /// at least one of timeout_block, timeout_timestamp is required
-    pub timeout_timestamp: Option<u64>,
+    pub timeout: IbcTimeout,
 }
 ```
 
diff --git a/contracts/ibc-reflect-send/schema/execute_msg.json b/contracts/ibc-reflect-send/schema/execute_msg.json
index 8a78e7b62..9cdc80374 100644
--- a/contracts/ibc-reflect-send/schema/execute_msg.json
+++ b/contracts/ibc-reflect-send/schema/execute_msg.json
@@ -436,59 +436,29 @@
     },
     "IbcTimeout": {
       "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.",
-      "anyOf": [
-        {
-          "description": "Block timestamp (nanoseconds since UNIX epoch) after which the packet times out (measured on the remote chain).",
-          "type": "object",
-          "required": [
-            "timestamp"
-          ],
-          "properties": {
-            "timestamp": {
-              "$ref": "#/definitions/Timestamp"
-            }
-          },
-          "additionalProperties": false
-        },
-        {
-          "description": "Block after which the packet times out (measured on remote chain).",
-          "type": "object",
-          "required": [
-            "block"
-          ],
-          "properties": {
-            "block": {
+      "type": "object",
+      "properties": {
+        "block": {
+          "anyOf": [
+            {
               "$ref": "#/definitions/IbcTimeoutBlock"
+            },
+            {
+              "type": "null"
             }
-          },
-          "additionalProperties": false
+          ]
         },
-        {
-          "description": "Use this to set both timestamp and block timeout. The package then times out once the first of both timeouts is hit.",
-          "type": "object",
-          "required": [
-            "both"
-          ],
-          "properties": {
-            "both": {
-              "type": "object",
-              "required": [
-                "block",
-                "timestamp"
-              ],
-              "properties": {
-                "block": {
-                  "$ref": "#/definitions/IbcTimeoutBlock"
-                },
-                "timestamp": {
-                  "$ref": "#/definitions/Timestamp"
-                }
-              }
+        "timestamp": {
+          "anyOf": [
+            {
+              "$ref": "#/definitions/Timestamp"
+            },
+            {
+              "type": "null"
             }
-          },
-          "additionalProperties": false
+          ]
         }
-      ]
+      }
     },
     "IbcTimeoutBlock": {
       "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)",
diff --git a/contracts/ibc-reflect-send/schema/packet_msg.json b/contracts/ibc-reflect-send/schema/packet_msg.json
index 502f680ad..10a883280 100644
--- a/contracts/ibc-reflect-send/schema/packet_msg.json
+++ b/contracts/ibc-reflect-send/schema/packet_msg.json
@@ -389,59 +389,29 @@
     },
     "IbcTimeout": {
       "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.",
-      "anyOf": [
-        {
-          "description": "Block timestamp (nanoseconds since UNIX epoch) after which the packet times out (measured on the remote chain).",
-          "type": "object",
-          "required": [
-            "timestamp"
-          ],
-          "properties": {
-            "timestamp": {
-              "$ref": "#/definitions/Timestamp"
-            }
-          },
-          "additionalProperties": false
-        },
-        {
-          "description": "Block after which the packet times out (measured on remote chain).",
-          "type": "object",
-          "required": [
-            "block"
-          ],
-          "properties": {
-            "block": {
+      "type": "object",
+      "properties": {
+        "block": {
+          "anyOf": [
+            {
               "$ref": "#/definitions/IbcTimeoutBlock"
+            },
+            {
+              "type": "null"
             }
-          },
-          "additionalProperties": false
+          ]
         },
-        {
-          "description": "Use this to set both timestamp and block timeout. The package then times out once the first of both timeouts is hit.",
-          "type": "object",
-          "required": [
-            "both"
-          ],
-          "properties": {
-            "both": {
-              "type": "object",
-              "required": [
-                "block",
-                "timestamp"
-              ],
-              "properties": {
-                "block": {
-                  "$ref": "#/definitions/IbcTimeoutBlock"
-                },
-                "timestamp": {
-                  "$ref": "#/definitions/Timestamp"
-                }
-              }
+        "timestamp": {
+          "anyOf": [
+            {
+              "$ref": "#/definitions/Timestamp"
+            },
+            {
+              "type": "null"
             }
-          },
-          "additionalProperties": false
+          ]
         }
-      ]
+      }
     },
     "IbcTimeoutBlock": {
       "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)",
diff --git a/contracts/ibc-reflect-send/src/ibc.rs b/contracts/ibc-reflect-send/src/ibc.rs
index 2be0b1ed5..2a6d8f270 100644
--- a/contracts/ibc-reflect-send/src/ibc.rs
+++ b/contracts/ibc-reflect-send/src/ibc.rs
@@ -255,7 +255,7 @@ mod tests {
         mock_dependencies, mock_env, mock_ibc_channel, mock_ibc_packet_ack, mock_info, MockApi,
         MockQuerier, MockStorage,
     };
-    use cosmwasm_std::{coin, coins, BankMsg, CosmosMsg, IbcTimeout, OwnedDeps};
+    use cosmwasm_std::{coin, coins, BankMsg, CosmosMsg, OwnedDeps};
 
     const CREATOR: &str = "creator";
 
@@ -445,7 +445,8 @@ mod tests {
                 assert_eq!(transfer_channel_id, channel_id.as_str());
                 assert_eq!(remote_addr, to_address.as_str());
                 assert_eq!(&coin(12344, "utrgd"), amount);
-                assert!(matches!(timeout, IbcTimeout::Timestamp { .. }));
+                assert!(timeout.block().is_none());
+                assert!(timeout.timestamp().is_some());
             }
             o => panic!("unexpected message: {:?}", o),
         }
diff --git a/contracts/ibc-reflect/schema/packet_msg.json b/contracts/ibc-reflect/schema/packet_msg.json
index a16d8cb3f..01be18064 100644
--- a/contracts/ibc-reflect/schema/packet_msg.json
+++ b/contracts/ibc-reflect/schema/packet_msg.json
@@ -388,59 +388,29 @@
     },
     "IbcTimeout": {
       "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.",
-      "anyOf": [
-        {
-          "description": "Block timestamp (nanoseconds since UNIX epoch) after which the packet times out (measured on the remote chain).",
-          "type": "object",
-          "required": [
-            "timestamp"
-          ],
-          "properties": {
-            "timestamp": {
-              "$ref": "#/definitions/Timestamp"
-            }
-          },
-          "additionalProperties": false
-        },
-        {
-          "description": "Block after which the packet times out (measured on remote chain).",
-          "type": "object",
-          "required": [
-            "block"
-          ],
-          "properties": {
-            "block": {
+      "type": "object",
+      "properties": {
+        "block": {
+          "anyOf": [
+            {
               "$ref": "#/definitions/IbcTimeoutBlock"
+            },
+            {
+              "type": "null"
             }
-          },
-          "additionalProperties": false
+          ]
         },
-        {
-          "description": "Use this to set both timestamp and block timeout. The package then times out once the first of both timeouts is hit.",
-          "type": "object",
-          "required": [
-            "both"
-          ],
-          "properties": {
-            "both": {
-              "type": "object",
-              "required": [
-                "block",
-                "timestamp"
-              ],
-              "properties": {
-                "block": {
-                  "$ref": "#/definitions/IbcTimeoutBlock"
-                },
-                "timestamp": {
-                  "$ref": "#/definitions/Timestamp"
-                }
-              }
+        "timestamp": {
+          "anyOf": [
+            {
+              "$ref": "#/definitions/Timestamp"
+            },
+            {
+              "type": "null"
             }
-          },
-          "additionalProperties": false
+          ]
         }
-      ]
+      }
     },
     "IbcTimeoutBlock": {
       "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)",
diff --git a/contracts/reflect/schema/execute_msg.json b/contracts/reflect/schema/execute_msg.json
index 6e2cc1611..1f9c2d87d 100644
--- a/contracts/reflect/schema/execute_msg.json
+++ b/contracts/reflect/schema/execute_msg.json
@@ -432,59 +432,29 @@
     },
     "IbcTimeout": {
       "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.",
-      "anyOf": [
-        {
-          "description": "Block timestamp (nanoseconds since UNIX epoch) after which the packet times out (measured on the remote chain).",
-          "type": "object",
-          "required": [
-            "timestamp"
-          ],
-          "properties": {
-            "timestamp": {
-              "$ref": "#/definitions/Timestamp"
-            }
-          },
-          "additionalProperties": false
-        },
-        {
-          "description": "Block after which the packet times out (measured on remote chain).",
-          "type": "object",
-          "required": [
-            "block"
-          ],
-          "properties": {
-            "block": {
+      "type": "object",
+      "properties": {
+        "block": {
+          "anyOf": [
+            {
               "$ref": "#/definitions/IbcTimeoutBlock"
+            },
+            {
+              "type": "null"
             }
-          },
-          "additionalProperties": false
+          ]
         },
-        {
-          "description": "Use this to set both timestamp and block timeout. The package then times out once the first of both timeouts is hit.",
-          "type": "object",
-          "required": [
-            "both"
-          ],
-          "properties": {
-            "both": {
-              "type": "object",
-              "required": [
-                "block",
-                "timestamp"
-              ],
-              "properties": {
-                "block": {
-                  "$ref": "#/definitions/IbcTimeoutBlock"
-                },
-                "timestamp": {
-                  "$ref": "#/definitions/Timestamp"
-                }
-              }
+        "timestamp": {
+          "anyOf": [
+            {
+              "$ref": "#/definitions/Timestamp"
+            },
+            {
+              "type": "null"
             }
-          },
-          "additionalProperties": false
+          ]
         }
-      ]
+      }
     },
     "IbcTimeoutBlock": {
       "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)",
diff --git a/contracts/reflect/schema/response_for__custom_msg.json b/contracts/reflect/schema/response_for__custom_msg.json
index 3fffad4ac..ff9dd4a27 100644
--- a/contracts/reflect/schema/response_for__custom_msg.json
+++ b/contracts/reflect/schema/response_for__custom_msg.json
@@ -420,59 +420,29 @@
     },
     "IbcTimeout": {
       "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.",
-      "anyOf": [
-        {
-          "description": "Block timestamp (nanoseconds since UNIX epoch) after which the packet times out (measured on the remote chain).",
-          "type": "object",
-          "required": [
-            "timestamp"
-          ],
-          "properties": {
-            "timestamp": {
-              "$ref": "#/definitions/Timestamp"
-            }
-          },
-          "additionalProperties": false
-        },
-        {
-          "description": "Block after which the packet times out (measured on remote chain).",
-          "type": "object",
-          "required": [
-            "block"
-          ],
-          "properties": {
-            "block": {
+      "type": "object",
+      "properties": {
+        "block": {
+          "anyOf": [
+            {
               "$ref": "#/definitions/IbcTimeoutBlock"
+            },
+            {
+              "type": "null"
             }
-          },
-          "additionalProperties": false
+          ]
         },
-        {
-          "description": "Use this to set both timestamp and block timeout. The package then times out once the first of both timeouts is hit.",
-          "type": "object",
-          "required": [
-            "both"
-          ],
-          "properties": {
-            "both": {
-              "type": "object",
-              "required": [
-                "block",
-                "timestamp"
-              ],
-              "properties": {
-                "block": {
-                  "$ref": "#/definitions/IbcTimeoutBlock"
-                },
-                "timestamp": {
-                  "$ref": "#/definitions/Timestamp"
-                }
-              }
+        "timestamp": {
+          "anyOf": [
+            {
+              "$ref": "#/definitions/Timestamp"
+            },
+            {
+              "type": "null"
             }
-          },
-          "additionalProperties": false
+          ]
         }
-      ]
+      }
     },
     "IbcTimeoutBlock": {
       "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)",
diff --git a/packages/std/src/ibc.rs b/packages/std/src/ibc.rs
index 147812cc2..9179cc320 100644
--- a/packages/std/src/ibc.rs
+++ b/packages/std/src/ibc.rs
@@ -59,23 +59,52 @@ pub struct IbcEndpoint {
 /// two timeout fields we ensure that at least one timeout is set.
 #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
 #[serde(rename_all = "snake_case")]
-pub enum IbcTimeout {
-    /// Block timestamp (nanoseconds since UNIX epoch) after which the packet times out
-    /// (measured on the remote chain).
-    Timestamp(Timestamp),
-    /// Block after which the packet times out (measured on remote chain).
-    Block(IbcTimeoutBlock),
-    /// Use this to set both timestamp and block timeout. The package then times out once
-    /// the first of both timeouts is hit.
-    Both {
-        timestamp: Timestamp,
-        block: IbcTimeoutBlock,
-    },
+pub struct IbcTimeout {
+    // use private fields to enforce the use of constructors, which ensure that at least one is set
+    block: Option<IbcTimeoutBlock>,
+    timestamp: Option<Timestamp>,
+}
+
+impl IbcTimeout {
+    pub fn with_block(block: IbcTimeoutBlock) -> Self {
+        IbcTimeout {
+            block: Some(block),
+            timestamp: None,
+        }
+    }
+
+    pub fn with_timestamp(timestamp: Timestamp) -> Self {
+        IbcTimeout {
+            block: None,
+            timestamp: Some(timestamp),
+        }
+    }
+
+    pub fn with_both(block: IbcTimeoutBlock, timestamp: Timestamp) -> Self {
+        IbcTimeout {
+            block: Some(block),
+            timestamp: Some(timestamp),
+        }
+    }
+
+    pub fn block(&self) -> Option<IbcTimeoutBlock> {
+        self.block
+    }
+
+    pub fn timestamp(&self) -> Option<Timestamp> {
+        self.timestamp
+    }
 }
 
 impl From<Timestamp> for IbcTimeout {
     fn from(timestamp: Timestamp) -> IbcTimeout {
-        IbcTimeout::Timestamp(timestamp)
+        IbcTimeout::with_timestamp(timestamp)
+    }
+}
+
+impl From<IbcTimeoutBlock> for IbcTimeout {
+    fn from(original: IbcTimeoutBlock) -> IbcTimeout {
+        IbcTimeout::with_block(original)
     }
 }
 
@@ -111,7 +140,7 @@ pub enum IbcOrder {
 /// that can be compared against another Height for the purposes of updating and
 /// freezing clients.
 /// Ordering is (revision_number, timeout_height)
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
+#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq, JsonSchema)]
 pub struct IbcTimeoutBlock {
     /// the version that the client is currently on
     /// (eg. after reseting the chain this could increment 1 as height drops to 0)
@@ -152,15 +181,7 @@ pub struct IbcPacket {
     pub dest: IbcEndpoint,
     /// The sequence number of the packet on the given channel
     pub sequence: u64,
-    // TODO: use IbcTimeout here as well? I doubt this is easier to parse and this
-    // is data coming from SDK -> contract
-    /// block height after which the packet times out.
-    /// at least one of timeout_block, timeout_timestamp is required
-    pub timeout_block: Option<IbcTimeoutBlock>,
-    /// block timestamp (nanoseconds since UNIX epoch) after which the packet times out.
-    /// See https://golang.org/pkg/time/#Time.UnixNano
-    /// at least one of timeout_block, timeout_timestamp is required
-    pub timeout_timestamp: Option<u64>,
+    pub timeout: IbcTimeout,
 }
 
 #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
@@ -257,13 +278,37 @@ mod tests {
             channel_id: "channel-123".to_string(),
             to_address: "my-special-addr".into(),
             amount: Coin::new(12345678, "uatom"),
-            timeout: IbcTimeout::Timestamp(Timestamp::from_nanos(1234567890)),
+            timeout: IbcTimeout::with_timestamp(Timestamp::from_nanos(1234567890)),
         };
         let encoded = to_string(&msg).unwrap();
-        let expected = r#"{"transfer":{"channel_id":"channel-123","to_address":"my-special-addr","amount":{"denom":"uatom","amount":"12345678"},"timeout":{"timestamp":"1234567890"}}}"#;
+        let expected = r#"{"transfer":{"channel_id":"channel-123","to_address":"my-special-addr","amount":{"denom":"uatom","amount":"12345678"},"timeout":{"block":null,"timestamp":"1234567890"}}}"#;
         assert_eq!(encoded.as_str(), expected);
     }
 
+    #[test]
+    fn ibc_timeout_serialize() {
+        let timestamp = IbcTimeout::with_timestamp(Timestamp::from_nanos(684816844));
+        let expected = r#"{"block":null,"timestamp":"684816844"}"#;
+        assert_eq!(to_string(&timestamp).unwrap(), expected);
+
+        let block = IbcTimeout::with_block(IbcTimeoutBlock {
+            revision: 12,
+            height: 129,
+        });
+        let expected = r#"{"block":{"revision":12,"height":129},"timestamp":null}"#;
+        assert_eq!(to_string(&block).unwrap(), expected);
+
+        let both = IbcTimeout::with_both(
+            IbcTimeoutBlock {
+                revision: 12,
+                height: 129,
+            },
+            Timestamp::from_nanos(684816844),
+        );
+        let expected = r#"{"block":{"revision":12,"height":129},"timestamp":"684816844"}"#;
+        assert_eq!(to_string(&both).unwrap(), expected);
+    }
+
     #[test]
     fn ibc_timeout_block_ord() {
         let epoch1a = IbcTimeoutBlock {
@@ -301,4 +346,48 @@ mod tests {
         assert!(epoch2a < epoch2b);
         assert!(epoch1b < epoch2b);
     }
+
+    #[test]
+    fn ibc_packet_serialize() {
+        let packet = IbcPacket {
+            data: b"foo".into(),
+            src: IbcEndpoint {
+                port_id: "their-port".to_string(),
+                channel_id: "channel-1234".to_string(),
+            },
+            dest: IbcEndpoint {
+                port_id: "our-port".to_string(),
+                channel_id: "chan33".into(),
+            },
+            sequence: 27,
+            timeout: IbcTimeout::with_both(
+                IbcTimeoutBlock {
+                    revision: 1,
+                    height: 12345678,
+                },
+                Timestamp::from_nanos(4611686018427387904),
+            ),
+        };
+        let expected = r#"{"data":"Zm9v","src":{"port_id":"their-port","channel_id":"channel-1234"},"dest":{"port_id":"our-port","channel_id":"chan33"},"sequence":27,"timeout":{"block":{"revision":1,"height":12345678},"timestamp":"4611686018427387904"}}"#;
+        assert_eq!(to_string(&packet).unwrap(), expected);
+
+        let no_timestamp = IbcPacket {
+            data: b"foo".into(),
+            src: IbcEndpoint {
+                port_id: "their-port".to_string(),
+                channel_id: "channel-1234".to_string(),
+            },
+            dest: IbcEndpoint {
+                port_id: "our-port".to_string(),
+                channel_id: "chan33".into(),
+            },
+            sequence: 27,
+            timeout: IbcTimeout::with_block(IbcTimeoutBlock {
+                revision: 1,
+                height: 12345678,
+            }),
+        };
+        let expected = r#"{"data":"Zm9v","src":{"port_id":"their-port","channel_id":"channel-1234"},"dest":{"port_id":"our-port","channel_id":"chan33"},"sequence":27,"timeout":{"block":{"revision":1,"height":12345678},"timestamp":null}}"#;
+        assert_eq!(to_string(&no_timestamp).unwrap(), expected);
+    }
 }
diff --git a/packages/std/src/mock.rs b/packages/std/src/mock.rs
index 33a2ad20c..cf076fe3c 100644
--- a/packages/std/src/mock.rs
+++ b/packages/std/src/mock.rs
@@ -243,11 +243,11 @@ pub fn mock_ibc_packet_recv<T: Serialize>(my_channel_id: &str, data: &T) -> StdR
             channel_id: my_channel_id.into(),
         },
         sequence: 27,
-        timeout_block: Some(IbcTimeoutBlock {
+        timeout: IbcTimeoutBlock {
             revision: 1,
             height: 12345678,
-        }),
-        timeout_timestamp: None,
+        }
+        .into(),
     })
 }
 
@@ -267,11 +267,11 @@ pub fn mock_ibc_packet_ack<T: Serialize>(my_channel_id: &str, data: &T) -> StdRe
             channel_id: "channel-1234".to_string(),
         },
         sequence: 29,
-        timeout_block: Some(IbcTimeoutBlock {
+        timeout: IbcTimeoutBlock {
             revision: 1,
             height: 432332552,
-        }),
-        timeout_timestamp: None,
+        }
+        .into(),
     })
 }
 


Test patch:
diff --git a/contracts/ibc-reflect-send/tests/integration.rs b/contracts/ibc-reflect-send/tests/integration.rs
index 97743f104..60267c994 100644
--- a/contracts/ibc-reflect-send/tests/integration.rs
+++ b/contracts/ibc-reflect-send/tests/integration.rs
@@ -20,7 +20,7 @@
 use cosmwasm_std::testing::{mock_ibc_channel, mock_ibc_packet_ack};
 use cosmwasm_std::{
     attr, coin, coins, to_binary, BankMsg, CosmosMsg, Empty, IbcAcknowledgement, IbcBasicResponse,
-    IbcMsg, IbcOrder, IbcTimeout, Response,
+    IbcMsg, IbcOrder, Response,
 };
 use cosmwasm_vm::testing::{
     execute, ibc_channel_connect, ibc_channel_open, ibc_packet_ack, instantiate, mock_env,
@@ -239,7 +239,8 @@ fn send_remote_funds() {
             assert_eq!(transfer_channel_id, channel_id.as_str());
             assert_eq!(remote_addr, to_address.as_str());
             assert_eq!(&coin(12344, "utrgd"), amount);
-            assert!(matches!(timeout, IbcTimeout::Timestamp { .. }));
+            assert!(timeout.block().is_none());
+            assert!(timeout.timestamp().is_some());
         }
         o => panic!("unexpected message: {:?}", o),
     }