From 5028fce6dabfeb4cef85ae72568e1a2a2f6d7ba4 Mon Sep 17 00:00:00 2001 From: Shoaib Ahmed Date: Tue, 11 Jan 2022 23:33:38 +0530 Subject: [PATCH 1/6] Path variants as types --- .../clients/ics07_tendermint/client_def.rs | 29 +- modules/src/core/ics24_host/path.rs | 273 +++++++++++------- modules/src/mock/client_def.rs | 5 +- relayer/src/chain/cosmos.rs | 53 ++-- 4 files changed, 224 insertions(+), 136 deletions(-) diff --git a/modules/src/clients/ics07_tendermint/client_def.rs b/modules/src/clients/ics07_tendermint/client_def.rs index 0fb7eac146..42855cb968 100644 --- a/modules/src/clients/ics07_tendermint/client_def.rs +++ b/modules/src/clients/ics07_tendermint/client_def.rs @@ -32,6 +32,10 @@ use crate::core::ics24_host::Path; use crate::prelude::*; use crate::Height; +use crate::core::ics24_host::path::{ + AcksPath, ChannelEndsPath, ClientConsensusStatePath, ClientStatePath, CommitmentsPath, + ConnectionsPath, ReceiptsPath, SeqRecvsPath, +}; use crate::downcast; #[derive(Clone, Debug, Default, PartialEq, Eq)] @@ -201,11 +205,11 @@ impl ClientDef for TendermintClient { ) -> Result<(), Ics02Error> { client_state.verify_height(height)?; - let path = Path::ClientConsensusState { + let path = Path::ClientConsensusState(ClientConsensusStatePath { client_id: client_id.clone(), epoch: consensus_height.revision_number, height: consensus_height.revision_height, - } + }) .to_string(); let value = expected_consensus_state.encode_vec().unwrap(); verify_membership(client_state, prefix, proof, root, path, value) @@ -223,7 +227,7 @@ impl ClientDef for TendermintClient { ) -> Result<(), Ics02Error> { client_state.verify_height(height)?; - let path = Path::Connections(connection_id.clone()).to_string(); + let path = Path::Connections(ConnectionsPath(connection_id.clone())).to_string(); let value = expected_connection_end.encode_vec().unwrap(); verify_membership(client_state, prefix, proof, root, path, value) } @@ -241,7 +245,8 @@ impl ClientDef for TendermintClient { ) -> Result<(), Ics02Error> { client_state.verify_height(height)?; - let path = Path::ChannelEnds(port_id.clone(), channel_id.clone()).to_string(); + let path = + Path::ChannelEnds(ChannelEndsPath(port_id.clone(), channel_id.clone())).to_string(); let value = expected_channel_end.encode_vec().unwrap(); verify_membership(client_state, prefix, proof, root, path, value) } @@ -258,7 +263,7 @@ impl ClientDef for TendermintClient { ) -> Result<(), Ics02Error> { client_state.verify_height(height)?; - let path = Path::ClientState(client_id.clone()).to_string(); + let path = Path::ClientState(ClientStatePath(client_id.clone())).to_string(); let value = expected_client_state.encode_vec().unwrap(); verify_membership(client_state, prefix, proof, root, path, value) } @@ -279,11 +284,11 @@ impl ClientDef for TendermintClient { client_state.verify_height(height)?; verify_delay_passed(ctx, height, connection_end)?; - let commitment_path = Path::Commitments { + let commitment_path = Path::Commitments(CommitmentsPath { port_id: port_id.clone(), channel_id: channel_id.clone(), sequence, - }; + }); verify_membership( client_state, connection_end.counterparty().prefix(), @@ -310,11 +315,11 @@ impl ClientDef for TendermintClient { client_state.verify_height(height)?; verify_delay_passed(ctx, height, connection_end)?; - let ack_path = Path::Acks { + let ack_path = Path::Acks(AcksPath { port_id: port_id.clone(), channel_id: channel_id.clone(), sequence, - }; + }); verify_membership( client_state, connection_end.counterparty().prefix(), @@ -340,7 +345,7 @@ impl ClientDef for TendermintClient { client_state.verify_height(height)?; verify_delay_passed(ctx, height, connection_end)?; - let seq_path = Path::SeqRecvs(port_id.clone(), channel_id.clone()); + let seq_path = Path::SeqRecvs(SeqRecvsPath(port_id.clone(), channel_id.clone())); verify_membership( client_state, connection_end.counterparty().prefix(), @@ -366,11 +371,11 @@ impl ClientDef for TendermintClient { client_state.verify_height(height)?; verify_delay_passed(ctx, height, connection_end)?; - let receipt_path = Path::Receipts { + let receipt_path = Path::Receipts(ReceiptsPath { port_id: port_id.clone(), channel_id: channel_id.clone(), sequence, - }; + }); verify_non_membership( client_state, connection_end.counterparty().prefix(), diff --git a/modules/src/core/ics24_host/path.rs b/modules/src/core/ics24_host/path.rs index 55b7b2a90e..1106933d62 100644 --- a/modules/src/core/ics24_host/path.rs +++ b/modules/src/core/ics24_host/path.rs @@ -30,38 +30,77 @@ const UPGRADED_CLIENT_CONSENSUS_STATE: &str = "upgradedConsState"; /// The Path enum abstracts out the different sub-paths. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Path { - ClientType(ClientId), - ClientState(ClientId), - ClientConsensusState { - client_id: ClientId, - epoch: u64, - height: u64, - }, - ClientConnections(ClientId), - Connections(ConnectionId), - Ports(PortId), - ChannelEnds(PortId, ChannelId), - SeqSends(PortId, ChannelId), - SeqRecvs(PortId, ChannelId), - SeqAcks(PortId, ChannelId), - Commitments { - port_id: PortId, - channel_id: ChannelId, - sequence: Sequence, - }, - Acks { - port_id: PortId, - channel_id: ChannelId, - sequence: Sequence, - }, - Receipts { - port_id: PortId, - channel_id: ChannelId, - sequence: Sequence, - }, + ClientType(ClientTypePath), + ClientState(ClientStatePath), + ClientConsensusState(ClientConsensusStatePath), + ClientConnections(ClientConnectionsPath), + Connections(ConnectionsPath), + Ports(PortsPath), + ChannelEnds(ChannelEndsPath), + SeqSends(SeqSendsPath), + SeqRecvs(SeqRecvsPath), + SeqAcks(SeqAcksPath), + Commitments(CommitmentsPath), + Acks(AcksPath), + Receipts(ReceiptsPath), Upgrade(ClientUpgradePath), } +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ClientTypePath(pub ClientId); + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ClientStatePath(pub ClientId); + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ClientConsensusStatePath { + pub client_id: ClientId, + pub epoch: u64, + pub height: u64, +} + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ClientConnectionsPath(pub ClientId); + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ConnectionsPath(pub ConnectionId); + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct PortsPath(pub PortId); + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ChannelEndsPath(pub PortId, pub ChannelId); + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct SeqSendsPath(pub PortId, pub ChannelId); + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct SeqRecvsPath(pub PortId, pub ChannelId); + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct SeqAcksPath(pub PortId, pub ChannelId); + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct CommitmentsPath { + pub port_id: PortId, + pub channel_id: ChannelId, + pub sequence: Sequence, +} + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct AcksPath { + pub port_id: PortId, + pub channel_id: ChannelId, + pub sequence: Sequence, +} + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ReceiptsPath { + pub port_id: PortId, + pub channel_id: ChannelId, + pub sequence: Sequence, +} + /// Paths that are specific for client upgrades. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum ClientUpgradePath { @@ -94,61 +133,69 @@ impl Path { impl Display for Path { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match &self { - Path::ClientType(client_id) => write!(f, "clients/{}/clientType", client_id), - Path::ClientState(client_id) => write!(f, "clients/{}/clientState", client_id), - Path::ClientConsensusState { + Path::ClientType(ClientTypePath(client_id)) => { + write!(f, "clients/{}/clientType", client_id) + } + Path::ClientState(ClientStatePath(client_id)) => { + write!(f, "clients/{}/clientState", client_id) + } + Path::ClientConsensusState(ClientConsensusStatePath { client_id, epoch, height, - } => write!( + }) => write!( f, "clients/{}/consensusStates/{}-{}", client_id, epoch, height ), - Path::ClientConnections(client_id) => write!(f, "clients/{}/connections", client_id), - Path::Connections(connection_id) => write!(f, "connections/{}", connection_id), - Path::Ports(port_id) => write!(f, "ports/{}", port_id), - Path::ChannelEnds(port_id, channel_id) => { + Path::ClientConnections(ClientConnectionsPath(client_id)) => { + write!(f, "clients/{}/connections", client_id) + } + Path::Connections(ConnectionsPath(connection_id)) => { + write!(f, "connections/{}", connection_id) + } + Path::Ports(PortsPath(port_id)) => write!(f, "ports/{}", port_id), + Path::ChannelEnds(ChannelEndsPath(port_id, channel_id)) => { write!(f, "channelEnds/ports/{}/channels/{}", port_id, channel_id) } - Path::SeqSends(port_id, channel_id) => write!( + Path::SeqSends(SeqSendsPath(port_id, channel_id)) => write!( f, "nextSequenceSend/ports/{}/channels/{}", port_id, channel_id ), - Path::SeqRecvs(port_id, channel_id) => write!( + Path::SeqRecvs(SeqRecvsPath(port_id, channel_id)) => write!( f, "nextSequenceRecv/ports/{}/channels/{}", port_id, channel_id ), - Path::SeqAcks(port_id, channel_id) => write!( + Path::SeqAcks(SeqAcksPath(port_id, channel_id)) => write!( f, "nextSequenceAck/ports/{}/channels/{}", port_id, channel_id ), - Path::Commitments { + Path::Commitments(CommitmentsPath { port_id, channel_id, sequence, - } => write!( + }) => write!( f, "commitments/ports/{}/channels/{}/sequences/{}", port_id, channel_id, sequence ), - Path::Acks { + Path::Acks(AcksPath { port_id, channel_id, sequence, - } => write!( + }) => write!( f, "acks/ports/{}/channels/{}/sequences/{}", port_id, channel_id, sequence ), - Path::Receipts { + Path::Receipts(ReceiptsPath { port_id, channel_id, sequence, - } => write!( + }) => write!( f, "receipts/ports/{}/channels/{}/sequences/{}", port_id, channel_id, sequence @@ -213,9 +260,9 @@ fn parse_client_paths(components: &[&str]) -> Option { if components.len() == 3 { match components[2] { - "clientType" => Some(Path::ClientType(client_id)), - "clientState" => Some(Path::ClientState(client_id)), - "connections" => Some(Path::ClientConnections(client_id)), + "clientType" => Some(Path::ClientType(ClientTypePath(client_id))), + "clientState" => Some(Path::ClientState(ClientStatePath(client_id))), + "connections" => Some(Path::ClientConnections(ClientConnectionsPath(client_id))), _ => None, } } else if components.len() == 4 { @@ -247,11 +294,11 @@ fn parse_client_paths(components: &[&str]) -> Option { Err(_) => return None, }; - Some(Path::ClientConsensusState { + Some(Path::ClientConsensusState(ClientConsensusStatePath { client_id, epoch, height, - }) + })) } else { None } @@ -281,7 +328,7 @@ fn parse_connections(components: &[&str]) -> Option { Err(_) => return None, }; - Some(Path::Connections(connection_id)) + Some(Path::Connections(ConnectionsPath(connection_id))) } fn parse_ports(components: &[&str]) -> Option { @@ -308,7 +355,7 @@ fn parse_ports(components: &[&str]) -> Option { Err(_) => return None, }; - Some(Path::Ports(port_id)) + Some(Path::Ports(PortsPath(port_id))) } fn parse_channels(components: &[&str]) -> Option { @@ -380,7 +427,7 @@ fn parse_channel_ends(components: &[&str]) -> Option { let port = parse_ports(&components[1..=2]); let channel = parse_channels(&components[3..=4]); - let port_id = if let Some(Path::Ports(port_id)) = port { + let port_id = if let Some(Path::Ports(PortsPath(port_id))) = port { port_id } else { return None; @@ -392,7 +439,7 @@ fn parse_channel_ends(components: &[&str]) -> Option { return None; }; - Some(Path::ChannelEnds(port_id, channel_id)) + Some(Path::ChannelEnds(ChannelEndsPath(port_id, channel_id))) } fn parse_seqs(components: &[&str]) -> Option { @@ -408,7 +455,7 @@ fn parse_seqs(components: &[&str]) -> Option { let port = parse_ports(&components[1..=2]); let channel = parse_channels(&components[3..=4]); - let port_id = if let Some(Path::Ports(port_id)) = port { + let port_id = if let Some(Path::Ports(PortsPath(port_id))) = port { port_id } else { return None; @@ -421,9 +468,9 @@ fn parse_seqs(components: &[&str]) -> Option { }; match first { - "nextSequenceSend" => Some(Path::SeqSends(port_id, channel_id)), - "nextSequenceRecv" => Some(Path::SeqRecvs(port_id, channel_id)), - "nextSequenceAck" => Some(Path::SeqAcks(port_id, channel_id)), + "nextSequenceSend" => Some(Path::SeqSends(SeqSendsPath(port_id, channel_id))), + "nextSequenceRecv" => Some(Path::SeqRecvs(SeqRecvsPath(port_id, channel_id))), + "nextSequenceAck" => Some(Path::SeqAcks(SeqAcksPath(port_id, channel_id))), _ => None, } } @@ -446,7 +493,7 @@ fn parse_commitments(components: &[&str]) -> Option { let channel = parse_channels(&components[3..=4]); let sequence = parse_sequences(&components[5..]); - let port_id = if let Some(Path::Ports(port_id)) = port { + let port_id = if let Some(Path::Ports(PortsPath(port_id))) = port { port_id } else { return None; @@ -464,11 +511,11 @@ fn parse_commitments(components: &[&str]) -> Option { return None; }; - Some(Path::Commitments { + Some(Path::Commitments(CommitmentsPath { port_id, channel_id, sequence, - }) + })) } fn parse_acks(components: &[&str]) -> Option { @@ -489,7 +536,7 @@ fn parse_acks(components: &[&str]) -> Option { let channel = parse_channels(&components[3..=4]); let sequence = parse_sequences(&components[5..]); - let port_id = if let Some(Path::Ports(port_id)) = port { + let port_id = if let Some(Path::Ports(PortsPath(port_id))) = port { port_id } else { return None; @@ -507,11 +554,11 @@ fn parse_acks(components: &[&str]) -> Option { return None; }; - Some(Path::Acks { + Some(Path::Acks(AcksPath { port_id, channel_id, sequence, - }) + })) } fn parse_receipts(components: &[&str]) -> Option { @@ -532,7 +579,7 @@ fn parse_receipts(components: &[&str]) -> Option { let channel = parse_channels(&components[3..=4]); let sequence = parse_sequences(&components[5..]); - let port_id = if let Some(Path::Ports(port_id)) = port { + let port_id = if let Some(Path::Ports(PortsPath(port_id))) = port { port_id } else { return None; @@ -550,11 +597,11 @@ fn parse_receipts(components: &[&str]) -> Option { return None; }; - Some(Path::Receipts { + Some(Path::Receipts(ReceiptsPath { port_id, channel_id, sequence, - }) + })) } fn parse_upgrades(components: &[&str]) -> Option { @@ -611,7 +658,7 @@ mod tests { assert_eq!( parse_client_paths(&components), - Some(Path::ClientType(ClientId::default())) + Some(Path::ClientType(ClientTypePath(ClientId::default()))) ); let path = "clients/07-tendermint-0/clientState"; @@ -619,7 +666,7 @@ mod tests { assert_eq!( parse_client_paths(&components), - Some(Path::ClientState(ClientId::default())) + Some(Path::ClientState(ClientStatePath(ClientId::default()))) ); let path = "clients/07-tendermint-0/consensusStates/15-31"; @@ -627,11 +674,11 @@ mod tests { assert_eq!( parse_client_paths(&components), - Some(Path::ClientConsensusState { + Some(Path::ClientConsensusState(ClientConsensusStatePath { client_id: ClientId::default(), epoch: 15, height: 31, - }) + })) ); } @@ -641,7 +688,10 @@ mod tests { let path = Path::from_str(path); assert!(path.is_ok()); - assert_eq!(path.unwrap(), Path::ClientType(ClientId::default()),); + assert_eq!( + path.unwrap(), + Path::ClientType(ClientTypePath(ClientId::default())) + ); } #[test] @@ -650,7 +700,10 @@ mod tests { let path = Path::from_str(path); assert!(path.is_ok()); - assert_eq!(path.unwrap(), Path::ClientState(ClientId::default())); + assert_eq!( + path.unwrap(), + Path::ClientState(ClientStatePath(ClientId::default())) + ); } #[test] @@ -661,11 +714,11 @@ mod tests { assert!(path.is_ok()); assert_eq!( path.unwrap(), - Path::ClientConsensusState { + Path::ClientConsensusState(ClientConsensusStatePath { client_id: ClientId::default(), epoch: 15, height: 31, - } + }) ); } @@ -675,7 +728,10 @@ mod tests { let path = Path::from_str(path); assert!(path.is_ok()); - assert_eq!(path.unwrap(), Path::ClientConnections(ClientId::default())); + assert_eq!( + path.unwrap(), + Path::ClientConnections(ClientConnectionsPath(ClientId::default())) + ); } #[test] @@ -685,7 +741,7 @@ mod tests { assert_eq!( parse_connections(&components), - Some(Path::Connections(ConnectionId::new(0))), + Some(Path::Connections(ConnectionsPath(ConnectionId::new(0)))), ); } @@ -695,7 +751,10 @@ mod tests { let path = Path::from_str(path); assert!(path.is_ok()); - assert_eq!(path.unwrap(), Path::Connections(ConnectionId::new(0))); + assert_eq!( + path.unwrap(), + Path::Connections(ConnectionsPath(ConnectionId::new(0))) + ); } #[test] @@ -705,7 +764,7 @@ mod tests { assert_eq!( parse_ports(&components), - Some(Path::Ports(PortId::default())), + Some(Path::Ports(PortsPath(PortId::default()))), ); } @@ -715,7 +774,7 @@ mod tests { let path = Path::from_str(path); assert!(path.is_ok()); - assert_eq!(path.unwrap(), Path::Ports(PortId::default())); + assert_eq!(path.unwrap(), Path::Ports(PortsPath(PortId::default()))); } #[test] @@ -763,7 +822,10 @@ mod tests { assert_eq!( parse_channel_ends(&components), - Some(Path::ChannelEnds(PortId::default(), ChannelId::default())), + Some(Path::ChannelEnds(ChannelEndsPath( + PortId::default(), + ChannelId::default() + ))), ); } @@ -775,7 +837,7 @@ mod tests { assert!(path.is_ok()); assert_eq!( path.unwrap(), - Path::ChannelEnds(PortId::default(), ChannelId::default()), + Path::ChannelEnds(ChannelEndsPath(PortId::default(), ChannelId::default())), ); } @@ -786,7 +848,10 @@ mod tests { assert_eq!( parse_seqs(&components), - Some(Path::SeqSends(PortId::default(), ChannelId::default())), + Some(Path::SeqSends(SeqSendsPath( + PortId::default(), + ChannelId::default() + ))), ); let path = "nextSequenceRecv/ports/defaultPort/channels/channel-0"; @@ -794,7 +859,10 @@ mod tests { assert_eq!( parse_seqs(&components), - Some(Path::SeqRecvs(PortId::default(), ChannelId::default())), + Some(Path::SeqRecvs(SeqRecvsPath( + PortId::default(), + ChannelId::default() + ))), ); let path = "nextSequenceAck/ports/defaultPort/channels/channel-0"; @@ -802,7 +870,10 @@ mod tests { assert_eq!( parse_seqs(&components), - Some(Path::SeqAcks(PortId::default(), ChannelId::default())), + Some(Path::SeqAcks(SeqAcksPath( + PortId::default(), + ChannelId::default() + ))), ); } @@ -814,7 +885,7 @@ mod tests { assert!(path.is_ok()); assert_eq!( path.unwrap(), - Path::SeqSends(PortId::default(), ChannelId::default()), + Path::SeqSends(SeqSendsPath(PortId::default(), ChannelId::default())), ); } @@ -826,7 +897,7 @@ mod tests { assert!(path.is_ok()); assert_eq!( path.unwrap(), - Path::SeqRecvs(PortId::default(), ChannelId::default()), + Path::SeqRecvs(SeqRecvsPath(PortId::default(), ChannelId::default())), ); } @@ -838,7 +909,7 @@ mod tests { assert!(path.is_ok()); assert_eq!( path.unwrap(), - Path::SeqAcks(PortId::default(), ChannelId::default()), + Path::SeqAcks(SeqAcksPath(PortId::default(), ChannelId::default())), ); } @@ -849,11 +920,11 @@ mod tests { assert_eq!( parse_commitments(&components), - Some(Path::Commitments { + Some(Path::Commitments(CommitmentsPath { port_id: PortId::default(), channel_id: ChannelId::default(), sequence: Sequence::default(), - }), + })), ); } @@ -865,11 +936,11 @@ mod tests { assert!(path.is_ok()); assert_eq!( path.unwrap(), - Path::Commitments { + Path::Commitments(CommitmentsPath { port_id: PortId::default(), channel_id: ChannelId::default(), sequence: Sequence::default(), - }, + }), ); } @@ -880,11 +951,11 @@ mod tests { assert_eq!( parse_acks(&components), - Some(Path::Acks { + Some(Path::Acks(AcksPath { port_id: PortId::default(), channel_id: ChannelId::default(), sequence: Sequence::default(), - }), + })), ); } @@ -896,11 +967,11 @@ mod tests { assert!(path.is_ok()); assert_eq!( path.unwrap(), - Path::Acks { + Path::Acks(AcksPath { port_id: PortId::default(), channel_id: ChannelId::default(), sequence: Sequence::default(), - }, + }), ); } @@ -911,11 +982,11 @@ mod tests { assert_eq!( parse_receipts(&components), - Some(Path::Receipts { + Some(Path::Receipts(ReceiptsPath { port_id: PortId::default(), channel_id: ChannelId::default(), sequence: Sequence::default(), - }), + })), ); } @@ -927,11 +998,11 @@ mod tests { assert!(path.is_ok()); assert_eq!( path.unwrap(), - Path::Receipts { + Path::Receipts(ReceiptsPath { port_id: PortId::default(), channel_id: ChannelId::default(), sequence: Sequence::default(), - }, + }), ); } diff --git a/modules/src/mock/client_def.rs b/modules/src/mock/client_def.rs index c5a755e478..5da5e284c0 100644 --- a/modules/src/mock/client_def.rs +++ b/modules/src/mock/client_def.rs @@ -14,6 +14,7 @@ use crate::core::ics23_commitment::commitment::{ }; use crate::core::ics23_commitment::merkle::apply_prefix; use crate::core::ics24_host::identifier::{ChannelId, ClientId, ConnectionId, PortId}; +use crate::core::ics24_host::path::ClientConsensusStatePath; use crate::core::ics24_host::Path; use crate::mock::client_state::{MockClientState, MockConsensusState}; use crate::mock::header::MockHeader; @@ -58,11 +59,11 @@ impl ClientDef for MockClient { consensus_height: Height, _expected_consensus_state: &AnyConsensusState, ) -> Result<(), Error> { - let client_prefixed_path = Path::ClientConsensusState { + let client_prefixed_path = Path::ClientConsensusState(ClientConsensusStatePath { client_id: client_id.clone(), epoch: consensus_height.revision_number, height: consensus_height.revision_height, - } + }) .to_string(); let _path = diff --git a/relayer/src/chain/cosmos.rs b/relayer/src/chain/cosmos.rs index a83506b9b3..4abae49ddf 100644 --- a/relayer/src/chain/cosmos.rs +++ b/relayer/src/chain/cosmos.rs @@ -50,8 +50,6 @@ use ibc::core::ics04_channel::packet::{Packet, PacketMsgType, Sequence}; use ibc::core::ics23_commitment::commitment::CommitmentPrefix; use ibc::core::ics23_commitment::merkle::convert_tm_to_ics_merkle_proof; use ibc::core::ics24_host::identifier::{ChainId, ChannelId, ClientId, ConnectionId, PortId}; -use ibc::core::ics24_host::Path::ClientConsensusState as ClientConsensusPath; -use ibc::core::ics24_host::Path::ClientState as ClientStatePath; use ibc::core::ics24_host::{ClientUpgradePath, Path, IBC_QUERY_PATH, SDK_UPGRADE_QUERY_PATH}; use ibc::events::{from_tx_response_event, IbcEvent}; use ibc::query::{QueryTxHash, QueryTxRequest}; @@ -97,6 +95,10 @@ use crate::{ }; use super::{ChainEndpoint, HealthCheck}; +use ibc::core::ics24_host::path::{ + AcksPath, ChannelEndsPath, ClientConsensusStatePath, ClientStatePath, CommitmentsPath, + ConnectionsPath, ReceiptsPath, SeqRecvsPath, +}; mod compatibility; pub mod version; @@ -1253,7 +1255,11 @@ impl ChainEndpoint for CosmosSdkChain { crate::time!("query_client_state"); let client_state = self - .query(ClientStatePath(client_id.clone()), height, false) + .query( + Path::ClientState(ClientStatePath(client_id.clone())), + height, + false, + ) .and_then(|v| AnyClientState::decode_vec(&v.value).map_err(Error::decode))?; let client_state = downcast!(client_state.clone() => AnyClientState::Tendermint) .ok_or_else(|| Error::client_state_type(format!("{:?}", client_state)))?; @@ -1546,7 +1552,7 @@ impl ChainEndpoint for CosmosSdkChain { height: ICSHeight, ) -> Result { let res = self.query( - Path::ChannelEnds(port_id.clone(), channel_id.clone()), + Path::ChannelEnds(ChannelEndsPath(port_id.clone(), channel_id.clone())), height, false, )?; @@ -1904,7 +1910,11 @@ impl ChainEndpoint for CosmosSdkChain { ) -> Result<(Self::ClientState, MerkleProof), Error> { crate::time!("proven_client_state"); - let res = self.query(ClientStatePath(client_id.clone()), height, true)?; + let res = self.query( + Path::ClientState(ClientStatePath(client_id.clone())), + height, + true, + )?; let client_state = AnyClientState::decode_vec(&res.value).map_err(Error::decode)?; @@ -1926,11 +1936,11 @@ impl ChainEndpoint for CosmosSdkChain { crate::time!("proven_client_consensus"); let res = self.query( - ClientConsensusPath { + Path::ClientConsensusState(ClientConsensusStatePath { client_id: client_id.clone(), epoch: consensus_height.revision_number, height: consensus_height.revision_height, - }, + }), height, true, )?; @@ -1952,7 +1962,11 @@ impl ChainEndpoint for CosmosSdkChain { connection_id: &ConnectionId, height: ICSHeight, ) -> Result<(ConnectionEnd, MerkleProof), Error> { - let res = self.query(Path::Connections(connection_id.clone()), height, true)?; + let res = self.query( + Path::Connections(ConnectionsPath(connection_id.clone())), + height, + true, + )?; let connection_end = ConnectionEnd::decode_vec(&res.value).map_err(Error::decode)?; Ok(( @@ -1968,7 +1982,7 @@ impl ChainEndpoint for CosmosSdkChain { height: ICSHeight, ) -> Result<(ChannelEnd, MerkleProof), Error> { let res = self.query( - Path::ChannelEnds(port_id.clone(), channel_id.clone()), + Path::ChannelEnds(ChannelEndsPath(port_id.clone(), channel_id.clone())), height, true, )?; @@ -1990,30 +2004,27 @@ impl ChainEndpoint for CosmosSdkChain { height: ICSHeight, ) -> Result<(Vec, MerkleProof), Error> { let data = match packet_type { - PacketMsgType::Recv => Path::Commitments { + PacketMsgType::Recv => Path::Commitments(CommitmentsPath { port_id, channel_id, sequence, - }, - PacketMsgType::Ack => Path::Acks { + }), + PacketMsgType::Ack => Path::Acks(AcksPath { port_id, channel_id, sequence, - }, - PacketMsgType::TimeoutUnordered => Path::Receipts { + }), + PacketMsgType::TimeoutUnordered => Path::Receipts(ReceiptsPath { port_id, channel_id, sequence, - }, - PacketMsgType::TimeoutOrdered => Path::SeqRecvs { - 0: port_id, - 1: channel_id, - }, - PacketMsgType::TimeoutOnClose => Path::Receipts { + }), + PacketMsgType::TimeoutOrdered => Path::SeqRecvs(SeqRecvsPath(port_id, channel_id)), + PacketMsgType::TimeoutOnClose => Path::Receipts(ReceiptsPath { port_id, channel_id, sequence, - }, + }), }; let res = self.query(data, height, true)?; From 9e5b17cf98a841d6829650ca2af80914ae839e96 Mon Sep 17 00:00:00 2001 From: Shoaib Ahmed Date: Wed, 12 Jan 2022 00:41:20 +0530 Subject: [PATCH 2/6] Use derive_more crate --- Cargo.lock | 1 + modules/Cargo.toml | 1 + modules/src/core/ics24_host/path.rs | 212 ++++++++++++---------------- 3 files changed, 90 insertions(+), 124 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2ff3803d81..f61c13aa1f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1382,6 +1382,7 @@ name = "ibc" version = "0.9.0" dependencies = [ "bytes", + "derive_more", "env_logger", "flex-error", "ibc-proto", diff --git a/modules/Cargo.toml b/modules/Cargo.toml index ee64ae3191..5e11d0232c 100644 --- a/modules/Cargo.toml +++ b/modules/Cargo.toml @@ -40,6 +40,7 @@ safe-regex = { version = "0.2.4", default-features = false } subtle-encoding = { version = "0.5", default-features = false } sha2 = { version = "0.10.1", default-features = false } flex-error = { version = "0.4.4", default-features = false } +derive_more = { version = "0.99.0", default-features = false, features = ["from", "display"] } [dependencies.tendermint] version = "=0.23.2" diff --git a/modules/src/core/ics24_host/path.rs b/modules/src/core/ics24_host/path.rs index 1106933d62..67b9421cca 100644 --- a/modules/src/core/ics24_host/path.rs +++ b/modules/src/core/ics24_host/path.rs @@ -4,12 +4,12 @@ use crate::prelude::*; /// https://github.com/cosmos/ibc/tree/master/spec/ics-024-host-requirements#path-space /// Some of these are implemented in other ICSs, but ICS-024 has a nice summary table. /// -use core::fmt::{self, Display, Formatter}; use core::str::FromStr; use crate::core::ics04_channel::packet::Sequence; use crate::core::ics24_host::identifier::{ChannelId, ClientId, ConnectionId, PortId}; +use derive_more::{Display, From}; use flex_error::define_error; /// ABCI Query path for the IBC sub-store @@ -28,20 +28,53 @@ const UPGRADED_CLIENT_STATE: &str = "upgradedClient"; const UPGRADED_CLIENT_CONSENSUS_STATE: &str = "upgradedConsState"; /// The Path enum abstracts out the different sub-paths. -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, From, Display)] pub enum Path { + #[display(fmt = "clients/{}/clientType", "_0.0")] ClientType(ClientTypePath), + #[display(fmt = "clients/{}/clientState", "_0.0")] ClientState(ClientStatePath), + #[display( + fmt = "clients/{}/consensusStates/{}-{}", + "_0.client_id", + "_0.epoch", + "_0.height" + )] ClientConsensusState(ClientConsensusStatePath), + #[display(fmt = "clients/{}/connections", "_0.0")] ClientConnections(ClientConnectionsPath), + #[display(fmt = "connections/{}", "_0.0")] Connections(ConnectionsPath), + #[display(fmt = "ports/{}", "_0.0")] Ports(PortsPath), + #[display(fmt = "channelEnds/ports/{}/channels/{}", "_0.0", "_0.1")] ChannelEnds(ChannelEndsPath), + #[display(fmt = "nextSequenceSend/ports/{}/channels/{}", "_0.0", "_0.1")] SeqSends(SeqSendsPath), + #[display(fmt = "nextSequenceRecv/ports/{}/channels/{}", "_0.0", "_0.1")] SeqRecvs(SeqRecvsPath), + #[display(fmt = "nextSequenceAck/ports/{}/channels/{}", "_0.0", "_0.1")] SeqAcks(SeqAcksPath), + #[display( + fmt = "commitments/ports/{}/channels/{}/sequences/{}", + "_0.port_id", + "_0.channel_id", + "_0.sequence" + )] Commitments(CommitmentsPath), + #[display( + fmt = "acks/ports/{}/channels/{}/sequences/{}", + "_0.port_id", + "_0.channel_id", + "_0.sequence" + )] Acks(AcksPath), + #[display( + fmt = "receipts/ports/{}/channels/{}/sequences/{}", + "_0.port_id", + "_0.channel_id", + "_0.sequence" + )] Receipts(ReceiptsPath), Upgrade(ClientUpgradePath), } @@ -102,9 +135,16 @@ pub struct ReceiptsPath { } /// Paths that are specific for client upgrades. -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display)] pub enum ClientUpgradePath { + #[display(fmt = "{}/{}/{}", UPGRADED_IBC_STATE, _0, UPGRADED_CLIENT_STATE)] UpgradedClientState(u64), + #[display( + fmt = "{}/{}/{}", + UPGRADED_IBC_STATE, + _0, + UPGRADED_CLIENT_CONSENSUS_STATE + )] UpgradedClientConsensusState(u64), } @@ -128,92 +168,6 @@ impl Path { } } -/// The Display trait adds the `.to_string()` method to the Path struct. -/// This is where the different path strings are constructed. -impl Display for Path { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match &self { - Path::ClientType(ClientTypePath(client_id)) => { - write!(f, "clients/{}/clientType", client_id) - } - Path::ClientState(ClientStatePath(client_id)) => { - write!(f, "clients/{}/clientState", client_id) - } - Path::ClientConsensusState(ClientConsensusStatePath { - client_id, - epoch, - height, - }) => write!( - f, - "clients/{}/consensusStates/{}-{}", - client_id, epoch, height - ), - Path::ClientConnections(ClientConnectionsPath(client_id)) => { - write!(f, "clients/{}/connections", client_id) - } - Path::Connections(ConnectionsPath(connection_id)) => { - write!(f, "connections/{}", connection_id) - } - Path::Ports(PortsPath(port_id)) => write!(f, "ports/{}", port_id), - Path::ChannelEnds(ChannelEndsPath(port_id, channel_id)) => { - write!(f, "channelEnds/ports/{}/channels/{}", port_id, channel_id) - } - Path::SeqSends(SeqSendsPath(port_id, channel_id)) => write!( - f, - "nextSequenceSend/ports/{}/channels/{}", - port_id, channel_id - ), - Path::SeqRecvs(SeqRecvsPath(port_id, channel_id)) => write!( - f, - "nextSequenceRecv/ports/{}/channels/{}", - port_id, channel_id - ), - Path::SeqAcks(SeqAcksPath(port_id, channel_id)) => write!( - f, - "nextSequenceAck/ports/{}/channels/{}", - port_id, channel_id - ), - Path::Commitments(CommitmentsPath { - port_id, - channel_id, - sequence, - }) => write!( - f, - "commitments/ports/{}/channels/{}/sequences/{}", - port_id, channel_id, sequence - ), - Path::Acks(AcksPath { - port_id, - channel_id, - sequence, - }) => write!( - f, - "acks/ports/{}/channels/{}/sequences/{}", - port_id, channel_id, sequence - ), - Path::Receipts(ReceiptsPath { - port_id, - channel_id, - sequence, - }) => write!( - f, - "receipts/ports/{}/channels/{}/sequences/{}", - port_id, channel_id, sequence - ), - Path::Upgrade(ClientUpgradePath::UpgradedClientState(height)) => write!( - f, - "{}/{}/{}", - UPGRADED_IBC_STATE, height, UPGRADED_CLIENT_STATE - ), - Path::Upgrade(ClientUpgradePath::UpgradedClientConsensusState(height)) => write!( - f, - "{}/{}/{}", - UPGRADED_IBC_STATE, height, UPGRADED_CLIENT_CONSENSUS_STATE - ), - } - } -} - define_error! { #[derive(Eq, PartialEq)] PathError { @@ -260,9 +214,9 @@ fn parse_client_paths(components: &[&str]) -> Option { if components.len() == 3 { match components[2] { - "clientType" => Some(Path::ClientType(ClientTypePath(client_id))), - "clientState" => Some(Path::ClientState(ClientStatePath(client_id))), - "connections" => Some(Path::ClientConnections(ClientConnectionsPath(client_id))), + "clientType" => Some(ClientTypePath(client_id).into()), + "clientState" => Some(ClientStatePath(client_id).into()), + "connections" => Some(ClientConnectionsPath(client_id).into()), _ => None, } } else if components.len() == 4 { @@ -294,11 +248,14 @@ fn parse_client_paths(components: &[&str]) -> Option { Err(_) => return None, }; - Some(Path::ClientConsensusState(ClientConsensusStatePath { - client_id, - epoch, - height, - })) + Some( + ClientConsensusStatePath { + client_id, + epoch, + height, + } + .into(), + ) } else { None } @@ -328,7 +285,7 @@ fn parse_connections(components: &[&str]) -> Option { Err(_) => return None, }; - Some(Path::Connections(ConnectionsPath(connection_id))) + Some(ConnectionsPath(connection_id).into()) } fn parse_ports(components: &[&str]) -> Option { @@ -355,7 +312,7 @@ fn parse_ports(components: &[&str]) -> Option { Err(_) => return None, }; - Some(Path::Ports(PortsPath(port_id))) + Some(PortsPath(port_id).into()) } fn parse_channels(components: &[&str]) -> Option { @@ -439,7 +396,7 @@ fn parse_channel_ends(components: &[&str]) -> Option { return None; }; - Some(Path::ChannelEnds(ChannelEndsPath(port_id, channel_id))) + Some(ChannelEndsPath(port_id, channel_id).into()) } fn parse_seqs(components: &[&str]) -> Option { @@ -468,9 +425,9 @@ fn parse_seqs(components: &[&str]) -> Option { }; match first { - "nextSequenceSend" => Some(Path::SeqSends(SeqSendsPath(port_id, channel_id))), - "nextSequenceRecv" => Some(Path::SeqRecvs(SeqRecvsPath(port_id, channel_id))), - "nextSequenceAck" => Some(Path::SeqAcks(SeqAcksPath(port_id, channel_id))), + "nextSequenceSend" => Some(SeqSendsPath(port_id, channel_id).into()), + "nextSequenceRecv" => Some(SeqRecvsPath(port_id, channel_id).into()), + "nextSequenceAck" => Some(SeqAcksPath(port_id, channel_id).into()), _ => None, } } @@ -511,11 +468,14 @@ fn parse_commitments(components: &[&str]) -> Option { return None; }; - Some(Path::Commitments(CommitmentsPath { - port_id, - channel_id, - sequence, - })) + Some( + CommitmentsPath { + port_id, + channel_id, + sequence, + } + .into(), + ) } fn parse_acks(components: &[&str]) -> Option { @@ -554,11 +514,14 @@ fn parse_acks(components: &[&str]) -> Option { return None; }; - Some(Path::Acks(AcksPath { - port_id, - channel_id, - sequence, - })) + Some( + AcksPath { + port_id, + channel_id, + sequence, + } + .into(), + ) } fn parse_receipts(components: &[&str]) -> Option { @@ -597,11 +560,14 @@ fn parse_receipts(components: &[&str]) -> Option { return None; }; - Some(Path::Receipts(ReceiptsPath { - port_id, - channel_id, - sequence, - })) + Some( + ReceiptsPath { + port_id, + channel_id, + sequence, + } + .into(), + ) } fn parse_upgrades(components: &[&str]) -> Option { @@ -629,12 +595,10 @@ fn parse_upgrades(components: &[&str]) -> Option { }; match last { - UPGRADED_CLIENT_STATE => Some(Path::Upgrade(ClientUpgradePath::UpgradedClientState( - height, - ))), - UPGRADED_CLIENT_CONSENSUS_STATE => Some(Path::Upgrade( - ClientUpgradePath::UpgradedClientConsensusState(height), - )), + UPGRADED_CLIENT_STATE => Some(ClientUpgradePath::UpgradedClientState(height).into()), + UPGRADED_CLIENT_CONSENSUS_STATE => { + Some(ClientUpgradePath::UpgradedClientConsensusState(height).into()) + } _ => None, } } From b2193118a7c4a8dc304afb5f58dbe6bcac9e60a1 Mon Sep 17 00:00:00 2001 From: Shoaib Ahmed Date: Wed, 12 Jan 2022 00:41:42 +0530 Subject: [PATCH 3/6] Simplify Path usage --- .../clients/ics07_tendermint/client_def.rs | 48 +++++++++---------- relayer/src/chain/cosmos.rs | 34 ++++++------- 2 files changed, 38 insertions(+), 44 deletions(-) diff --git a/modules/src/clients/ics07_tendermint/client_def.rs b/modules/src/clients/ics07_tendermint/client_def.rs index 42855cb968..4c3de94144 100644 --- a/modules/src/clients/ics07_tendermint/client_def.rs +++ b/modules/src/clients/ics07_tendermint/client_def.rs @@ -205,12 +205,11 @@ impl ClientDef for TendermintClient { ) -> Result<(), Ics02Error> { client_state.verify_height(height)?; - let path = Path::ClientConsensusState(ClientConsensusStatePath { + let path = ClientConsensusStatePath { client_id: client_id.clone(), epoch: consensus_height.revision_number, height: consensus_height.revision_height, - }) - .to_string(); + }; let value = expected_consensus_state.encode_vec().unwrap(); verify_membership(client_state, prefix, proof, root, path, value) } @@ -227,7 +226,7 @@ impl ClientDef for TendermintClient { ) -> Result<(), Ics02Error> { client_state.verify_height(height)?; - let path = Path::Connections(ConnectionsPath(connection_id.clone())).to_string(); + let path = ConnectionsPath(connection_id.clone()); let value = expected_connection_end.encode_vec().unwrap(); verify_membership(client_state, prefix, proof, root, path, value) } @@ -245,8 +244,7 @@ impl ClientDef for TendermintClient { ) -> Result<(), Ics02Error> { client_state.verify_height(height)?; - let path = - Path::ChannelEnds(ChannelEndsPath(port_id.clone(), channel_id.clone())).to_string(); + let path = ChannelEndsPath(port_id.clone(), channel_id.clone()); let value = expected_channel_end.encode_vec().unwrap(); verify_membership(client_state, prefix, proof, root, path, value) } @@ -263,7 +261,7 @@ impl ClientDef for TendermintClient { ) -> Result<(), Ics02Error> { client_state.verify_height(height)?; - let path = Path::ClientState(ClientStatePath(client_id.clone())).to_string(); + let path = ClientStatePath(client_id.clone()); let value = expected_client_state.encode_vec().unwrap(); verify_membership(client_state, prefix, proof, root, path, value) } @@ -284,17 +282,17 @@ impl ClientDef for TendermintClient { client_state.verify_height(height)?; verify_delay_passed(ctx, height, connection_end)?; - let commitment_path = Path::Commitments(CommitmentsPath { + let commitment_path = CommitmentsPath { port_id: port_id.clone(), channel_id: channel_id.clone(), sequence, - }); + }; verify_membership( client_state, connection_end.counterparty().prefix(), proof, root, - commitment_path.to_string(), + commitment_path, commitment.encode_to_vec(), ) } @@ -315,17 +313,17 @@ impl ClientDef for TendermintClient { client_state.verify_height(height)?; verify_delay_passed(ctx, height, connection_end)?; - let ack_path = Path::Acks(AcksPath { + let ack_path = AcksPath { port_id: port_id.clone(), channel_id: channel_id.clone(), sequence, - }); + }; verify_membership( client_state, connection_end.counterparty().prefix(), proof, root, - ack_path.to_string(), + ack_path, ack, ) } @@ -345,13 +343,13 @@ impl ClientDef for TendermintClient { client_state.verify_height(height)?; verify_delay_passed(ctx, height, connection_end)?; - let seq_path = Path::SeqRecvs(SeqRecvsPath(port_id.clone(), channel_id.clone())); + let seq_path = SeqRecvsPath(port_id.clone(), channel_id.clone()); verify_membership( client_state, connection_end.counterparty().prefix(), proof, root, - seq_path.to_string(), + seq_path, u64::from(sequence).encode_to_vec(), ) } @@ -371,17 +369,17 @@ impl ClientDef for TendermintClient { client_state.verify_height(height)?; verify_delay_passed(ctx, height, connection_end)?; - let receipt_path = Path::Receipts(ReceiptsPath { + let receipt_path = ReceiptsPath { port_id: port_id.clone(), channel_id: channel_id.clone(), sequence, - }); + }; verify_non_membership( client_state, connection_end.counterparty().prefix(), proof, root, - receipt_path.to_string(), + receipt_path, ) } @@ -396,15 +394,16 @@ impl ClientDef for TendermintClient { } } -fn verify_membership( +fn verify_membership>( client_state: &ClientState, prefix: &CommitmentPrefix, proof: &CommitmentProofBytes, root: &CommitmentRoot, - path: String, + path: P, value: Vec, ) -> Result<(), Ics02Error> { - let merkle_path = apply_prefix(prefix, vec![path]).map_err(Error::ics23_error)?; + let merkle_path = + apply_prefix(prefix, vec![path.into().to_string()]).map_err(Error::ics23_error)?; let merkle_proof: MerkleProof = RawMerkleProof::try_from(proof.clone()) .map_err(Ics02Error::invalid_commitment_proof)? .into(); @@ -420,14 +419,15 @@ fn verify_membership( .map_err(|e| Ics02Error::tendermint(Error::ics23_error(e))) } -fn verify_non_membership( +fn verify_non_membership>( client_state: &ClientState, prefix: &CommitmentPrefix, proof: &CommitmentProofBytes, root: &CommitmentRoot, - path: String, + path: P, ) -> Result<(), Ics02Error> { - let merkle_path = apply_prefix(prefix, vec![path]).map_err(Error::ics23_error)?; + let merkle_path = + apply_prefix(prefix, vec![path.into().to_string()]).map_err(Error::ics23_error)?; let merkle_proof: MerkleProof = RawMerkleProof::try_from(proof.clone()) .map_err(Ics02Error::invalid_commitment_proof)? .into(); diff --git a/relayer/src/chain/cosmos.rs b/relayer/src/chain/cosmos.rs index 4abae49ddf..b112db009e 100644 --- a/relayer/src/chain/cosmos.rs +++ b/relayer/src/chain/cosmos.rs @@ -596,7 +596,12 @@ impl CosmosSdkChain { self.config.max_tx_size.into() } - fn query(&self, data: Path, height: ICSHeight, prove: bool) -> Result { + fn query>( + &self, + data: P, + height: ICSHeight, + prove: bool, + ) -> Result { crate::time!("query"); // SAFETY: Creating a Path from a constant; this should never fail @@ -605,6 +610,7 @@ impl CosmosSdkChain { let height = Height::try_from(height.revision_height).map_err(Error::invalid_height)?; + let data = data.into(); if !data.is_provable() & prove { return Err(Error::private_store()); } @@ -1255,11 +1261,7 @@ impl ChainEndpoint for CosmosSdkChain { crate::time!("query_client_state"); let client_state = self - .query( - Path::ClientState(ClientStatePath(client_id.clone())), - height, - false, - ) + .query(ClientStatePath(client_id.clone()), height, false) .and_then(|v| AnyClientState::decode_vec(&v.value).map_err(Error::decode))?; let client_state = downcast!(client_state.clone() => AnyClientState::Tendermint) .ok_or_else(|| Error::client_state_type(format!("{:?}", client_state)))?; @@ -1552,7 +1554,7 @@ impl ChainEndpoint for CosmosSdkChain { height: ICSHeight, ) -> Result { let res = self.query( - Path::ChannelEnds(ChannelEndsPath(port_id.clone(), channel_id.clone())), + ChannelEndsPath(port_id.clone(), channel_id.clone()), height, false, )?; @@ -1910,11 +1912,7 @@ impl ChainEndpoint for CosmosSdkChain { ) -> Result<(Self::ClientState, MerkleProof), Error> { crate::time!("proven_client_state"); - let res = self.query( - Path::ClientState(ClientStatePath(client_id.clone())), - height, - true, - )?; + let res = self.query(ClientStatePath(client_id.clone()), height, true)?; let client_state = AnyClientState::decode_vec(&res.value).map_err(Error::decode)?; @@ -1936,11 +1934,11 @@ impl ChainEndpoint for CosmosSdkChain { crate::time!("proven_client_consensus"); let res = self.query( - Path::ClientConsensusState(ClientConsensusStatePath { + ClientConsensusStatePath { client_id: client_id.clone(), epoch: consensus_height.revision_number, height: consensus_height.revision_height, - }), + }, height, true, )?; @@ -1962,11 +1960,7 @@ impl ChainEndpoint for CosmosSdkChain { connection_id: &ConnectionId, height: ICSHeight, ) -> Result<(ConnectionEnd, MerkleProof), Error> { - let res = self.query( - Path::Connections(ConnectionsPath(connection_id.clone())), - height, - true, - )?; + let res = self.query(ConnectionsPath(connection_id.clone()), height, true)?; let connection_end = ConnectionEnd::decode_vec(&res.value).map_err(Error::decode)?; Ok(( @@ -1982,7 +1976,7 @@ impl ChainEndpoint for CosmosSdkChain { height: ICSHeight, ) -> Result<(ChannelEnd, MerkleProof), Error> { let res = self.query( - Path::ChannelEnds(ChannelEndsPath(port_id.clone(), channel_id.clone())), + ChannelEndsPath(port_id.clone(), channel_id.clone()), height, true, )?; From 3e5aa3b84b50a5ca2dc66ff4dc944b5f50f56a61 Mon Sep 17 00:00:00 2001 From: Shoaib Ahmed Date: Thu, 13 Jan 2022 13:08:39 +0530 Subject: [PATCH 4/6] Minor refactoring --- modules/src/clients/ics07_tendermint/client_def.rs | 8 ++++---- relayer/src/chain/cosmos.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/src/clients/ics07_tendermint/client_def.rs b/modules/src/clients/ics07_tendermint/client_def.rs index 4c3de94144..dcb5123c3b 100644 --- a/modules/src/clients/ics07_tendermint/client_def.rs +++ b/modules/src/clients/ics07_tendermint/client_def.rs @@ -394,12 +394,12 @@ impl ClientDef for TendermintClient { } } -fn verify_membership>( +fn verify_membership( client_state: &ClientState, prefix: &CommitmentPrefix, proof: &CommitmentProofBytes, root: &CommitmentRoot, - path: P, + path: impl Into, value: Vec, ) -> Result<(), Ics02Error> { let merkle_path = @@ -419,12 +419,12 @@ fn verify_membership>( .map_err(|e| Ics02Error::tendermint(Error::ics23_error(e))) } -fn verify_non_membership>( +fn verify_non_membership( client_state: &ClientState, prefix: &CommitmentPrefix, proof: &CommitmentProofBytes, root: &CommitmentRoot, - path: P, + path: impl Into, ) -> Result<(), Ics02Error> { let merkle_path = apply_prefix(prefix, vec![path.into().to_string()]).map_err(Error::ics23_error)?; diff --git a/relayer/src/chain/cosmos.rs b/relayer/src/chain/cosmos.rs index b112db009e..c214c8431b 100644 --- a/relayer/src/chain/cosmos.rs +++ b/relayer/src/chain/cosmos.rs @@ -596,9 +596,9 @@ impl CosmosSdkChain { self.config.max_tx_size.into() } - fn query>( + fn query( &self, - data: P, + data: impl Into, height: ICSHeight, prove: bool, ) -> Result { From 7ed4f016006e7ee938a9384574e7395f40f2f118 Mon Sep 17 00:00:00 2001 From: Shoaib Ahmed Date: Thu, 13 Jan 2022 17:18:02 +0530 Subject: [PATCH 5/6] More cleanup --- relayer/src/chain/cosmos.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/relayer/src/chain/cosmos.rs b/relayer/src/chain/cosmos.rs index c214c8431b..bed26821ca 100644 --- a/relayer/src/chain/cosmos.rs +++ b/relayer/src/chain/cosmos.rs @@ -1997,28 +1997,32 @@ impl ChainEndpoint for CosmosSdkChain { sequence: Sequence, height: ICSHeight, ) -> Result<(Vec, MerkleProof), Error> { - let data = match packet_type { - PacketMsgType::Recv => Path::Commitments(CommitmentsPath { + let data: Path = match packet_type { + PacketMsgType::Recv => CommitmentsPath { port_id, channel_id, sequence, - }), - PacketMsgType::Ack => Path::Acks(AcksPath { + } + .into(), + PacketMsgType::Ack => AcksPath { port_id, channel_id, sequence, - }), - PacketMsgType::TimeoutUnordered => Path::Receipts(ReceiptsPath { + } + .into(), + PacketMsgType::TimeoutUnordered => ReceiptsPath { port_id, channel_id, sequence, - }), - PacketMsgType::TimeoutOrdered => Path::SeqRecvs(SeqRecvsPath(port_id, channel_id)), - PacketMsgType::TimeoutOnClose => Path::Receipts(ReceiptsPath { + } + .into(), + PacketMsgType::TimeoutOrdered => SeqRecvsPath(port_id, channel_id).into(), + PacketMsgType::TimeoutOnClose => ReceiptsPath { port_id, channel_id, sequence, - }), + } + .into(), }; let res = self.query(data, height, true)?; From 6a11af62ba68d845d4a88de593a970f80ea65524 Mon Sep 17 00:00:00 2001 From: Shoaib Ahmed Date: Thu, 13 Jan 2022 23:51:29 +0530 Subject: [PATCH 6/6] Add .changelog entry --- .../unreleased/improvements/ibc/1760-path-variants-as-types.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/improvements/ibc/1760-path-variants-as-types.md diff --git a/.changelog/unreleased/improvements/ibc/1760-path-variants-as-types.md b/.changelog/unreleased/improvements/ibc/1760-path-variants-as-types.md new file mode 100644 index 0000000000..3045efb67e --- /dev/null +++ b/.changelog/unreleased/improvements/ibc/1760-path-variants-as-types.md @@ -0,0 +1,2 @@ +- Extract all `ics24_host::Path` variants into their separate types + ([#1760](https://github.com/informalsystems/ibc-rs/issues/1760)) \ No newline at end of file