From a23a61a64a532a4b8633a2bf18f9e775639ebf10 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 27 Jul 2023 10:20:09 +0200 Subject: [PATCH 01/58] add grpc service dependencies --- crates/ibc/Cargo.toml | 4 ++++ crates/ibc/src/lib.rs | 3 +++ crates/ibc/src/services/mod.rs | 0 3 files changed, 7 insertions(+) create mode 100644 crates/ibc/src/services/mod.rs diff --git a/crates/ibc/Cargo.toml b/crates/ibc/Cargo.toml index 12291754b..a90fcf1a5 100644 --- a/crates/ibc/Cargo.toml +++ b/crates/ibc/Cargo.toml @@ -34,10 +34,13 @@ std = [ "primitive-types/std", "tendermint/clock", "tendermint/std", + "grpc", ] parity-scale-codec = ["dep:parity-scale-codec", "dep:scale-info", "ibc-proto/parity-scale-codec"] borsh = ["dep:borsh", "ibc-proto/borsh"] +grpc = ["dep:tonic", "ibc-proto/server"] + # This feature is required for token transfer (ICS-20) serde = ["dep:serde", "dep:serde_derive", "serde_json", "ics23/serde"] @@ -67,6 +70,7 @@ num-traits = { version = "0.2.15", default-features = false } derive_more = { version = "0.99.17", default-features = false, features = ["from", "into", "display", "try_into"] } uint = { version = "0.9", default-features = false } primitive-types = { version = "0.12.0", default-features = false, features = ["serde_no_std"] } +tonic = { version = "0.9", optional = true } ## for codec encode or decode parity-scale-codec = { version = "3.0.0", default-features = false, features = ["full"], optional = true } diff --git a/crates/ibc/src/lib.rs b/crates/ibc/src/lib.rs index 68004e69f..6575a4d24 100644 --- a/crates/ibc/src/lib.rs +++ b/crates/ibc/src/lib.rs @@ -53,6 +53,9 @@ pub mod clients; pub mod core; pub mod hosts; +#[cfg(feature = "grpc")] +pub mod services; + #[cfg(any(test, feature = "mocks"))] pub mod mock; #[cfg(any(test, feature = "mocks"))] diff --git a/crates/ibc/src/services/mod.rs b/crates/ibc/src/services/mod.rs new file mode 100644 index 000000000..e69de29bb From ee98869b0a9960acde4a0875b82ca13402e41187 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 27 Jul 2023 10:20:51 +0200 Subject: [PATCH 02/58] client service implementation --- crates/ibc/src/services/client.rs | 159 ++++++++++++++++++++++++++++++ crates/ibc/src/services/mod.rs | 1 + 2 files changed, 160 insertions(+) create mode 100644 crates/ibc/src/services/client.rs diff --git a/crates/ibc/src/services/client.rs b/crates/ibc/src/services/client.rs new file mode 100644 index 000000000..47acd681c --- /dev/null +++ b/crates/ibc/src/services/client.rs @@ -0,0 +1,159 @@ +use ibc_proto::{ + google::protobuf::Any, + ibc::core::client::v1::{ + query_server::Query as ClientQuery, QueryClientParamsRequest, QueryClientParamsResponse, + QueryClientStateRequest, QueryClientStateResponse, QueryClientStatesRequest, + QueryClientStatesResponse, QueryClientStatusRequest, QueryClientStatusResponse, + QueryConsensusStateHeightsRequest, QueryConsensusStateHeightsResponse, + QueryConsensusStateRequest, QueryConsensusStateResponse, QueryConsensusStatesRequest, + QueryConsensusStatesResponse, QueryUpgradedClientStateRequest, + QueryUpgradedClientStateResponse, QueryUpgradedConsensusStateRequest, + QueryUpgradedConsensusStateResponse, + }, +}; + +use crate::{ + core::{ + ics24_host::{identifier::ClientId, path::ClientConsensusStatePath}, + ValidationContext, + }, + Height, +}; + +use core::str::FromStr; +use std::boxed::Box; +use tonic::{Request, Response, Status}; +use tracing::trace; + +pub struct ClientQueryServer { + context: T, +} + +impl ClientQueryServer { + pub fn new(context: T) -> Self { + Self { context } + } +} + +#[tonic::async_trait] +impl ClientQuery for ClientQueryServer +where + T: ValidationContext + Send + Sync + 'static, + ::AnyClientState: Into, + ::AnyConsensusState: Into, +{ + async fn client_state( + &self, + request: Request, + ) -> Result, Status> { + trace!("Got client state request: {:?}", request); + + let request_ref = request.get_ref(); + + let client_id = ClientId::from_str(request_ref.client_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!("Invalid client id: {}", request_ref.client_id)) + })?; + let client_state = self.context.client_state(&client_id).map_err(|_| { + Status::not_found(std::format!( + "Client state not found for client {}", + client_id + )) + })?; + + Ok(Response::new(QueryClientStateResponse { + client_state: Some(client_state.into()), + proof: Default::default(), + proof_height: None, + })) + } + + async fn client_states( + &self, + request: Request, + ) -> Result, Status> { + trace!("Got client states request: {:?}", request); + todo!() + } + + async fn consensus_state( + &self, + request: Request, + ) -> Result, Status> { + trace!("Got consensus state request: {:?}", request); + + let request_ref = request.get_ref(); + + let client_id = ClientId::from_str(request_ref.client_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!("Invalid client id: {}", request_ref.client_id)) + })?; + + let height = Height::new(request_ref.revision_number, request_ref.revision_height) + .map_err(|_| { + Status::invalid_argument(std::format!( + "Invalid height: {}-{}", + request_ref.revision_number, + request_ref.revision_height + )) + })?; + + let consensus_state = self + .context + .consensus_state(&ClientConsensusStatePath::new(&client_id, &height)) + .map_err(|_| { + Status::not_found(std::format!( + "Consensus state not found for client {} at height {}", + client_id, + height + )) + })?; + + Ok(Response::new(QueryConsensusStateResponse { + consensus_state: Some(consensus_state.into()), + proof: Default::default(), + proof_height: None, + })) + } + + async fn consensus_states( + &self, + request: Request, + ) -> Result, Status> { + trace!("Got consensus states request: {:?}", request); + todo!(); + } + + async fn consensus_state_heights( + &self, + _request: Request, + ) -> Result, Status> { + todo!() + } + + async fn client_status( + &self, + _request: Request, + ) -> Result, Status> { + unimplemented!() + } + + async fn client_params( + &self, + _request: Request, + ) -> Result, Status> { + unimplemented!() + } + + async fn upgraded_client_state( + &self, + _request: Request, + ) -> Result, Status> { + unimplemented!() + } + + async fn upgraded_consensus_state( + &self, + _request: Request, + ) -> Result, Status> { + unimplemented!() + } +} diff --git a/crates/ibc/src/services/mod.rs b/crates/ibc/src/services/mod.rs index e69de29bb..b9babe5bc 100644 --- a/crates/ibc/src/services/mod.rs +++ b/crates/ibc/src/services/mod.rs @@ -0,0 +1 @@ +pub mod client; From a90697154b9119f7b7b8bd72c17c1646c447ac4b Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 27 Jul 2023 10:21:13 +0200 Subject: [PATCH 03/58] connection service implementation --- crates/ibc/src/services/connection.rs | 185 ++++++++++++++++++++++++++ crates/ibc/src/services/mod.rs | 1 + 2 files changed, 186 insertions(+) create mode 100644 crates/ibc/src/services/connection.rs diff --git a/crates/ibc/src/services/connection.rs b/crates/ibc/src/services/connection.rs new file mode 100644 index 000000000..4d7bf7515 --- /dev/null +++ b/crates/ibc/src/services/connection.rs @@ -0,0 +1,185 @@ +use ibc_proto::{ + google::protobuf::Any, + ibc::core::{ + client::v1::IdentifiedClientState, + connection::v1::{ + query_server::Query as ConnectionQuery, QueryClientConnectionsRequest, + QueryClientConnectionsResponse, QueryConnectionClientStateRequest, + QueryConnectionClientStateResponse, QueryConnectionConsensusStateRequest, + QueryConnectionConsensusStateResponse, QueryConnectionParamsRequest, + QueryConnectionParamsResponse, QueryConnectionRequest, QueryConnectionResponse, + QueryConnectionsRequest, QueryConnectionsResponse, + }, + }, +}; + +use crate::{ + core::{ + ics24_host::{identifier::ConnectionId, path::ClientConsensusStatePath}, + ValidationContext, + }, + Height, +}; + +use core::str::FromStr; +use std::boxed::Box; +use tonic::{Request, Response, Status}; +use tracing::trace; + +pub struct ConnectionQueryServer { + pub context: T, +} + +impl ConnectionQueryServer { + pub fn new(context: T) -> Self { + Self { context } + } +} + +#[tonic::async_trait] +impl ConnectionQuery for ConnectionQueryServer +where + T: ValidationContext + Send + Sync + 'static, + ::AnyClientState: Into, + ::AnyConsensusState: Into, +{ + async fn connection( + &self, + request: Request, + ) -> Result, Status> { + let request_ref = request.get_ref(); + + let connection_id = + ConnectionId::from_str(request_ref.connection_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!( + "Invalid connection id: {}", + request_ref.connection_id + )) + })?; + + let connection_end = self.context.connection_end(&connection_id).map_err(|_| { + Status::not_found(std::format!( + "Connection end not found for connection {}", + connection_id + )) + })?; + + Ok(Response::new(QueryConnectionResponse { + connection: Some(connection_end.into()), + proof: Default::default(), + proof_height: None, + })) + } + + async fn connections( + &self, + _request: Request, + ) -> Result, Status> { + todo!() + } + + async fn client_connections( + &self, + request: Request, + ) -> Result, Status> { + trace!("Got client connections request: {:?}", request); + todo!() + } + + async fn connection_client_state( + &self, + request: Request, + ) -> Result, Status> { + let request_ref = request.get_ref(); + + let connection_id = + ConnectionId::from_str(request_ref.connection_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!( + "Invalid connection id: {}", + request_ref.connection_id + )) + })?; + + let connection_end = self.context.connection_end(&connection_id).map_err(|_| { + Status::not_found(std::format!( + "Connection end not found for connection {}", + connection_id + )) + })?; + + let client_state = self + .context + .client_state(connection_end.client_id()) + .map_err(|_| { + Status::not_found(std::format!( + "Client state not found for connection {}", + connection_id + )) + })?; + + Ok(Response::new(QueryConnectionClientStateResponse { + identified_client_state: Some(IdentifiedClientState { + client_id: connection_end.client_id().as_str().into(), + client_state: Some(client_state.into()), + }), + proof: Default::default(), + proof_height: None, + })) + } + + async fn connection_consensus_state( + &self, + request: Request, + ) -> Result, Status> { + let request_ref = request.get_ref(); + + let connection_id = + ConnectionId::from_str(request_ref.connection_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!( + "Invalid connection id: {}", + request_ref.connection_id + )) + })?; + + let connection_end = self.context.connection_end(&connection_id).map_err(|_| { + Status::not_found(std::format!( + "Connection end not found for connection {}", + connection_id + )) + })?; + + let consensus_path = ClientConsensusStatePath::new( + connection_end.client_id(), + &Height::new(request_ref.revision_number, request_ref.revision_height).map_err( + |_| { + Status::invalid_argument(std::format!( + "Invalid height: {}-{}", + request_ref.revision_number, + request_ref.revision_height + )) + }, + )?, + ); + + let consensus_state = self.context.consensus_state(&consensus_path).map_err(|_| { + Status::not_found(std::format!( + "Consensus state not found for connection {}", + connection_id + )) + })?; + + Ok(Response::new(QueryConnectionConsensusStateResponse { + consensus_state: Some(consensus_state.into()), + client_id: connection_end.client_id().as_str().into(), + proof: Default::default(), + proof_height: None, + })) + } + + async fn connection_params( + &self, + _request: Request, + ) -> Result, Status> { + todo!() + } +} diff --git a/crates/ibc/src/services/mod.rs b/crates/ibc/src/services/mod.rs index b9babe5bc..771d38780 100644 --- a/crates/ibc/src/services/mod.rs +++ b/crates/ibc/src/services/mod.rs @@ -1 +1,2 @@ pub mod client; +pub mod connection; From b8efb6371cab62fc6c3ee7837614fcd9098ab0e5 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 27 Jul 2023 10:21:30 +0200 Subject: [PATCH 04/58] channel service implementation --- crates/ibc/src/services/channel.rs | 435 +++++++++++++++++++++++++++++ crates/ibc/src/services/mod.rs | 1 + 2 files changed, 436 insertions(+) create mode 100644 crates/ibc/src/services/channel.rs diff --git a/crates/ibc/src/services/channel.rs b/crates/ibc/src/services/channel.rs new file mode 100644 index 000000000..d587a3867 --- /dev/null +++ b/crates/ibc/src/services/channel.rs @@ -0,0 +1,435 @@ +use ibc_proto::{ + google::protobuf::Any, + ibc::core::{ + channel::v1::{ + query_server::Query as ChannelQuery, QueryChannelClientStateRequest, + QueryChannelClientStateResponse, QueryChannelConsensusStateRequest, + QueryChannelConsensusStateResponse, QueryChannelRequest, QueryChannelResponse, + QueryChannelsRequest, QueryChannelsResponse, QueryConnectionChannelsRequest, + QueryConnectionChannelsResponse, QueryNextSequenceReceiveRequest, + QueryNextSequenceReceiveResponse, QueryPacketAcknowledgementRequest, + QueryPacketAcknowledgementResponse, QueryPacketAcknowledgementsRequest, + QueryPacketAcknowledgementsResponse, QueryPacketCommitmentRequest, + QueryPacketCommitmentResponse, QueryPacketCommitmentsRequest, + QueryPacketCommitmentsResponse, QueryPacketReceiptRequest, QueryPacketReceiptResponse, + QueryUnreceivedAcksRequest, QueryUnreceivedAcksResponse, QueryUnreceivedPacketsRequest, + QueryUnreceivedPacketsResponse, + }, + client::v1::IdentifiedClientState, + }, +}; + +use crate::{ + core::{ + ics04_channel::packet::Sequence, + ics24_host::{ + identifier::{ChannelId, PortId}, + path::{ + AckPath, ChannelEndPath, ClientConsensusStatePath, CommitmentPath, ReceiptPath, + SeqRecvPath, + }, + }, + ValidationContext, + }, + Height, +}; + +use core::str::FromStr; +use std::boxed::Box; +use tonic::{Request, Response, Status}; +use tracing::trace; + +pub struct ChannelQueryServer { + context: T, +} + +impl ChannelQueryServer { + pub fn new(context: T) -> Self { + Self { context } + } +} + +#[tonic::async_trait] +impl ChannelQuery for ChannelQueryServer +where + T: ValidationContext + Send + Sync + 'static, + ::AnyClientState: Into, + ::AnyConsensusState: Into, +{ + async fn channel( + &self, + request: Request, + ) -> Result, Status> { + trace!("Got channel request: {:?}", request); + let request_ref = request.get_ref(); + + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!( + "Invalid channel id: {}", + request_ref.channel_id + )) + })?; + + let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) + })?; + + let channel_end_path = ChannelEndPath::new(&port_id, &channel_id); + + let channel_end = self.context.channel_end(&channel_end_path).map_err(|_| { + Status::not_found(std::format!( + "Channel end not found for channel {}", + channel_id + )) + })?; + + Ok(Response::new(QueryChannelResponse { + channel: Some(channel_end.into()), + proof: Default::default(), + proof_height: None, + })) + } + /// Channels queries all the IBC channels of a chain. + async fn channels( + &self, + _request: Request, + ) -> Result, Status> { + todo!() + } + /// ConnectionChannels queries all the channels associated with a connection + /// end. + async fn connection_channels( + &self, + _request: Request, + ) -> Result, Status> { + todo!() + } + /// ChannelClientState queries for the client state for the channel associated + /// with the provided channel identifiers. + async fn channel_client_state( + &self, + request: Request, + ) -> Result, Status> { + let request_ref = request.get_ref(); + + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!( + "Invalid channel id: {}", + request_ref.channel_id + )) + })?; + + let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) + })?; + + let channel_end_path = ChannelEndPath::new(&port_id, &channel_id); + + let channel_end = self.context.channel_end(&channel_end_path).map_err(|_| { + Status::not_found(std::format!( + "Channel end not found for channel {}", + channel_id + )) + })?; + + let connection_end = channel_end + .connection_hops() + .first() + .map(|connection_id| { + self.context.connection_end(connection_id).map_err(|_| { + Status::not_found(std::format!( + "Connection end not found for connection {}", + connection_id + )) + }) + }) + .ok_or_else(|| { + Status::not_found(std::format!( + "Channel {} has no connection hops", + channel_id + )) + })??; + + let client_state = self + .context + .client_state(connection_end.client_id()) + .map_err(|_| { + Status::not_found(std::format!( + "Client state not found for client {}", + connection_end.client_id() + )) + })?; + + Ok(Response::new(QueryChannelClientStateResponse { + identified_client_state: Some(IdentifiedClientState { + client_id: connection_end.client_id().as_str().into(), + client_state: Some(client_state.into()), + }), + proof: Default::default(), + proof_height: None, + })) + } + /// ChannelConsensusState queries for the consensus state for the channel + /// associated with the provided channel identifiers. + async fn channel_consensus_state( + &self, + request: Request, + ) -> Result, Status> { + let request_ref = request.get_ref(); + + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!( + "Invalid channel id: {}", + request_ref.channel_id + )) + })?; + + let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) + })?; + + let channel_end_path = ChannelEndPath::new(&port_id, &channel_id); + + let channel_end = self.context.channel_end(&channel_end_path).map_err(|_| { + Status::not_found(std::format!( + "Channel end not found for channel {}", + channel_id + )) + })?; + + let connection_end = channel_end + .connection_hops() + .first() + .map(|connection_id| { + self.context.connection_end(connection_id).map_err(|_| { + Status::not_found(std::format!( + "Connection end not found for connection {}", + connection_id + )) + }) + }) + .ok_or_else(|| { + Status::not_found(std::format!( + "Channel {} has no connection hops", + channel_id + )) + })??; + + let consensus_path = ClientConsensusStatePath::new( + connection_end.client_id(), + &Height::new(request_ref.revision_number, request_ref.revision_height).map_err( + |_| { + Status::invalid_argument(std::format!( + "Invalid height: {}-{}", + request_ref.revision_number, + request_ref.revision_height + )) + }, + )?, + ); + + let consensus_state = self.context.consensus_state(&consensus_path).map_err(|_| { + Status::not_found(std::format!( + "Consensus state not found for client {} and revision {}", + connection_end.client_id(), + request_ref.revision_number + )) + })?; + + Ok(Response::new(QueryChannelConsensusStateResponse { + client_id: connection_end.client_id().as_str().into(), + consensus_state: Some(consensus_state.into()), + proof: Default::default(), + proof_height: None, + })) + } + /// PacketCommitment queries a stored packet commitment hash. + async fn packet_commitment( + &self, + request: Request, + ) -> Result, Status> { + let request_ref = request.get_ref(); + + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!( + "Invalid channel id: {}", + request_ref.channel_id + )) + })?; + + let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) + })?; + + let sequence = Sequence::from(request_ref.sequence); + + let commitment_path = CommitmentPath::new(&port_id, &channel_id, sequence); + + let packet_commitment_data = self + .context + .get_packet_commitment(&commitment_path) + .map_err(|_| { + Status::not_found(std::format!( + "Packet commitment not found for channel {} and sequence {}", + channel_id, + sequence + )) + })?; + + Ok(Response::new(QueryPacketCommitmentResponse { + commitment: packet_commitment_data.into_vec(), + proof: Default::default(), + proof_height: None, + })) + } + /// PacketCommitments returns all the packet commitments hashes associated + /// with a channel. + async fn packet_commitments( + &self, + _request: Request, + ) -> Result, Status> { + todo!() + } + + /// PacketReceipt queries if a given packet sequence has been received on the + /// queried chain + async fn packet_receipt( + &self, + request: Request, + ) -> Result, Status> { + let request_ref = request.get_ref(); + + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!( + "Invalid channel id: {}", + request_ref.channel_id + )) + })?; + + let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) + })?; + + let sequence = Sequence::from(request_ref.sequence); + + let receipt_path = ReceiptPath::new(&port_id, &channel_id, sequence); + + // Receipt only has one enum + // Unreceived packets are not stored + let packet_receipt_data = self.context.get_packet_receipt(&receipt_path); + + Ok(Response::new(QueryPacketReceiptResponse { + received: packet_receipt_data.is_ok(), + proof: Default::default(), + proof_height: None, + })) + } + + /// PacketAcknowledgement queries a stored packet acknowledgement hash. + async fn packet_acknowledgement( + &self, + request: Request, + ) -> Result, Status> { + let request_ref = request.get_ref(); + + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!( + "Invalid channel id: {}", + request_ref.channel_id + )) + })?; + + let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) + })?; + + let sequence = Sequence::from(request_ref.sequence); + + let acknowledgement_path = AckPath::new(&port_id, &channel_id, sequence); + + let packet_acknowledgement_data = self + .context + .get_packet_acknowledgement(&acknowledgement_path) + .map_err(|_| { + Status::not_found(std::format!( + "Packet acknowledgement not found for channel {} and sequence {}", + channel_id, + sequence + )) + })?; + + Ok(Response::new(QueryPacketAcknowledgementResponse { + acknowledgement: packet_acknowledgement_data.into_vec(), + proof: Default::default(), + proof_height: None, + })) + } + + /// PacketAcknowledgements returns all the packet acknowledgements associated + /// with a channel. + async fn packet_acknowledgements( + &self, + _request: Request, + ) -> Result, Status> { + todo!() + } + + /// UnreceivedPackets returns all the unreceived IBC packets associated with + /// a channel and sequences. + /// + /// QUESTION. Currently only works for unordered channels; ordered channels + /// don't use receipts. However, ibc-go does it this way. Investigate if + /// this query only ever makes sense on unordered channels. + async fn unreceived_packets( + &self, + _request: Request, + ) -> Result, Status> { + todo!() + } + + /// UnreceivedAcks returns all the unreceived IBC acknowledgements associated + /// with a channel and sequences. + async fn unreceived_acks( + &self, + _request: Request, + ) -> Result, Status> { + todo!() + } + + /// NextSequenceReceive returns the next receive sequence for a given channel. + async fn next_sequence_receive( + &self, + request: Request, + ) -> Result, Status> { + let request_ref = request.get_ref(); + + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!( + "Invalid channel id: {}", + request_ref.channel_id + )) + })?; + + let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) + })?; + + let next_seq_recv_path = SeqRecvPath::new(&port_id, &channel_id); + + let next_sequence_recv = self + .context + .get_next_sequence_recv(&next_seq_recv_path) + .map_err(|_| { + Status::not_found(std::format!( + "Next sequence receive not found for channel {}", + channel_id + )) + })?; + + Ok(Response::new(QueryNextSequenceReceiveResponse { + next_sequence_receive: next_sequence_recv.into(), + proof: Default::default(), + proof_height: None, + })) + } +} diff --git a/crates/ibc/src/services/mod.rs b/crates/ibc/src/services/mod.rs index 771d38780..210a35c8a 100644 --- a/crates/ibc/src/services/mod.rs +++ b/crates/ibc/src/services/mod.rs @@ -1,2 +1,3 @@ +pub mod channel; pub mod client; pub mod connection; From 505b16fe6ee8a36773681f5d6688e41eb87b9a7e Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 24 Aug 2023 13:48:11 +0200 Subject: [PATCH 05/58] finish grpc service implementations --- crates/ibc/src/core/context.rs | 53 ++++- crates/ibc/src/services/channel.rs | 288 ++++++++++++++++++++++++-- crates/ibc/src/services/client.rs | 126 +++++++++-- crates/ibc/src/services/connection.rs | 45 +++- 4 files changed, 464 insertions(+), 48 deletions(-) diff --git a/crates/ibc/src/core/context.rs b/crates/ibc/src/core/context.rs index b74437af1..c8aca5a43 100644 --- a/crates/ibc/src/core/context.rs +++ b/crates/ibc/src/core/context.rs @@ -21,8 +21,7 @@ use crate::core::ics04_channel::error::ChannelError; use crate::core::ics04_channel::error::PacketError; use crate::core::ics04_channel::packet::{Receipt, Sequence}; use crate::core::ics23_commitment::commitment::CommitmentPrefix; -use crate::core::ics24_host::identifier::ClientId; -use crate::core::ics24_host::identifier::ConnectionId; +use crate::core::ics24_host::identifier::{ClientId, ConnectionId}; use crate::core::ics24_host::path::{ AckPath, ChannelEndPath, ClientConnectionPath, ClientConsensusStatePath, CommitmentPath, ConnectionPath, ReceiptPath, SeqAckPath, SeqRecvPath, SeqSendPath, @@ -33,6 +32,8 @@ use crate::Height; use super::ics02_client::client_state::ClientState; use super::ics02_client::consensus_state::ConsensusState; use super::ics02_client::ClientExecutionContext; +use super::ics03_connection::connection::IdentifiedConnectionEnd; +use super::ics04_channel::channel::IdentifiedChannelEnd; use super::ics24_host::identifier::PortId; /// Top-level error @@ -244,6 +245,54 @@ pub trait ValidationContext { fn validate_message_signer(&self, signer: &Signer) -> Result<(), ContextError>; } +/// Context to be implemented by the host that provides gRPC query services. +/// +/// Trait used for the [`gRPC query services`](crate::services). +pub trait QueryContext: ValidationContext { + // Client queries + fn client_states( + &self, + ) -> Result::AnyClientState)>, ContextError>; + fn consensus_states( + &self, + client_id: &ClientId, + ) -> Result::AnyConsensusState)>, ContextError>; + fn consensus_state_heights(&self, client_id: &ClientId) -> Result, ContextError>; + fn client_status(&self, client_id: &ClientId) -> Result; + + // Connection queries + fn connection_ends(&self) -> Result, ContextError>; + fn client_connection_ends(&self, client_id: &ClientId) -> Result, ContextError>; + + // Channel queries + fn channel_ends(&self) -> Result, ContextError>; + fn connection_channel_ends( + &self, + connection_id: &ConnectionId, + ) -> Result, ContextError>; + + // Packet queries + fn packet_commitments( + &self, + channel_end_path: &ChannelEndPath, + ) -> Result, ContextError>; + fn packet_acknowledgements( + &self, + channel_end_path: &ChannelEndPath, + sequences: impl IntoIterator, + ) -> Result, ContextError>; + fn unreceived_packets( + &self, + channel_end_path: &ChannelEndPath, + sequences: impl IntoIterator, + ) -> Result, ContextError>; + fn unreceived_acks( + &self, + channel_end_path: &ChannelEndPath, + sequences: impl IntoIterator, + ) -> Result, ContextError>; +} + /// Context to be implemented by the host that provides all "write-only" methods. /// /// Trait used for the top-level [`execute`](crate::core::execute) and [`dispatch`](crate::core::dispatch) diff --git a/crates/ibc/src/services/channel.rs b/crates/ibc/src/services/channel.rs index d587a3867..ba93e6ad1 100644 --- a/crates/ibc/src/services/channel.rs +++ b/crates/ibc/src/services/channel.rs @@ -2,12 +2,13 @@ use ibc_proto::{ google::protobuf::Any, ibc::core::{ channel::v1::{ - query_server::Query as ChannelQuery, QueryChannelClientStateRequest, + query_server::Query as ChannelQuery, PacketState, QueryChannelClientStateRequest, QueryChannelClientStateResponse, QueryChannelConsensusStateRequest, QueryChannelConsensusStateResponse, QueryChannelRequest, QueryChannelResponse, QueryChannelsRequest, QueryChannelsResponse, QueryConnectionChannelsRequest, QueryConnectionChannelsResponse, QueryNextSequenceReceiveRequest, - QueryNextSequenceReceiveResponse, QueryPacketAcknowledgementRequest, + QueryNextSequenceReceiveResponse, QueryNextSequenceSendRequest, + QueryNextSequenceSendResponse, QueryPacketAcknowledgementRequest, QueryPacketAcknowledgementResponse, QueryPacketAcknowledgementsRequest, QueryPacketAcknowledgementsResponse, QueryPacketCommitmentRequest, QueryPacketCommitmentResponse, QueryPacketCommitmentsRequest, @@ -23,13 +24,13 @@ use crate::{ core::{ ics04_channel::packet::Sequence, ics24_host::{ - identifier::{ChannelId, PortId}, + identifier::{ChannelId, ConnectionId, PortId}, path::{ AckPath, ChannelEndPath, ClientConsensusStatePath, CommitmentPath, ReceiptPath, - SeqRecvPath, + SeqRecvPath, SeqSendPath, }, }, - ValidationContext, + QueryContext, ValidationContext, }, Height, }; @@ -52,7 +53,7 @@ impl ChannelQueryServer { #[tonic::async_trait] impl ChannelQuery for ChannelQueryServer where - T: ValidationContext + Send + Sync + 'static, + T: QueryContext + Send + Sync + 'static, ::AnyClientState: Into, ::AnyConsensusState: Into, { @@ -92,17 +93,54 @@ where /// Channels queries all the IBC channels of a chain. async fn channels( &self, - _request: Request, + request: Request, ) -> Result, Status> { - todo!() + trace!("Got channels request: {:?}", request); + + let channel_ends = self + .context + .channel_ends() + .map_err(|_| Status::not_found("Channel ends not found"))?; + + Ok(Response::new(QueryChannelsResponse { + channels: channel_ends.into_iter().map(Into::into).collect(), + pagination: None, + height: None, + })) } /// ConnectionChannels queries all the channels associated with a connection /// end. async fn connection_channels( &self, - _request: Request, + request: Request, ) -> Result, Status> { - todo!() + trace!("Got connection channels request: {:?}", request); + + let request_ref = request.get_ref(); + + let connection_id = + ConnectionId::from_str(request_ref.connection.as_str()).map_err(|_| { + Status::invalid_argument(std::format!( + "Invalid connection id: {}", + request_ref.connection + )) + })?; + + let channel_ends = self + .context + .connection_channel_ends(&connection_id) + .map_err(|_| { + Status::not_found(std::format!( + "Connection channels not found for connection {}", + connection_id + )) + })?; + + Ok(Response::new(QueryConnectionChannelsResponse { + channels: channel_ends.into_iter().map(Into::into).collect(), + pagination: None, + height: None, + })) } /// ChannelClientState queries for the client state for the channel associated /// with the provided channel identifiers. @@ -110,6 +148,8 @@ where &self, request: Request, ) -> Result, Status> { + trace!("Got channel client state request: {:?}", request); + let request_ref = request.get_ref(); let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { @@ -175,6 +215,8 @@ where &self, request: Request, ) -> Result, Status> { + trace!("Got channel consensus state request: {:?}", request); + let request_ref = request.get_ref(); let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { @@ -248,6 +290,8 @@ where &self, request: Request, ) -> Result, Status> { + trace!("Got packet commitment request: {:?}", request); + let request_ref = request.get_ref(); let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { @@ -282,13 +326,64 @@ where proof_height: None, })) } + /// PacketCommitments returns all the packet commitments hashes associated /// with a channel. async fn packet_commitments( &self, - _request: Request, + request: Request, ) -> Result, Status> { - todo!() + trace!("Got packet commitments request: {:?}", request); + + let request_ref = request.get_ref(); + + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!( + "Invalid channel id: {}", + request_ref.channel_id + )) + })?; + + let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) + })?; + + let channel_end_path = ChannelEndPath::new(&port_id, &channel_id); + + let commitments = self + .context + .packet_commitments(&channel_end_path) + .map_err(|_| { + Status::not_found(std::format!( + "Packet commitments not found for channel {}", + channel_id + )) + })? + .into_iter() + .map(|path| { + self.context + .get_packet_commitment(&path) + .map(|commitment| PacketState { + port_id: path.port_id.as_str().into(), + channel_id: path.channel_id.as_str().into(), + sequence: path.sequence.into(), + data: commitment.into_vec(), + }) + .map_err(|_| { + Status::not_found(std::format!( + "Packet commitment not found for channel {} and sequence {}", + channel_id, + path.sequence + )) + }) + }) + .collect::>()?; + + Ok(Response::new(QueryPacketCommitmentsResponse { + commitments, + pagination: None, + height: None, + })) } /// PacketReceipt queries if a given packet sequence has been received on the @@ -369,9 +464,63 @@ where /// with a channel. async fn packet_acknowledgements( &self, - _request: Request, + request: Request, ) -> Result, Status> { - todo!() + let request_ref = request.get_ref(); + + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!( + "Invalid channel id: {}", + request_ref.channel_id + )) + })?; + + let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) + })?; + + let commitment_sequences = request_ref + .packet_commitment_sequences + .iter() + .copied() + .map(Sequence::from); + + let channel_end_path = ChannelEndPath::new(&port_id, &channel_id); + + let acknowledgements = self + .context + .packet_acknowledgements(&channel_end_path, commitment_sequences) + .map_err(|_| { + Status::not_found(std::format!( + "Packet acknowledgements not found for channel {}", + channel_id + )) + })? + .into_iter() + .map(|path| { + self.context + .get_packet_acknowledgement(&path) + .map(|acknowledgement| PacketState { + port_id: path.port_id.as_str().into(), + channel_id: path.channel_id.as_str().into(), + sequence: path.sequence.into(), + data: acknowledgement.into_vec(), + }) + .map_err(|_| { + Status::not_found(std::format!( + "Packet acknowledgement not found for channel {} and sequence {}", + channel_id, + path.sequence + )) + }) + }) + .collect::>()?; + + Ok(Response::new(QueryPacketAcknowledgementsResponse { + acknowledgements, + pagination: None, + height: None, + })) } /// UnreceivedPackets returns all the unreceived IBC packets associated with @@ -382,9 +531,43 @@ where /// this query only ever makes sense on unordered channels. async fn unreceived_packets( &self, - _request: Request, + request: Request, ) -> Result, Status> { - todo!() + let request_ref = request.get_ref(); + + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!( + "Invalid channel id: {}", + request_ref.channel_id + )) + })?; + + let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) + })?; + + let sequences = request_ref + .packet_commitment_sequences + .iter() + .copied() + .map(Sequence::from); + + let channel_end_path = ChannelEndPath::new(&port_id, &channel_id); + + let unreceived_packets = self + .context + .unreceived_packets(&channel_end_path, sequences) + .map_err(|_| { + Status::not_found(std::format!( + "Unreceived packets not found for channel {}", + channel_id + )) + })?; + + Ok(Response::new(QueryUnreceivedPacketsResponse { + sequences: unreceived_packets.into_iter().map(Into::into).collect(), + height: None, + })) } /// UnreceivedAcks returns all the unreceived IBC acknowledgements associated @@ -393,7 +576,41 @@ where &self, _request: Request, ) -> Result, Status> { - todo!() + let request_ref = _request.get_ref(); + + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!( + "Invalid channel id: {}", + request_ref.channel_id + )) + })?; + + let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) + })?; + + let sequences = request_ref + .packet_ack_sequences + .iter() + .copied() + .map(Sequence::from); + + let channel_end_path = ChannelEndPath::new(&port_id, &channel_id); + + let unreceived_acks = self + .context + .unreceived_acks(&channel_end_path, sequences) + .map_err(|_| { + Status::not_found(std::format!( + "Unreceived acks not found for channel {}", + channel_id + )) + })?; + + Ok(Response::new(QueryUnreceivedAcksResponse { + sequences: unreceived_acks.into_iter().map(Into::into).collect(), + height: None, + })) } /// NextSequenceReceive returns the next receive sequence for a given channel. @@ -432,4 +649,41 @@ where proof_height: None, })) } + + // NextSequenceSend returns the next send sequence for a given channel. + async fn next_sequence_send( + &self, + request: Request, + ) -> Result, Status> { + let request_ref = request.get_ref(); + + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!( + "Invalid channel id: {}", + request_ref.channel_id + )) + })?; + + let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) + })?; + + let next_seq_send_path = SeqSendPath::new(&port_id, &channel_id); + + let next_sequence_send = self + .context + .get_next_sequence_send(&next_seq_send_path) + .map_err(|_| { + Status::not_found(std::format!( + "Next sequence send not found for channel {}", + channel_id + )) + })?; + + Ok(Response::new(QueryNextSequenceSendResponse { + next_sequence_send: next_sequence_send.into(), + proof: Default::default(), + proof_height: None, + })) + } } diff --git a/crates/ibc/src/services/client.rs b/crates/ibc/src/services/client.rs index 47acd681c..2832f5fea 100644 --- a/crates/ibc/src/services/client.rs +++ b/crates/ibc/src/services/client.rs @@ -1,21 +1,21 @@ use ibc_proto::{ google::protobuf::Any, ibc::core::client::v1::{ - query_server::Query as ClientQuery, QueryClientParamsRequest, QueryClientParamsResponse, - QueryClientStateRequest, QueryClientStateResponse, QueryClientStatesRequest, - QueryClientStatesResponse, QueryClientStatusRequest, QueryClientStatusResponse, - QueryConsensusStateHeightsRequest, QueryConsensusStateHeightsResponse, - QueryConsensusStateRequest, QueryConsensusStateResponse, QueryConsensusStatesRequest, - QueryConsensusStatesResponse, QueryUpgradedClientStateRequest, - QueryUpgradedClientStateResponse, QueryUpgradedConsensusStateRequest, - QueryUpgradedConsensusStateResponse, + query_server::Query as ClientQuery, ConsensusStateWithHeight, IdentifiedClientState, + QueryClientParamsRequest, QueryClientParamsResponse, QueryClientStateRequest, + QueryClientStateResponse, QueryClientStatesRequest, QueryClientStatesResponse, + QueryClientStatusRequest, QueryClientStatusResponse, QueryConsensusStateHeightsRequest, + QueryConsensusStateHeightsResponse, QueryConsensusStateRequest, + QueryConsensusStateResponse, QueryConsensusStatesRequest, QueryConsensusStatesResponse, + QueryUpgradedClientStateRequest, QueryUpgradedClientStateResponse, + QueryUpgradedConsensusStateRequest, QueryUpgradedConsensusStateResponse, }, }; use crate::{ core::{ ics24_host::{identifier::ClientId, path::ClientConsensusStatePath}, - ValidationContext, + QueryContext, ValidationContext, }, Height, }; @@ -38,7 +38,7 @@ impl ClientQueryServer { #[tonic::async_trait] impl ClientQuery for ClientQueryServer where - T: ValidationContext + Send + Sync + 'static, + T: QueryContext + Send + Sync + 'static, ::AnyClientState: Into, ::AnyConsensusState: Into, { @@ -72,7 +72,22 @@ where request: Request, ) -> Result, Status> { trace!("Got client states request: {:?}", request); - todo!() + + let client_states = self + .context + .client_states() + .map_err(|_| Status::not_found("Client states not found"))?; + + Ok(Response::new(QueryClientStatesResponse { + client_states: client_states + .into_iter() + .map(|(id, state)| IdentifiedClientState { + client_id: id.into(), + client_state: Some(state.into()), + }) + .collect(), + pagination: None, + })) } async fn consensus_state( @@ -119,41 +134,108 @@ where request: Request, ) -> Result, Status> { trace!("Got consensus states request: {:?}", request); - todo!(); + + let request_ref = request.get_ref(); + + let client_id = ClientId::from_str(request_ref.client_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!("Invalid client id: {}", request_ref.client_id)) + })?; + + let consensus_states = self.context.consensus_states(&client_id).map_err(|_| { + Status::not_found(std::format!( + "Consensus states not found for client {}", + client_id + )) + })?; + + Ok(Response::new(QueryConsensusStatesResponse { + consensus_states: consensus_states + .into_iter() + .map(|(height, state)| ConsensusStateWithHeight { + height: Some(height.into()), + consensus_state: Some(state.into()), + }) + .collect(), + pagination: None, + })) } async fn consensus_state_heights( &self, - _request: Request, + request: Request, ) -> Result, Status> { - todo!() + trace!("Got consensus state heights request: {:?}", request); + + let request_ref = request.get_ref(); + + let client_id = ClientId::from_str(request_ref.client_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!("Invalid client id: {}", request_ref.client_id)) + })?; + + let consensus_state_heights = + self.context + .consensus_state_heights(&client_id) + .map_err(|_| { + Status::not_found(std::format!( + "Consensus state heights not found for client {}", + client_id + )) + })?; + + Ok(Response::new(QueryConsensusStateHeightsResponse { + consensus_state_heights: consensus_state_heights + .into_iter() + .map(|height| height.into()) + .collect(), + pagination: None, + })) } async fn client_status( &self, - _request: Request, + request: Request, ) -> Result, Status> { - unimplemented!() + trace!("Got client status request: {:?}", request); + + let request_ref = request.get_ref(); + + let client_id = ClientId::from_str(request_ref.client_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!("Invalid client id: {}", request_ref.client_id)) + })?; + + let client_status = self.context.client_status(&client_id).map_err(|_| { + Status::not_found(std::format!( + "Client status not found for client {}", + client_id + )) + })?; + + Ok(Response::new(QueryClientStatusResponse { + status: client_status, + })) } async fn client_params( &self, - _request: Request, + request: Request, ) -> Result, Status> { - unimplemented!() + trace!("Got client params request: {:?}", request); + Err(Status::unimplemented("Not implemented")) } async fn upgraded_client_state( &self, - _request: Request, + request: Request, ) -> Result, Status> { - unimplemented!() + trace!("Got upgraded client state request: {:?}", request); + Err(Status::unimplemented("Not implemented")) } async fn upgraded_consensus_state( &self, - _request: Request, + request: Request, ) -> Result, Status> { - unimplemented!() + trace!("Got upgraded consensus state request: {:?}", request); + Err(Status::unimplemented("Not implemented")) } } diff --git a/crates/ibc/src/services/connection.rs b/crates/ibc/src/services/connection.rs index 4d7bf7515..21483939c 100644 --- a/crates/ibc/src/services/connection.rs +++ b/crates/ibc/src/services/connection.rs @@ -15,8 +15,11 @@ use ibc_proto::{ use crate::{ core::{ - ics24_host::{identifier::ConnectionId, path::ClientConsensusStatePath}, - ValidationContext, + ics24_host::{ + identifier::{ClientId, ConnectionId}, + path::ClientConsensusStatePath, + }, + QueryContext, ValidationContext, }, Height, }; @@ -39,7 +42,7 @@ impl ConnectionQueryServer { #[tonic::async_trait] impl ConnectionQuery for ConnectionQueryServer where - T: ValidationContext + Send + Sync + 'static, + T: QueryContext + Send + Sync + 'static, ::AnyClientState: Into, ::AnyConsensusState: Into, { @@ -73,9 +76,20 @@ where async fn connections( &self, - _request: Request, + request: Request, ) -> Result, Status> { - todo!() + trace!("Got connections request: {:?}", request); + + let connections = self + .context + .connection_ends() + .map_err(|_| Status::not_found("Connections not found"))?; + + Ok(Response::new(QueryConnectionsResponse { + connections: connections.into_iter().map(Into::into).collect(), + pagination: None, + height: None, + })) } async fn client_connections( @@ -83,7 +97,23 @@ where request: Request, ) -> Result, Status> { trace!("Got client connections request: {:?}", request); - todo!() + + let request_ref = request.get_ref(); + + let client_id = ClientId::from_str(request_ref.client_id.as_str()).map_err(|_| { + Status::invalid_argument(std::format!("Invalid client id: {}", request_ref.client_id)) + })?; + + let connections = self + .context + .client_connection_ends(&client_id) + .map_err(|_| Status::not_found("Connections not found"))?; + + Ok(Response::new(QueryClientConnectionsResponse { + connection_paths: connections, + proof: Default::default(), + proof_height: None, + })) } async fn connection_client_state( @@ -180,6 +210,7 @@ where &self, _request: Request, ) -> Result, Status> { - todo!() + trace!("Got connection params request: {:?}", _request); + Err(Status::unimplemented("Not implemented")) } } From 096324500366f5e8fba5ec204f8c6a125fd9d4cb Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 24 Aug 2023 14:38:35 +0200 Subject: [PATCH 06/58] QueryContext under grpc feature --- crates/ibc/src/core/context.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/ibc/src/core/context.rs b/crates/ibc/src/core/context.rs index c8aca5a43..42c22cce8 100644 --- a/crates/ibc/src/core/context.rs +++ b/crates/ibc/src/core/context.rs @@ -248,6 +248,7 @@ pub trait ValidationContext { /// Context to be implemented by the host that provides gRPC query services. /// /// Trait used for the [`gRPC query services`](crate::services). +#[cfg(feature = "grpc")] pub trait QueryContext: ValidationContext { // Client queries fn client_states( From efcbc88db88df23e106e8e5eda1594ac5924c367 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 24 Aug 2023 14:53:22 +0200 Subject: [PATCH 07/58] fix no-default-features lints --- crates/ibc/src/core/context.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/ibc/src/core/context.rs b/crates/ibc/src/core/context.rs index 42c22cce8..02823f95e 100644 --- a/crates/ibc/src/core/context.rs +++ b/crates/ibc/src/core/context.rs @@ -32,10 +32,14 @@ use crate::Height; use super::ics02_client::client_state::ClientState; use super::ics02_client::consensus_state::ConsensusState; use super::ics02_client::ClientExecutionContext; -use super::ics03_connection::connection::IdentifiedConnectionEnd; -use super::ics04_channel::channel::IdentifiedChannelEnd; use super::ics24_host::identifier::PortId; +#[cfg(feature = "grpc")] +use super::{ + ics03_connection::connection::IdentifiedConnectionEnd, + ics04_channel::channel::IdentifiedChannelEnd, +}; + /// Top-level error #[derive(Debug, Display, From)] pub enum ContextError { From 0931f242b3c5294296af7ee12cdc19eaf31cfe78 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 24 Aug 2023 20:48:14 +0200 Subject: [PATCH 08/58] use domain types --- crates/ibc/src/core/context.rs | 9 ++++++--- crates/ibc/src/services/client.rs | 2 +- crates/ibc/src/services/connection.rs | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/crates/ibc/src/core/context.rs b/crates/ibc/src/core/context.rs index 02823f95e..8034754c8 100644 --- a/crates/ibc/src/core/context.rs +++ b/crates/ibc/src/core/context.rs @@ -29,7 +29,7 @@ use crate::core::ics24_host::path::{ use crate::core::timestamp::Timestamp; use crate::Height; -use super::ics02_client::client_state::ClientState; +use super::ics02_client::client_state::{ClientState, Status}; use super::ics02_client::consensus_state::ConsensusState; use super::ics02_client::ClientExecutionContext; use super::ics24_host::identifier::PortId; @@ -263,11 +263,14 @@ pub trait QueryContext: ValidationContext { client_id: &ClientId, ) -> Result::AnyConsensusState)>, ContextError>; fn consensus_state_heights(&self, client_id: &ClientId) -> Result, ContextError>; - fn client_status(&self, client_id: &ClientId) -> Result; + fn client_status(&self, client_id: &ClientId) -> Result; // Connection queries fn connection_ends(&self) -> Result, ContextError>; - fn client_connection_ends(&self, client_id: &ClientId) -> Result, ContextError>; + fn client_connection_ends( + &self, + client_id: &ClientId, + ) -> Result, ContextError>; // Channel queries fn channel_ends(&self) -> Result, ContextError>; diff --git a/crates/ibc/src/services/client.rs b/crates/ibc/src/services/client.rs index 2832f5fea..4ae4ef572 100644 --- a/crates/ibc/src/services/client.rs +++ b/crates/ibc/src/services/client.rs @@ -211,7 +211,7 @@ where })?; Ok(Response::new(QueryClientStatusResponse { - status: client_status, + status: std::format!("{}", client_status), })) } diff --git a/crates/ibc/src/services/connection.rs b/crates/ibc/src/services/connection.rs index 21483939c..c05e41328 100644 --- a/crates/ibc/src/services/connection.rs +++ b/crates/ibc/src/services/connection.rs @@ -110,7 +110,7 @@ where .map_err(|_| Status::not_found("Connections not found"))?; Ok(Response::new(QueryClientConnectionsResponse { - connection_paths: connections, + connection_paths: connections.into_iter().map(|x| x.as_str().into()).collect(), proof: Default::default(), proof_height: None, })) From cb7512936f42bb8b1c53fc2634cbec2cb07c87d7 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 24 Aug 2023 22:12:20 +0200 Subject: [PATCH 09/58] return query block height --- crates/ibc/src/services/channel.rs | 42 +++++++++++++++++++++++---- crates/ibc/src/services/connection.rs | 7 ++++- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/crates/ibc/src/services/channel.rs b/crates/ibc/src/services/channel.rs index ba93e6ad1..3ade4bf68 100644 --- a/crates/ibc/src/services/channel.rs +++ b/crates/ibc/src/services/channel.rs @@ -105,7 +105,12 @@ where Ok(Response::new(QueryChannelsResponse { channels: channel_ends.into_iter().map(Into::into).collect(), pagination: None, - height: None, + height: Some( + self.context + .host_height() + .map_err(|_| Status::not_found("Host chain height not found"))? + .into(), + ), })) } /// ConnectionChannels queries all the channels associated with a connection @@ -139,7 +144,12 @@ where Ok(Response::new(QueryConnectionChannelsResponse { channels: channel_ends.into_iter().map(Into::into).collect(), pagination: None, - height: None, + height: Some( + self.context + .host_height() + .map_err(|_| Status::not_found("Host chain height not found"))? + .into(), + ), })) } /// ChannelClientState queries for the client state for the channel associated @@ -382,7 +392,12 @@ where Ok(Response::new(QueryPacketCommitmentsResponse { commitments, pagination: None, - height: None, + height: Some( + self.context + .host_height() + .map_err(|_| Status::not_found("Host chain height not found"))? + .into(), + ), })) } @@ -519,7 +534,12 @@ where Ok(Response::new(QueryPacketAcknowledgementsResponse { acknowledgements, pagination: None, - height: None, + height: Some( + self.context + .host_height() + .map_err(|_| Status::not_found("Host chain height not found"))? + .into(), + ), })) } @@ -566,7 +586,12 @@ where Ok(Response::new(QueryUnreceivedPacketsResponse { sequences: unreceived_packets.into_iter().map(Into::into).collect(), - height: None, + height: Some( + self.context + .host_height() + .map_err(|_| Status::not_found("Host chain height not found"))? + .into(), + ), })) } @@ -609,7 +634,12 @@ where Ok(Response::new(QueryUnreceivedAcksResponse { sequences: unreceived_acks.into_iter().map(Into::into).collect(), - height: None, + height: Some( + self.context + .host_height() + .map_err(|_| Status::not_found("Host chain height not found"))? + .into(), + ), })) } diff --git a/crates/ibc/src/services/connection.rs b/crates/ibc/src/services/connection.rs index c05e41328..1ab5b3938 100644 --- a/crates/ibc/src/services/connection.rs +++ b/crates/ibc/src/services/connection.rs @@ -88,7 +88,12 @@ where Ok(Response::new(QueryConnectionsResponse { connections: connections.into_iter().map(Into::into).collect(), pagination: None, - height: None, + height: Some( + self.context + .host_height() + .map_err(|_| Status::not_found("Host chain height not found"))? + .into(), + ), })) } From 6eb22d3efe43a5b3deb6b469e3dbed753b93aac1 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 24 Aug 2023 22:17:40 +0200 Subject: [PATCH 10/58] happy lint --- crates/ibc/src/core/context.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/ibc/src/core/context.rs b/crates/ibc/src/core/context.rs index 8034754c8..e2a5d50db 100644 --- a/crates/ibc/src/core/context.rs +++ b/crates/ibc/src/core/context.rs @@ -29,14 +29,14 @@ use crate::core::ics24_host::path::{ use crate::core::timestamp::Timestamp; use crate::Height; -use super::ics02_client::client_state::{ClientState, Status}; +use super::ics02_client::client_state::ClientState; use super::ics02_client::consensus_state::ConsensusState; use super::ics02_client::ClientExecutionContext; use super::ics24_host::identifier::PortId; #[cfg(feature = "grpc")] use super::{ - ics03_connection::connection::IdentifiedConnectionEnd, + ics02_client::client_state::Status, ics03_connection::connection::IdentifiedConnectionEnd, ics04_channel::channel::IdentifiedChannelEnd, }; From cc38d8de5c5828a41816d2e98d73c96a706bd74a Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Mon, 28 Aug 2023 17:30:42 +0200 Subject: [PATCH 11/58] immut router in validate --- crates/ibc/src/core/handler.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/crates/ibc/src/core/handler.rs b/crates/ibc/src/core/handler.rs index faa3216a6..75cd23aa7 100644 --- a/crates/ibc/src/core/handler.rs +++ b/crates/ibc/src/core/handler.rs @@ -51,11 +51,7 @@ pub fn dispatch( /// That is, the state transition of message `i` must be applied before /// message `i+1` is validated. This is equivalent to calling /// `dispatch()` on each successively. -pub fn validate( - ctx: &Ctx, - router: &mut impl Router, - msg: MsgEnvelope, -) -> Result<(), RouterError> +pub fn validate(ctx: &Ctx, router: &impl Router, msg: MsgEnvelope) -> Result<(), RouterError> where Ctx: ValidationContext, { From 42c7f7aa97a9bf24b24f28590592fcf74538f409 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Mon, 28 Aug 2023 18:39:36 +0200 Subject: [PATCH 12/58] client and connection param service --- crates/ibc/src/core/context.rs | 1 + crates/ibc/src/services/client.rs | 27 +++++++++++++++++++-------- crates/ibc/src/services/connection.rs | 23 ++++++++++++++--------- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/crates/ibc/src/core/context.rs b/crates/ibc/src/core/context.rs index e2a5d50db..455a67577 100644 --- a/crates/ibc/src/core/context.rs +++ b/crates/ibc/src/core/context.rs @@ -264,6 +264,7 @@ pub trait QueryContext: ValidationContext { ) -> Result::AnyConsensusState)>, ContextError>; fn consensus_state_heights(&self, client_id: &ClientId) -> Result, ContextError>; fn client_status(&self, client_id: &ClientId) -> Result; + fn allowed_clients(&self) -> Vec; // Connection queries fn connection_ends(&self) -> Result, ContextError>; diff --git a/crates/ibc/src/services/client.rs b/crates/ibc/src/services/client.rs index 4ae4ef572..d0a4b0514 100644 --- a/crates/ibc/src/services/client.rs +++ b/crates/ibc/src/services/client.rs @@ -2,13 +2,14 @@ use ibc_proto::{ google::protobuf::Any, ibc::core::client::v1::{ query_server::Query as ClientQuery, ConsensusStateWithHeight, IdentifiedClientState, - QueryClientParamsRequest, QueryClientParamsResponse, QueryClientStateRequest, - QueryClientStateResponse, QueryClientStatesRequest, QueryClientStatesResponse, - QueryClientStatusRequest, QueryClientStatusResponse, QueryConsensusStateHeightsRequest, - QueryConsensusStateHeightsResponse, QueryConsensusStateRequest, - QueryConsensusStateResponse, QueryConsensusStatesRequest, QueryConsensusStatesResponse, - QueryUpgradedClientStateRequest, QueryUpgradedClientStateResponse, - QueryUpgradedConsensusStateRequest, QueryUpgradedConsensusStateResponse, + Params as ClientParams, QueryClientParamsRequest, QueryClientParamsResponse, + QueryClientStateRequest, QueryClientStateResponse, QueryClientStatesRequest, + QueryClientStatesResponse, QueryClientStatusRequest, QueryClientStatusResponse, + QueryConsensusStateHeightsRequest, QueryConsensusStateHeightsResponse, + QueryConsensusStateRequest, QueryConsensusStateResponse, QueryConsensusStatesRequest, + QueryConsensusStatesResponse, QueryUpgradedClientStateRequest, + QueryUpgradedClientStateResponse, QueryUpgradedConsensusStateRequest, + QueryUpgradedConsensusStateResponse, }, }; @@ -220,7 +221,17 @@ where request: Request, ) -> Result, Status> { trace!("Got client params request: {:?}", request); - Err(Status::unimplemented("Not implemented")) + + Ok(Response::new(QueryClientParamsResponse { + params: Some(ClientParams { + allowed_clients: self + .context + .allowed_clients() + .into_iter() + .map(|x| x.as_str().into()) + .collect(), + }), + })) } async fn upgraded_client_state( diff --git a/crates/ibc/src/services/connection.rs b/crates/ibc/src/services/connection.rs index 1ab5b3938..fb7f61114 100644 --- a/crates/ibc/src/services/connection.rs +++ b/crates/ibc/src/services/connection.rs @@ -3,12 +3,12 @@ use ibc_proto::{ ibc::core::{ client::v1::IdentifiedClientState, connection::v1::{ - query_server::Query as ConnectionQuery, QueryClientConnectionsRequest, - QueryClientConnectionsResponse, QueryConnectionClientStateRequest, - QueryConnectionClientStateResponse, QueryConnectionConsensusStateRequest, - QueryConnectionConsensusStateResponse, QueryConnectionParamsRequest, - QueryConnectionParamsResponse, QueryConnectionRequest, QueryConnectionResponse, - QueryConnectionsRequest, QueryConnectionsResponse, + query_server::Query as ConnectionQuery, Params as ConnectionParams, + QueryClientConnectionsRequest, QueryClientConnectionsResponse, + QueryConnectionClientStateRequest, QueryConnectionClientStateResponse, + QueryConnectionConsensusStateRequest, QueryConnectionConsensusStateResponse, + QueryConnectionParamsRequest, QueryConnectionParamsResponse, QueryConnectionRequest, + QueryConnectionResponse, QueryConnectionsRequest, QueryConnectionsResponse, }, }, }; @@ -213,9 +213,14 @@ where async fn connection_params( &self, - _request: Request, + request: Request, ) -> Result, Status> { - trace!("Got connection params request: {:?}", _request); - Err(Status::unimplemented("Not implemented")) + trace!("Got connection params request: {:?}", request); + + Ok(Response::new(QueryConnectionParamsResponse { + params: Some(ConnectionParams { + max_expected_time_per_block: self.context.max_expected_time_per_block().as_secs(), + }), + })) } } From 3bb8f54465feedea44e60da9041eb1620888aaa6 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Mon, 28 Aug 2023 19:11:41 +0200 Subject: [PATCH 13/58] implement upgrade service --- crates/ibc/src/core/context.rs | 14 +++++++--- crates/ibc/src/services/client.rs | 45 ++++++++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/crates/ibc/src/core/context.rs b/crates/ibc/src/core/context.rs index 455a67577..aa6c1df56 100644 --- a/crates/ibc/src/core/context.rs +++ b/crates/ibc/src/core/context.rs @@ -30,14 +30,20 @@ use crate::core::timestamp::Timestamp; use crate::Height; use super::ics02_client::client_state::ClientState; +use super::ics02_client::client_type::ClientType; use super::ics02_client::consensus_state::ConsensusState; use super::ics02_client::ClientExecutionContext; use super::ics24_host::identifier::PortId; +use super::ics24_host::path::Path; + #[cfg(feature = "grpc")] -use super::{ - ics02_client::client_state::Status, ics03_connection::connection::IdentifiedConnectionEnd, - ics04_channel::channel::IdentifiedChannelEnd, +use crate::{ + core::{ + ics02_client::client_state::Status, ics03_connection::connection::IdentifiedConnectionEnd, + ics04_channel::channel::IdentifiedChannelEnd, + }, + hosts::tendermint::upgrade_proposal::UpgradeValidationContext, }; /// Top-level error @@ -253,7 +259,7 @@ pub trait ValidationContext { /// /// Trait used for the [`gRPC query services`](crate::services). #[cfg(feature = "grpc")] -pub trait QueryContext: ValidationContext { +pub trait QueryContext: UpgradeValidationContext + ValidationContext { // Client queries fn client_states( &self, diff --git a/crates/ibc/src/services/client.rs b/crates/ibc/src/services/client.rs index d0a4b0514..c45d6b58f 100644 --- a/crates/ibc/src/services/client.rs +++ b/crates/ibc/src/services/client.rs @@ -15,9 +15,13 @@ use ibc_proto::{ use crate::{ core::{ - ics24_host::{identifier::ClientId, path::ClientConsensusStatePath}, + ics24_host::{ + identifier::ClientId, + path::{ClientConsensusStatePath, UpgradeClientPath}, + }, QueryContext, ValidationContext, }, + hosts::tendermint::upgrade_proposal::UpgradeValidationContext, Height, }; @@ -42,6 +46,8 @@ where T: QueryContext + Send + Sync + 'static, ::AnyClientState: Into, ::AnyConsensusState: Into, + ::AnyClientState: Into, + ::AnyConsensusState: Into, { async fn client_state( &self, @@ -239,7 +245,23 @@ where request: Request, ) -> Result, Status> { trace!("Got upgraded client state request: {:?}", request); - Err(Status::unimplemented("Not implemented")) + + let plan = self + .context + .upgrade_plan() + .map_err(|_| Status::not_found("Upgrade plan not found"))?; + + let upgraded_client_state_path = UpgradeClientPath::UpgradedClientState(plan.height); + + let upgraded_client_state = UpgradeValidationContext::upgraded_client_state( + &self.context, + &upgraded_client_state_path, + ) + .map_err(|_| Status::not_found("Upgraded client state not found"))?; + + Ok(Response::new(QueryUpgradedClientStateResponse { + upgraded_client_state: Some(upgraded_client_state.into()), + })) } async fn upgraded_consensus_state( @@ -247,6 +269,23 @@ where request: Request, ) -> Result, Status> { trace!("Got upgraded consensus state request: {:?}", request); - Err(Status::unimplemented("Not implemented")) + + let plan = self + .context + .upgrade_plan() + .map_err(|_| Status::not_found("Upgrade plan not found"))?; + + let upgraded_consensus_state_path = + UpgradeClientPath::UpgradedClientConsensusState(plan.height); + + let upgraded_consensus_state = UpgradeValidationContext::upgraded_consensus_state( + &self.context, + &upgraded_consensus_state_path, + ) + .map_err(|_| Status::not_found("Upgraded consensus state not found"))?; + + Ok(Response::new(QueryUpgradedConsensusStateResponse { + upgraded_consensus_state: Some(upgraded_consensus_state.into()), + })) } } From f0ee9ec3608ca019e083422176695037694a7088 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Mon, 28 Aug 2023 19:20:12 +0200 Subject: [PATCH 14/58] fix upgrade context --- crates/ibc/src/services/client.rs | 41 +++++++++++++++++-------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/crates/ibc/src/services/client.rs b/crates/ibc/src/services/client.rs index c45d6b58f..1f14a1aad 100644 --- a/crates/ibc/src/services/client.rs +++ b/crates/ibc/src/services/client.rs @@ -30,24 +30,29 @@ use std::boxed::Box; use tonic::{Request, Response, Status}; use tracing::trace; -pub struct ClientQueryServer { +pub struct ClientQueryServer { context: T, + upgrade_context: U, } -impl ClientQueryServer { - pub fn new(context: T) -> Self { - Self { context } +impl ClientQueryServer { + pub fn new(context: T, upgrade_context: U) -> Self { + Self { + context, + upgrade_context, + } } } #[tonic::async_trait] -impl ClientQuery for ClientQueryServer +impl ClientQuery for ClientQueryServer where T: QueryContext + Send + Sync + 'static, + U: UpgradeValidationContext + Send + Sync + 'static, ::AnyClientState: Into, ::AnyConsensusState: Into, - ::AnyClientState: Into, - ::AnyConsensusState: Into, + ::AnyClientState: Into, + ::AnyConsensusState: Into, { async fn client_state( &self, @@ -247,17 +252,16 @@ where trace!("Got upgraded client state request: {:?}", request); let plan = self - .context + .upgrade_context .upgrade_plan() .map_err(|_| Status::not_found("Upgrade plan not found"))?; let upgraded_client_state_path = UpgradeClientPath::UpgradedClientState(plan.height); - let upgraded_client_state = UpgradeValidationContext::upgraded_client_state( - &self.context, - &upgraded_client_state_path, - ) - .map_err(|_| Status::not_found("Upgraded client state not found"))?; + let upgraded_client_state = self + .upgrade_context + .upgraded_client_state(&upgraded_client_state_path) + .map_err(|_| Status::not_found("Upgraded client state not found"))?; Ok(Response::new(QueryUpgradedClientStateResponse { upgraded_client_state: Some(upgraded_client_state.into()), @@ -271,18 +275,17 @@ where trace!("Got upgraded consensus state request: {:?}", request); let plan = self - .context + .upgrade_context .upgrade_plan() .map_err(|_| Status::not_found("Upgrade plan not found"))?; let upgraded_consensus_state_path = UpgradeClientPath::UpgradedClientConsensusState(plan.height); - let upgraded_consensus_state = UpgradeValidationContext::upgraded_consensus_state( - &self.context, - &upgraded_consensus_state_path, - ) - .map_err(|_| Status::not_found("Upgraded consensus state not found"))?; + let upgraded_consensus_state = self + .upgrade_context + .upgraded_consensus_state(&upgraded_consensus_state_path) + .map_err(|_| Status::not_found("Upgraded consensus state not found"))?; Ok(Response::new(QueryUpgradedConsensusStateResponse { upgraded_consensus_state: Some(upgraded_consensus_state.into()), From 2c4354f2a2513fe5b077b016220b91361577c397 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Mon, 28 Aug 2023 19:24:34 +0200 Subject: [PATCH 15/58] rename struct fields and generics --- crates/ibc/src/services/channel.rs | 124 ++++++++++++++------------ crates/ibc/src/services/client.rs | 48 +++++----- crates/ibc/src/services/connection.rs | 91 +++++++++++-------- 3 files changed, 145 insertions(+), 118 deletions(-) diff --git a/crates/ibc/src/services/channel.rs b/crates/ibc/src/services/channel.rs index 3ade4bf68..a540c79d9 100644 --- a/crates/ibc/src/services/channel.rs +++ b/crates/ibc/src/services/channel.rs @@ -40,22 +40,22 @@ use std::boxed::Box; use tonic::{Request, Response, Status}; use tracing::trace; -pub struct ChannelQueryServer { - context: T, +pub struct ChannelQueryServer { + ibc_context: I, } -impl ChannelQueryServer { - pub fn new(context: T) -> Self { - Self { context } +impl ChannelQueryServer { + pub fn new(ibc_context: I) -> Self { + Self { ibc_context } } } #[tonic::async_trait] -impl ChannelQuery for ChannelQueryServer +impl ChannelQuery for ChannelQueryServer where - T: QueryContext + Send + Sync + 'static, - ::AnyClientState: Into, - ::AnyConsensusState: Into, + I: QueryContext + Send + Sync + 'static, + ::AnyClientState: Into, + ::AnyConsensusState: Into, { async fn channel( &self, @@ -77,12 +77,15 @@ where let channel_end_path = ChannelEndPath::new(&port_id, &channel_id); - let channel_end = self.context.channel_end(&channel_end_path).map_err(|_| { - Status::not_found(std::format!( - "Channel end not found for channel {}", - channel_id - )) - })?; + let channel_end = self + .ibc_context + .channel_end(&channel_end_path) + .map_err(|_| { + Status::not_found(std::format!( + "Channel end not found for channel {}", + channel_id + )) + })?; Ok(Response::new(QueryChannelResponse { channel: Some(channel_end.into()), @@ -98,7 +101,7 @@ where trace!("Got channels request: {:?}", request); let channel_ends = self - .context + .ibc_context .channel_ends() .map_err(|_| Status::not_found("Channel ends not found"))?; @@ -106,7 +109,7 @@ where channels: channel_ends.into_iter().map(Into::into).collect(), pagination: None, height: Some( - self.context + self.ibc_context .host_height() .map_err(|_| Status::not_found("Host chain height not found"))? .into(), @@ -132,7 +135,7 @@ where })?; let channel_ends = self - .context + .ibc_context .connection_channel_ends(&connection_id) .map_err(|_| { Status::not_found(std::format!( @@ -145,7 +148,7 @@ where channels: channel_ends.into_iter().map(Into::into).collect(), pagination: None, height: Some( - self.context + self.ibc_context .host_height() .map_err(|_| Status::not_found("Host chain height not found"))? .into(), @@ -175,18 +178,21 @@ where let channel_end_path = ChannelEndPath::new(&port_id, &channel_id); - let channel_end = self.context.channel_end(&channel_end_path).map_err(|_| { - Status::not_found(std::format!( - "Channel end not found for channel {}", - channel_id - )) - })?; + let channel_end = self + .ibc_context + .channel_end(&channel_end_path) + .map_err(|_| { + Status::not_found(std::format!( + "Channel end not found for channel {}", + channel_id + )) + })?; let connection_end = channel_end .connection_hops() .first() .map(|connection_id| { - self.context.connection_end(connection_id).map_err(|_| { + self.ibc_context.connection_end(connection_id).map_err(|_| { Status::not_found(std::format!( "Connection end not found for connection {}", connection_id @@ -201,7 +207,7 @@ where })??; let client_state = self - .context + .ibc_context .client_state(connection_end.client_id()) .map_err(|_| { Status::not_found(std::format!( @@ -242,18 +248,21 @@ where let channel_end_path = ChannelEndPath::new(&port_id, &channel_id); - let channel_end = self.context.channel_end(&channel_end_path).map_err(|_| { - Status::not_found(std::format!( - "Channel end not found for channel {}", - channel_id - )) - })?; + let channel_end = self + .ibc_context + .channel_end(&channel_end_path) + .map_err(|_| { + Status::not_found(std::format!( + "Channel end not found for channel {}", + channel_id + )) + })?; let connection_end = channel_end .connection_hops() .first() .map(|connection_id| { - self.context.connection_end(connection_id).map_err(|_| { + self.ibc_context.connection_end(connection_id).map_err(|_| { Status::not_found(std::format!( "Connection end not found for connection {}", connection_id @@ -280,13 +289,16 @@ where )?, ); - let consensus_state = self.context.consensus_state(&consensus_path).map_err(|_| { - Status::not_found(std::format!( - "Consensus state not found for client {} and revision {}", - connection_end.client_id(), - request_ref.revision_number - )) - })?; + let consensus_state = self + .ibc_context + .consensus_state(&consensus_path) + .map_err(|_| { + Status::not_found(std::format!( + "Consensus state not found for client {} and revision {}", + connection_end.client_id(), + request_ref.revision_number + )) + })?; Ok(Response::new(QueryChannelConsensusStateResponse { client_id: connection_end.client_id().as_str().into(), @@ -320,7 +332,7 @@ where let commitment_path = CommitmentPath::new(&port_id, &channel_id, sequence); let packet_commitment_data = self - .context + .ibc_context .get_packet_commitment(&commitment_path) .map_err(|_| { Status::not_found(std::format!( @@ -361,7 +373,7 @@ where let channel_end_path = ChannelEndPath::new(&port_id, &channel_id); let commitments = self - .context + .ibc_context .packet_commitments(&channel_end_path) .map_err(|_| { Status::not_found(std::format!( @@ -371,7 +383,7 @@ where })? .into_iter() .map(|path| { - self.context + self.ibc_context .get_packet_commitment(&path) .map(|commitment| PacketState { port_id: path.port_id.as_str().into(), @@ -393,7 +405,7 @@ where commitments, pagination: None, height: Some( - self.context + self.ibc_context .host_height() .map_err(|_| Status::not_found("Host chain height not found"))? .into(), @@ -426,7 +438,7 @@ where // Receipt only has one enum // Unreceived packets are not stored - let packet_receipt_data = self.context.get_packet_receipt(&receipt_path); + let packet_receipt_data = self.ibc_context.get_packet_receipt(&receipt_path); Ok(Response::new(QueryPacketReceiptResponse { received: packet_receipt_data.is_ok(), @@ -458,7 +470,7 @@ where let acknowledgement_path = AckPath::new(&port_id, &channel_id, sequence); let packet_acknowledgement_data = self - .context + .ibc_context .get_packet_acknowledgement(&acknowledgement_path) .map_err(|_| { Status::not_found(std::format!( @@ -503,7 +515,7 @@ where let channel_end_path = ChannelEndPath::new(&port_id, &channel_id); let acknowledgements = self - .context + .ibc_context .packet_acknowledgements(&channel_end_path, commitment_sequences) .map_err(|_| { Status::not_found(std::format!( @@ -513,7 +525,7 @@ where })? .into_iter() .map(|path| { - self.context + self.ibc_context .get_packet_acknowledgement(&path) .map(|acknowledgement| PacketState { port_id: path.port_id.as_str().into(), @@ -535,7 +547,7 @@ where acknowledgements, pagination: None, height: Some( - self.context + self.ibc_context .host_height() .map_err(|_| Status::not_found("Host chain height not found"))? .into(), @@ -575,7 +587,7 @@ where let channel_end_path = ChannelEndPath::new(&port_id, &channel_id); let unreceived_packets = self - .context + .ibc_context .unreceived_packets(&channel_end_path, sequences) .map_err(|_| { Status::not_found(std::format!( @@ -587,7 +599,7 @@ where Ok(Response::new(QueryUnreceivedPacketsResponse { sequences: unreceived_packets.into_iter().map(Into::into).collect(), height: Some( - self.context + self.ibc_context .host_height() .map_err(|_| Status::not_found("Host chain height not found"))? .into(), @@ -623,7 +635,7 @@ where let channel_end_path = ChannelEndPath::new(&port_id, &channel_id); let unreceived_acks = self - .context + .ibc_context .unreceived_acks(&channel_end_path, sequences) .map_err(|_| { Status::not_found(std::format!( @@ -635,7 +647,7 @@ where Ok(Response::new(QueryUnreceivedAcksResponse { sequences: unreceived_acks.into_iter().map(Into::into).collect(), height: Some( - self.context + self.ibc_context .host_height() .map_err(|_| Status::not_found("Host chain height not found"))? .into(), @@ -664,7 +676,7 @@ where let next_seq_recv_path = SeqRecvPath::new(&port_id, &channel_id); let next_sequence_recv = self - .context + .ibc_context .get_next_sequence_recv(&next_seq_recv_path) .map_err(|_| { Status::not_found(std::format!( @@ -701,7 +713,7 @@ where let next_seq_send_path = SeqSendPath::new(&port_id, &channel_id); let next_sequence_send = self - .context + .ibc_context .get_next_sequence_send(&next_seq_send_path) .map_err(|_| { Status::not_found(std::format!( diff --git a/crates/ibc/src/services/client.rs b/crates/ibc/src/services/client.rs index 1f14a1aad..3a7da5fdb 100644 --- a/crates/ibc/src/services/client.rs +++ b/crates/ibc/src/services/client.rs @@ -30,27 +30,27 @@ use std::boxed::Box; use tonic::{Request, Response, Status}; use tracing::trace; -pub struct ClientQueryServer { - context: T, +pub struct ClientQueryServer { + ibc_context: I, upgrade_context: U, } -impl ClientQueryServer { - pub fn new(context: T, upgrade_context: U) -> Self { +impl ClientQueryServer { + pub fn new(ibc_context: I, upgrade_context: U) -> Self { Self { - context, + ibc_context, upgrade_context, } } } #[tonic::async_trait] -impl ClientQuery for ClientQueryServer +impl ClientQuery for ClientQueryServer where - T: QueryContext + Send + Sync + 'static, + I: QueryContext + Send + Sync + 'static, U: UpgradeValidationContext + Send + Sync + 'static, - ::AnyClientState: Into, - ::AnyConsensusState: Into, + ::AnyClientState: Into, + ::AnyConsensusState: Into, ::AnyClientState: Into, ::AnyConsensusState: Into, { @@ -65,7 +65,7 @@ where let client_id = ClientId::from_str(request_ref.client_id.as_str()).map_err(|_| { Status::invalid_argument(std::format!("Invalid client id: {}", request_ref.client_id)) })?; - let client_state = self.context.client_state(&client_id).map_err(|_| { + let client_state = self.ibc_context.client_state(&client_id).map_err(|_| { Status::not_found(std::format!( "Client state not found for client {}", client_id @@ -86,7 +86,7 @@ where trace!("Got client states request: {:?}", request); let client_states = self - .context + .ibc_context .client_states() .map_err(|_| Status::not_found("Client states not found"))?; @@ -124,7 +124,7 @@ where })?; let consensus_state = self - .context + .ibc_context .consensus_state(&ClientConsensusStatePath::new(&client_id, &height)) .map_err(|_| { Status::not_found(std::format!( @@ -153,7 +153,7 @@ where Status::invalid_argument(std::format!("Invalid client id: {}", request_ref.client_id)) })?; - let consensus_states = self.context.consensus_states(&client_id).map_err(|_| { + let consensus_states = self.ibc_context.consensus_states(&client_id).map_err(|_| { Status::not_found(std::format!( "Consensus states not found for client {}", client_id @@ -184,15 +184,15 @@ where Status::invalid_argument(std::format!("Invalid client id: {}", request_ref.client_id)) })?; - let consensus_state_heights = - self.context - .consensus_state_heights(&client_id) - .map_err(|_| { - Status::not_found(std::format!( - "Consensus state heights not found for client {}", - client_id - )) - })?; + let consensus_state_heights = self + .ibc_context + .consensus_state_heights(&client_id) + .map_err(|_| { + Status::not_found(std::format!( + "Consensus state heights not found for client {}", + client_id + )) + })?; Ok(Response::new(QueryConsensusStateHeightsResponse { consensus_state_heights: consensus_state_heights @@ -215,7 +215,7 @@ where Status::invalid_argument(std::format!("Invalid client id: {}", request_ref.client_id)) })?; - let client_status = self.context.client_status(&client_id).map_err(|_| { + let client_status = self.ibc_context.client_status(&client_id).map_err(|_| { Status::not_found(std::format!( "Client status not found for client {}", client_id @@ -236,7 +236,7 @@ where Ok(Response::new(QueryClientParamsResponse { params: Some(ClientParams { allowed_clients: self - .context + .ibc_context .allowed_clients() .into_iter() .map(|x| x.as_str().into()) diff --git a/crates/ibc/src/services/connection.rs b/crates/ibc/src/services/connection.rs index fb7f61114..d1ae095bb 100644 --- a/crates/ibc/src/services/connection.rs +++ b/crates/ibc/src/services/connection.rs @@ -29,22 +29,22 @@ use std::boxed::Box; use tonic::{Request, Response, Status}; use tracing::trace; -pub struct ConnectionQueryServer { - pub context: T, +pub struct ConnectionQueryServer { + ibc_context: I, } -impl ConnectionQueryServer { - pub fn new(context: T) -> Self { - Self { context } +impl ConnectionQueryServer { + pub fn new(ibc_context: I) -> Self { + Self { ibc_context } } } #[tonic::async_trait] -impl ConnectionQuery for ConnectionQueryServer +impl ConnectionQuery for ConnectionQueryServer where - T: QueryContext + Send + Sync + 'static, - ::AnyClientState: Into, - ::AnyConsensusState: Into, + I: QueryContext + Send + Sync + 'static, + ::AnyClientState: Into, + ::AnyConsensusState: Into, { async fn connection( &self, @@ -60,12 +60,15 @@ where )) })?; - let connection_end = self.context.connection_end(&connection_id).map_err(|_| { - Status::not_found(std::format!( - "Connection end not found for connection {}", - connection_id - )) - })?; + let connection_end = self + .ibc_context + .connection_end(&connection_id) + .map_err(|_| { + Status::not_found(std::format!( + "Connection end not found for connection {}", + connection_id + )) + })?; Ok(Response::new(QueryConnectionResponse { connection: Some(connection_end.into()), @@ -81,7 +84,7 @@ where trace!("Got connections request: {:?}", request); let connections = self - .context + .ibc_context .connection_ends() .map_err(|_| Status::not_found("Connections not found"))?; @@ -89,7 +92,7 @@ where connections: connections.into_iter().map(Into::into).collect(), pagination: None, height: Some( - self.context + self.ibc_context .host_height() .map_err(|_| Status::not_found("Host chain height not found"))? .into(), @@ -110,7 +113,7 @@ where })?; let connections = self - .context + .ibc_context .client_connection_ends(&client_id) .map_err(|_| Status::not_found("Connections not found"))?; @@ -135,15 +138,18 @@ where )) })?; - let connection_end = self.context.connection_end(&connection_id).map_err(|_| { - Status::not_found(std::format!( - "Connection end not found for connection {}", - connection_id - )) - })?; + let connection_end = self + .ibc_context + .connection_end(&connection_id) + .map_err(|_| { + Status::not_found(std::format!( + "Connection end not found for connection {}", + connection_id + )) + })?; let client_state = self - .context + .ibc_context .client_state(connection_end.client_id()) .map_err(|_| { Status::not_found(std::format!( @@ -176,12 +182,15 @@ where )) })?; - let connection_end = self.context.connection_end(&connection_id).map_err(|_| { - Status::not_found(std::format!( - "Connection end not found for connection {}", - connection_id - )) - })?; + let connection_end = self + .ibc_context + .connection_end(&connection_id) + .map_err(|_| { + Status::not_found(std::format!( + "Connection end not found for connection {}", + connection_id + )) + })?; let consensus_path = ClientConsensusStatePath::new( connection_end.client_id(), @@ -196,12 +205,15 @@ where )?, ); - let consensus_state = self.context.consensus_state(&consensus_path).map_err(|_| { - Status::not_found(std::format!( - "Consensus state not found for connection {}", - connection_id - )) - })?; + let consensus_state = self + .ibc_context + .consensus_state(&consensus_path) + .map_err(|_| { + Status::not_found(std::format!( + "Consensus state not found for connection {}", + connection_id + )) + })?; Ok(Response::new(QueryConnectionConsensusStateResponse { consensus_state: Some(consensus_state.into()), @@ -219,7 +231,10 @@ where Ok(Response::new(QueryConnectionParamsResponse { params: Some(ConnectionParams { - max_expected_time_per_block: self.context.max_expected_time_per_block().as_secs(), + max_expected_time_per_block: self + .ibc_context + .max_expected_time_per_block() + .as_secs(), }), })) } From bf40f925da773575f5cb1afe950626ff4a4be246 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Mon, 28 Aug 2023 19:31:01 +0200 Subject: [PATCH 16/58] remove UpgradeValidationContext trait bound --- crates/ibc/src/core/context.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/ibc/src/core/context.rs b/crates/ibc/src/core/context.rs index aa6c1df56..de9e4d21f 100644 --- a/crates/ibc/src/core/context.rs +++ b/crates/ibc/src/core/context.rs @@ -255,11 +255,16 @@ pub trait ValidationContext { fn validate_message_signer(&self, signer: &Signer) -> Result<(), ContextError>; } +#[cfg(feature = "grpc")] +pub trait ProofContext { + fn get_proof(&self, height: Height, path: &Path) -> Result, ContextError>; +} + /// Context to be implemented by the host that provides gRPC query services. /// /// Trait used for the [`gRPC query services`](crate::services). #[cfg(feature = "grpc")] -pub trait QueryContext: UpgradeValidationContext + ValidationContext { +pub trait QueryContext: ValidationContext { // Client queries fn client_states( &self, From 67cd50b1c1a478609f1702f9fcb29501a64e7511 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Mon, 28 Aug 2023 19:57:17 +0200 Subject: [PATCH 17/58] cargo fmt and clippy --- crates/ibc/src/core/context.rs | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/crates/ibc/src/core/context.rs b/crates/ibc/src/core/context.rs index de9e4d21f..34b01129a 100644 --- a/crates/ibc/src/core/context.rs +++ b/crates/ibc/src/core/context.rs @@ -30,20 +30,15 @@ use crate::core::timestamp::Timestamp; use crate::Height; use super::ics02_client::client_state::ClientState; -use super::ics02_client::client_type::ClientType; use super::ics02_client::consensus_state::ConsensusState; use super::ics02_client::ClientExecutionContext; use super::ics24_host::identifier::PortId; -use super::ics24_host::path::Path; - #[cfg(feature = "grpc")] -use crate::{ - core::{ - ics02_client::client_state::Status, ics03_connection::connection::IdentifiedConnectionEnd, - ics04_channel::channel::IdentifiedChannelEnd, - }, - hosts::tendermint::upgrade_proposal::UpgradeValidationContext, +use crate::core::{ + ics02_client::{client_state::Status, client_type::ClientType}, + ics03_connection::connection::IdentifiedConnectionEnd, + ics04_channel::channel::IdentifiedChannelEnd, }; /// Top-level error @@ -255,11 +250,6 @@ pub trait ValidationContext { fn validate_message_signer(&self, signer: &Signer) -> Result<(), ContextError>; } -#[cfg(feature = "grpc")] -pub trait ProofContext { - fn get_proof(&self, height: Height, path: &Path) -> Result, ContextError>; -} - /// Context to be implemented by the host that provides gRPC query services. /// /// Trait used for the [`gRPC query services`](crate::services). From c2d047684f86047479913fe5f6d10634dcbc8994 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Tue, 29 Aug 2023 03:06:18 +0200 Subject: [PATCH 18/58] add ProvableContext --- crates/ibc/src/core/context.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crates/ibc/src/core/context.rs b/crates/ibc/src/core/context.rs index 34b01129a..fbc13c159 100644 --- a/crates/ibc/src/core/context.rs +++ b/crates/ibc/src/core/context.rs @@ -39,6 +39,7 @@ use crate::core::{ ics02_client::{client_state::Status, client_type::ClientType}, ics03_connection::connection::IdentifiedConnectionEnd, ics04_channel::channel::IdentifiedChannelEnd, + ics24_host::path::Path, }; /// Top-level error @@ -250,6 +251,12 @@ pub trait ValidationContext { fn validate_message_signer(&self, signer: &Signer) -> Result<(), ContextError>; } +#[cfg(feature = "grpc")] +pub trait ProvableContext { + fn get_proof(&self, height: Height, path: &Path) -> Option>; + fn current_height(&self) -> Result; +} + /// Context to be implemented by the host that provides gRPC query services. /// /// Trait used for the [`gRPC query services`](crate::services). From 89316ea8b1c2dab7d0f3e5ddb363454a1fc17552 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Tue, 29 Aug 2023 03:07:32 +0200 Subject: [PATCH 19/58] add proofs to client service --- crates/ibc/src/services/client.rs | 52 ++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/crates/ibc/src/services/client.rs b/crates/ibc/src/services/client.rs index 3a7da5fdb..b0aec575c 100644 --- a/crates/ibc/src/services/client.rs +++ b/crates/ibc/src/services/client.rs @@ -17,9 +17,9 @@ use crate::{ core::{ ics24_host::{ identifier::ClientId, - path::{ClientConsensusStatePath, UpgradeClientPath}, + path::{ClientConsensusStatePath, ClientStatePath, Path, UpgradeClientPath}, }, - QueryContext, ValidationContext, + ProvableContext, QueryContext, ValidationContext, }, hosts::tendermint::upgrade_proposal::UpgradeValidationContext, Height, @@ -47,7 +47,7 @@ impl ClientQueryServer { #[tonic::async_trait] impl ClientQuery for ClientQueryServer where - I: QueryContext + Send + Sync + 'static, + I: QueryContext + ProvableContext + Send + Sync + 'static, U: UpgradeValidationContext + Send + Sync + 'static, ::AnyClientState: Into, ::AnyConsensusState: Into, @@ -72,10 +72,29 @@ where )) })?; + let current_height = self + .ibc_context + .current_height() + .map_err(|_| Status::not_found("Current height not found"))?; + + let proof = self + .ibc_context + .get_proof( + current_height, + &Path::ClientState(ClientStatePath::new(&client_id)), + ) + .ok_or_else(|| { + Status::not_found(std::format!( + "Client state not found for client {} at height {}", + client_id, + current_height + )) + })?; + Ok(Response::new(QueryClientStateResponse { client_state: Some(client_state.into()), - proof: Default::default(), - proof_height: None, + proof, + proof_height: Some(current_height.into()), })) } @@ -134,10 +153,29 @@ where )) })?; + let current_height = self + .ibc_context + .current_height() + .map_err(|_| Status::not_found("Current height not found"))?; + + let proof = self + .ibc_context + .get_proof( + current_height, + &Path::ClientConsensusState(ClientConsensusStatePath::new(&client_id, &height)), + ) + .ok_or_else(|| { + Status::not_found(std::format!( + "Consensus state not found for client {} at height {}", + client_id, + height + )) + })?; + Ok(Response::new(QueryConsensusStateResponse { consensus_state: Some(consensus_state.into()), - proof: Default::default(), - proof_height: None, + proof, + proof_height: Some(current_height.into()), })) } From 0ae557ca0afebad3db1b0d6fd6d7141911e5a625 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Tue, 29 Aug 2023 03:07:54 +0200 Subject: [PATCH 20/58] add proofs to connection service --- crates/ibc/src/services/connection.rs | 98 +++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 13 deletions(-) diff --git a/crates/ibc/src/services/connection.rs b/crates/ibc/src/services/connection.rs index d1ae095bb..8cd11f9b1 100644 --- a/crates/ibc/src/services/connection.rs +++ b/crates/ibc/src/services/connection.rs @@ -17,9 +17,12 @@ use crate::{ core::{ ics24_host::{ identifier::{ClientId, ConnectionId}, - path::ClientConsensusStatePath, + path::{ + ClientConnectionPath, ClientConsensusStatePath, ClientStatePath, ConnectionPath, + Path, + }, }, - QueryContext, ValidationContext, + ProvableContext, QueryContext, ValidationContext, }, Height, }; @@ -42,7 +45,7 @@ impl ConnectionQueryServer { #[tonic::async_trait] impl ConnectionQuery for ConnectionQueryServer where - I: QueryContext + Send + Sync + 'static, + I: QueryContext + ProvableContext + Send + Sync + 'static, ::AnyClientState: Into, ::AnyConsensusState: Into, { @@ -70,10 +73,28 @@ where )) })?; + let current_height = self + .ibc_context + .current_height() + .map_err(|_| Status::not_found("Current height not found"))?; + + let proof = self + .ibc_context + .get_proof( + current_height, + &Path::Connection(ConnectionPath::new(&connection_id)), + ) + .ok_or_else(|| { + Status::not_found(std::format!( + "Proof not found for connection path {}", + connection_id.as_str() + )) + })?; + Ok(Response::new(QueryConnectionResponse { connection: Some(connection_end.into()), - proof: Default::default(), - proof_height: None, + proof, + proof_height: Some(current_height.into()), })) } @@ -93,8 +114,8 @@ where pagination: None, height: Some( self.ibc_context - .host_height() - .map_err(|_| Status::not_found("Host chain height not found"))? + .current_height() + .map_err(|_| Status::not_found("Current height not found"))? .into(), ), })) @@ -117,10 +138,28 @@ where .client_connection_ends(&client_id) .map_err(|_| Status::not_found("Connections not found"))?; + let current_height = self + .ibc_context + .current_height() + .map_err(|_| Status::not_found("Current height not found"))?; + + let proof: alloc::vec::Vec = self + .ibc_context + .get_proof( + current_height, + &Path::ClientConnection(ClientConnectionPath::new(&client_id)), + ) + .ok_or_else(|| { + Status::not_found(std::format!( + "Proof not found for client connection path {}", + client_id.as_str() + )) + })?; + Ok(Response::new(QueryClientConnectionsResponse { connection_paths: connections.into_iter().map(|x| x.as_str().into()).collect(), - proof: Default::default(), - proof_height: None, + proof, + proof_height: Some(current_height.into()), })) } @@ -158,13 +197,31 @@ where )) })?; + let current_height = self + .ibc_context + .current_height() + .map_err(|_| Status::not_found("Current height not found"))?; + + let proof = self + .ibc_context + .get_proof( + current_height, + &Path::ClientState(ClientStatePath::new(connection_end.client_id())), + ) + .ok_or_else(|| { + Status::not_found(std::format!( + "Proof not found for client state path {}", + connection_end.client_id().as_str() + )) + })?; + Ok(Response::new(QueryConnectionClientStateResponse { identified_client_state: Some(IdentifiedClientState { client_id: connection_end.client_id().as_str().into(), client_state: Some(client_state.into()), }), - proof: Default::default(), - proof_height: None, + proof, + proof_height: Some(current_height.into()), })) } @@ -215,11 +272,26 @@ where )) })?; + let current_height = self + .ibc_context + .current_height() + .map_err(|_| Status::not_found("Current height not found"))?; + + let proof = self + .ibc_context + .get_proof(current_height, &Path::ClientConsensusState(consensus_path)) + .ok_or_else(|| { + Status::not_found(std::format!( + "Proof not found for consensus state path {}", + connection_end.client_id().as_str() + )) + })?; + Ok(Response::new(QueryConnectionConsensusStateResponse { consensus_state: Some(consensus_state.into()), client_id: connection_end.client_id().as_str().into(), - proof: Default::default(), - proof_height: None, + proof, + proof_height: Some(current_height.into()), })) } From bbb1a64f622bfab192006ae199bdbd9494fe7b79 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Tue, 29 Aug 2023 03:08:22 +0200 Subject: [PATCH 21/58] add proofs to channel service --- crates/ibc/src/services/channel.rs | 228 +++++++++++++++++++++++++---- 1 file changed, 196 insertions(+), 32 deletions(-) diff --git a/crates/ibc/src/services/channel.rs b/crates/ibc/src/services/channel.rs index a540c79d9..7146bf519 100644 --- a/crates/ibc/src/services/channel.rs +++ b/crates/ibc/src/services/channel.rs @@ -26,11 +26,11 @@ use crate::{ ics24_host::{ identifier::{ChannelId, ConnectionId, PortId}, path::{ - AckPath, ChannelEndPath, ClientConsensusStatePath, CommitmentPath, ReceiptPath, - SeqRecvPath, SeqSendPath, + AckPath, ChannelEndPath, ClientConsensusStatePath, ClientStatePath, CommitmentPath, + Path, ReceiptPath, SeqRecvPath, SeqSendPath, }, }, - QueryContext, ValidationContext, + ProvableContext, QueryContext, ValidationContext, }, Height, }; @@ -53,7 +53,7 @@ impl ChannelQueryServer { #[tonic::async_trait] impl ChannelQuery for ChannelQueryServer where - I: QueryContext + Send + Sync + 'static, + I: QueryContext + ProvableContext + Send + Sync + 'static, ::AnyClientState: Into, ::AnyConsensusState: Into, { @@ -87,10 +87,27 @@ where )) })?; + let current_height = self.ibc_context.current_height().map_err(|_| { + Status::not_found(std::format!( + "Current height not found for channel {}", + channel_id + )) + })?; + + let proof = self + .ibc_context + .get_proof(current_height, &Path::ChannelEnd(channel_end_path)) + .ok_or_else(|| { + Status::not_found(std::format!( + "Channel end proof not found for channel {}", + channel_id + )) + })?; + Ok(Response::new(QueryChannelResponse { channel: Some(channel_end.into()), - proof: Default::default(), - proof_height: None, + proof, + proof_height: Some(current_height.into()), })) } /// Channels queries all the IBC channels of a chain. @@ -110,8 +127,8 @@ where pagination: None, height: Some( self.ibc_context - .host_height() - .map_err(|_| Status::not_found("Host chain height not found"))? + .current_height() + .map_err(|_| Status::not_found("Current height not found"))? .into(), ), })) @@ -149,8 +166,13 @@ where pagination: None, height: Some( self.ibc_context - .host_height() - .map_err(|_| Status::not_found("Host chain height not found"))? + .current_height() + .map_err(|_| { + Status::not_found(std::format!( + "Current height not found for connection {}", + connection_id + )) + })? .into(), ), })) @@ -216,13 +238,33 @@ where )) })?; + let current_height = self.ibc_context.current_height().map_err(|_| { + Status::not_found(std::format!( + "Current height not found for client {}", + connection_end.client_id() + )) + })?; + + let proof = self + .ibc_context + .get_proof( + current_height, + &Path::ClientState(ClientStatePath::new(connection_end.client_id())), + ) + .ok_or_else(|| { + Status::not_found(std::format!( + "Client state proof not found for client {}", + connection_end.client_id() + )) + })?; + Ok(Response::new(QueryChannelClientStateResponse { identified_client_state: Some(IdentifiedClientState { client_id: connection_end.client_id().as_str().into(), client_state: Some(client_state.into()), }), - proof: Default::default(), - proof_height: None, + proof, + proof_height: Some(current_height.into()), })) } /// ChannelConsensusState queries for the consensus state for the channel @@ -300,11 +342,28 @@ where )) })?; + let current_height = self.ibc_context.current_height().map_err(|_| { + Status::not_found(std::format!( + "Current height not found for client {}", + connection_end.client_id() + )) + })?; + + let proof = self + .ibc_context + .get_proof(current_height, &Path::ClientConsensusState(consensus_path)) + .ok_or_else(|| { + Status::not_found(std::format!( + "Consensus state proof not found for client {}", + connection_end.client_id() + )) + })?; + Ok(Response::new(QueryChannelConsensusStateResponse { client_id: connection_end.client_id().as_str().into(), consensus_state: Some(consensus_state.into()), - proof: Default::default(), - proof_height: None, + proof, + proof_height: Some(current_height.into()), })) } /// PacketCommitment queries a stored packet commitment hash. @@ -342,10 +401,27 @@ where )) })?; + let current_height = self.ibc_context.current_height().map_err(|_| { + Status::not_found(std::format!( + "Current height not found for channel {}", + channel_id + )) + })?; + + let proof = self + .ibc_context + .get_proof(current_height, &Path::Commitment(commitment_path)) + .ok_or_else(|| { + Status::not_found(std::format!( + "Packet commitment proof not found for channel {}", + channel_id + )) + })?; + Ok(Response::new(QueryPacketCommitmentResponse { commitment: packet_commitment_data.into_vec(), - proof: Default::default(), - proof_height: None, + proof, + proof_height: Some(current_height.into()), })) } @@ -406,8 +482,13 @@ where pagination: None, height: Some( self.ibc_context - .host_height() - .map_err(|_| Status::not_found("Host chain height not found"))? + .current_height() + .map_err(|_| { + Status::not_found(std::format!( + "Current height not found for channel {}", + channel_id + )) + })? .into(), ), })) @@ -440,10 +521,27 @@ where // Unreceived packets are not stored let packet_receipt_data = self.ibc_context.get_packet_receipt(&receipt_path); + let current_height = self.ibc_context.current_height().map_err(|_| { + Status::not_found(std::format!( + "Current height not found for channel {}", + channel_id + )) + })?; + + let proof = self + .ibc_context + .get_proof(current_height, &Path::Receipt(receipt_path)) + .ok_or_else(|| { + Status::not_found(std::format!( + "Packet receipt proof not found for channel {}", + channel_id + )) + })?; + Ok(Response::new(QueryPacketReceiptResponse { received: packet_receipt_data.is_ok(), - proof: Default::default(), - proof_height: None, + proof, + proof_height: Some(current_height.into()), })) } @@ -480,10 +578,27 @@ where )) })?; + let current_height = self.ibc_context.current_height().map_err(|_| { + Status::not_found(std::format!( + "Current height not found for channel {}", + channel_id + )) + })?; + + let proof = self + .ibc_context + .get_proof(current_height, &Path::Ack(acknowledgement_path)) + .ok_or_else(|| { + Status::not_found(std::format!( + "Packet acknowledgement proof not found for channel {}", + channel_id + )) + })?; + Ok(Response::new(QueryPacketAcknowledgementResponse { acknowledgement: packet_acknowledgement_data.into_vec(), - proof: Default::default(), - proof_height: None, + proof, + proof_height: Some(current_height.into()), })) } @@ -548,8 +663,13 @@ where pagination: None, height: Some( self.ibc_context - .host_height() - .map_err(|_| Status::not_found("Host chain height not found"))? + .current_height() + .map_err(|_| { + Status::not_found(std::format!( + "Current height not found for channel {}", + channel_id + )) + })? .into(), ), })) @@ -600,8 +720,13 @@ where sequences: unreceived_packets.into_iter().map(Into::into).collect(), height: Some( self.ibc_context - .host_height() - .map_err(|_| Status::not_found("Host chain height not found"))? + .current_height() + .map_err(|_| { + Status::not_found(std::format!( + "Current height not found for channel {}", + channel_id + )) + })? .into(), ), })) @@ -648,8 +773,13 @@ where sequences: unreceived_acks.into_iter().map(Into::into).collect(), height: Some( self.ibc_context - .host_height() - .map_err(|_| Status::not_found("Host chain height not found"))? + .current_height() + .map_err(|_| { + Status::not_found(std::format!( + "Current height not found for channel {}", + channel_id + )) + })? .into(), ), })) @@ -685,10 +815,27 @@ where )) })?; + let current_height = self.ibc_context.current_height().map_err(|_| { + Status::not_found(std::format!( + "Current height not found for channel {}", + channel_id + )) + })?; + + let proof = self + .ibc_context + .get_proof(current_height, &Path::SeqRecv(next_seq_recv_path)) + .ok_or_else(|| { + Status::not_found(std::format!( + "Next sequence receive proof not found for channel {}", + channel_id + )) + })?; + Ok(Response::new(QueryNextSequenceReceiveResponse { next_sequence_receive: next_sequence_recv.into(), - proof: Default::default(), - proof_height: None, + proof, + proof_height: Some(current_height.into()), })) } @@ -722,10 +869,27 @@ where )) })?; + let current_height = self.ibc_context.current_height().map_err(|_| { + Status::not_found(std::format!( + "Current height not found for channel {}", + channel_id + )) + })?; + + let proof = self + .ibc_context + .get_proof(current_height, &Path::SeqSend(next_seq_send_path)) + .ok_or_else(|| { + Status::not_found(std::format!( + "Next sequence send proof not found for channel {}", + channel_id + )) + })?; + Ok(Response::new(QueryNextSequenceSendResponse { next_sequence_send: next_sequence_send.into(), - proof: Default::default(), - proof_height: None, + proof, + proof_height: Some(current_height.into()), })) } } From c7c6594ae68fa413c7dfdbc64b1c710e9c029371 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Tue, 29 Aug 2023 03:18:06 +0200 Subject: [PATCH 22/58] remove redundant trait method --- crates/ibc/src/core/context.rs | 1 - crates/ibc/src/services/channel.rs | 28 +++++++++++++-------------- crates/ibc/src/services/client.rs | 4 ++-- crates/ibc/src/services/connection.rs | 10 +++++----- 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/crates/ibc/src/core/context.rs b/crates/ibc/src/core/context.rs index fbc13c159..c963f7ae2 100644 --- a/crates/ibc/src/core/context.rs +++ b/crates/ibc/src/core/context.rs @@ -254,7 +254,6 @@ pub trait ValidationContext { #[cfg(feature = "grpc")] pub trait ProvableContext { fn get_proof(&self, height: Height, path: &Path) -> Option>; - fn current_height(&self) -> Result; } /// Context to be implemented by the host that provides gRPC query services. diff --git a/crates/ibc/src/services/channel.rs b/crates/ibc/src/services/channel.rs index 7146bf519..2836c4e23 100644 --- a/crates/ibc/src/services/channel.rs +++ b/crates/ibc/src/services/channel.rs @@ -87,7 +87,7 @@ where )) })?; - let current_height = self.ibc_context.current_height().map_err(|_| { + let current_height = self.ibc_context.host_height().map_err(|_| { Status::not_found(std::format!( "Current height not found for channel {}", channel_id @@ -127,7 +127,7 @@ where pagination: None, height: Some( self.ibc_context - .current_height() + .host_height() .map_err(|_| Status::not_found("Current height not found"))? .into(), ), @@ -166,7 +166,7 @@ where pagination: None, height: Some( self.ibc_context - .current_height() + .host_height() .map_err(|_| { Status::not_found(std::format!( "Current height not found for connection {}", @@ -238,7 +238,7 @@ where )) })?; - let current_height = self.ibc_context.current_height().map_err(|_| { + let current_height = self.ibc_context.host_height().map_err(|_| { Status::not_found(std::format!( "Current height not found for client {}", connection_end.client_id() @@ -342,7 +342,7 @@ where )) })?; - let current_height = self.ibc_context.current_height().map_err(|_| { + let current_height = self.ibc_context.host_height().map_err(|_| { Status::not_found(std::format!( "Current height not found for client {}", connection_end.client_id() @@ -401,7 +401,7 @@ where )) })?; - let current_height = self.ibc_context.current_height().map_err(|_| { + let current_height = self.ibc_context.host_height().map_err(|_| { Status::not_found(std::format!( "Current height not found for channel {}", channel_id @@ -482,7 +482,7 @@ where pagination: None, height: Some( self.ibc_context - .current_height() + .host_height() .map_err(|_| { Status::not_found(std::format!( "Current height not found for channel {}", @@ -521,7 +521,7 @@ where // Unreceived packets are not stored let packet_receipt_data = self.ibc_context.get_packet_receipt(&receipt_path); - let current_height = self.ibc_context.current_height().map_err(|_| { + let current_height = self.ibc_context.host_height().map_err(|_| { Status::not_found(std::format!( "Current height not found for channel {}", channel_id @@ -578,7 +578,7 @@ where )) })?; - let current_height = self.ibc_context.current_height().map_err(|_| { + let current_height = self.ibc_context.host_height().map_err(|_| { Status::not_found(std::format!( "Current height not found for channel {}", channel_id @@ -663,7 +663,7 @@ where pagination: None, height: Some( self.ibc_context - .current_height() + .host_height() .map_err(|_| { Status::not_found(std::format!( "Current height not found for channel {}", @@ -720,7 +720,7 @@ where sequences: unreceived_packets.into_iter().map(Into::into).collect(), height: Some( self.ibc_context - .current_height() + .host_height() .map_err(|_| { Status::not_found(std::format!( "Current height not found for channel {}", @@ -773,7 +773,7 @@ where sequences: unreceived_acks.into_iter().map(Into::into).collect(), height: Some( self.ibc_context - .current_height() + .host_height() .map_err(|_| { Status::not_found(std::format!( "Current height not found for channel {}", @@ -815,7 +815,7 @@ where )) })?; - let current_height = self.ibc_context.current_height().map_err(|_| { + let current_height = self.ibc_context.host_height().map_err(|_| { Status::not_found(std::format!( "Current height not found for channel {}", channel_id @@ -869,7 +869,7 @@ where )) })?; - let current_height = self.ibc_context.current_height().map_err(|_| { + let current_height = self.ibc_context.host_height().map_err(|_| { Status::not_found(std::format!( "Current height not found for channel {}", channel_id diff --git a/crates/ibc/src/services/client.rs b/crates/ibc/src/services/client.rs index b0aec575c..aa8abc974 100644 --- a/crates/ibc/src/services/client.rs +++ b/crates/ibc/src/services/client.rs @@ -74,7 +74,7 @@ where let current_height = self .ibc_context - .current_height() + .host_height() .map_err(|_| Status::not_found("Current height not found"))?; let proof = self @@ -155,7 +155,7 @@ where let current_height = self .ibc_context - .current_height() + .host_height() .map_err(|_| Status::not_found("Current height not found"))?; let proof = self diff --git a/crates/ibc/src/services/connection.rs b/crates/ibc/src/services/connection.rs index 8cd11f9b1..122f38ce1 100644 --- a/crates/ibc/src/services/connection.rs +++ b/crates/ibc/src/services/connection.rs @@ -75,7 +75,7 @@ where let current_height = self .ibc_context - .current_height() + .host_height() .map_err(|_| Status::not_found("Current height not found"))?; let proof = self @@ -114,7 +114,7 @@ where pagination: None, height: Some( self.ibc_context - .current_height() + .host_height() .map_err(|_| Status::not_found("Current height not found"))? .into(), ), @@ -140,7 +140,7 @@ where let current_height = self .ibc_context - .current_height() + .host_height() .map_err(|_| Status::not_found("Current height not found"))?; let proof: alloc::vec::Vec = self @@ -199,7 +199,7 @@ where let current_height = self .ibc_context - .current_height() + .host_height() .map_err(|_| Status::not_found("Current height not found"))?; let proof = self @@ -274,7 +274,7 @@ where let current_height = self .ibc_context - .current_height() + .host_height() .map_err(|_| Status::not_found("Current height not found"))?; let proof = self From ca23b3830ec98263ac635bbc6cf6a187df7616b1 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Tue, 29 Aug 2023 14:46:47 +0200 Subject: [PATCH 23/58] refactor ProvableContext trait bounds --- crates/ibc/src/core/context.rs | 7 +++++-- crates/ibc/src/services/channel.rs | 4 ++-- crates/ibc/src/services/client.rs | 4 ++-- crates/ibc/src/services/connection.rs | 4 ++-- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/crates/ibc/src/core/context.rs b/crates/ibc/src/core/context.rs index c963f7ae2..20a6d8d59 100644 --- a/crates/ibc/src/core/context.rs +++ b/crates/ibc/src/core/context.rs @@ -102,7 +102,7 @@ impl std::error::Error for RouterError { /// Context to be implemented by the host that provides all "read-only" methods. /// -/// Trait used for the top-level [`validate`](crate::core::validate) +/// Trait used for the top-level [`validate`](crate::core::validate) and the [`gRPC query services`](crate::services). pub trait ValidationContext { type ClientValidationContext; type E: ClientExecutionContext; @@ -251,6 +251,9 @@ pub trait ValidationContext { fn validate_message_signer(&self, signer: &Signer) -> Result<(), ContextError>; } +/// Context to be implemented by the host to provide proofs in gRPC query responses +/// +/// Trait used for the [`gRPC query services`](crate::services). #[cfg(feature = "grpc")] pub trait ProvableContext { fn get_proof(&self, height: Height, path: &Path) -> Option>; @@ -260,7 +263,7 @@ pub trait ProvableContext { /// /// Trait used for the [`gRPC query services`](crate::services). #[cfg(feature = "grpc")] -pub trait QueryContext: ValidationContext { +pub trait QueryContext: ProvableContext + ValidationContext { // Client queries fn client_states( &self, diff --git a/crates/ibc/src/services/channel.rs b/crates/ibc/src/services/channel.rs index 2836c4e23..6ec466805 100644 --- a/crates/ibc/src/services/channel.rs +++ b/crates/ibc/src/services/channel.rs @@ -30,7 +30,7 @@ use crate::{ Path, ReceiptPath, SeqRecvPath, SeqSendPath, }, }, - ProvableContext, QueryContext, ValidationContext, + QueryContext, ValidationContext, }, Height, }; @@ -53,7 +53,7 @@ impl ChannelQueryServer { #[tonic::async_trait] impl ChannelQuery for ChannelQueryServer where - I: QueryContext + ProvableContext + Send + Sync + 'static, + I: QueryContext + Send + Sync + 'static, ::AnyClientState: Into, ::AnyConsensusState: Into, { diff --git a/crates/ibc/src/services/client.rs b/crates/ibc/src/services/client.rs index aa8abc974..54692ffad 100644 --- a/crates/ibc/src/services/client.rs +++ b/crates/ibc/src/services/client.rs @@ -19,7 +19,7 @@ use crate::{ identifier::ClientId, path::{ClientConsensusStatePath, ClientStatePath, Path, UpgradeClientPath}, }, - ProvableContext, QueryContext, ValidationContext, + QueryContext, ValidationContext, }, hosts::tendermint::upgrade_proposal::UpgradeValidationContext, Height, @@ -47,7 +47,7 @@ impl ClientQueryServer { #[tonic::async_trait] impl ClientQuery for ClientQueryServer where - I: QueryContext + ProvableContext + Send + Sync + 'static, + I: QueryContext + Send + Sync + 'static, U: UpgradeValidationContext + Send + Sync + 'static, ::AnyClientState: Into, ::AnyConsensusState: Into, diff --git a/crates/ibc/src/services/connection.rs b/crates/ibc/src/services/connection.rs index 122f38ce1..732bbd522 100644 --- a/crates/ibc/src/services/connection.rs +++ b/crates/ibc/src/services/connection.rs @@ -22,7 +22,7 @@ use crate::{ Path, }, }, - ProvableContext, QueryContext, ValidationContext, + QueryContext, ValidationContext, }, Height, }; @@ -45,7 +45,7 @@ impl ConnectionQueryServer { #[tonic::async_trait] impl ConnectionQuery for ConnectionQueryServer where - I: QueryContext + ProvableContext + Send + Sync + 'static, + I: QueryContext + Send + Sync + 'static, ::AnyClientState: Into, ::AnyConsensusState: Into, { From de6d10e70ac36b2a37a8f310e6054284f4d8506f Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Tue, 29 Aug 2023 14:47:24 +0200 Subject: [PATCH 24/58] refactor service structs --- crates/ibc/src/services/channel.rs | 16 +++++++++++++--- crates/ibc/src/services/client.rs | 22 +++++++++++++++++++--- crates/ibc/src/services/connection.rs | 16 +++++++++++++--- 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/crates/ibc/src/services/channel.rs b/crates/ibc/src/services/channel.rs index 6ec466805..0ab20cd3d 100644 --- a/crates/ibc/src/services/channel.rs +++ b/crates/ibc/src/services/channel.rs @@ -40,18 +40,28 @@ use std::boxed::Box; use tonic::{Request, Response, Status}; use tracing::trace; -pub struct ChannelQueryServer { +pub struct ChannelQueryService +where + I: QueryContext + Send + Sync + 'static, + ::AnyClientState: Into, + ::AnyConsensusState: Into, +{ ibc_context: I, } -impl ChannelQueryServer { +impl ChannelQueryService +where + I: QueryContext + Send + Sync + 'static, + ::AnyClientState: Into, + ::AnyConsensusState: Into, +{ pub fn new(ibc_context: I) -> Self { Self { ibc_context } } } #[tonic::async_trait] -impl ChannelQuery for ChannelQueryServer +impl ChannelQuery for ChannelQueryService where I: QueryContext + Send + Sync + 'static, ::AnyClientState: Into, diff --git a/crates/ibc/src/services/client.rs b/crates/ibc/src/services/client.rs index 54692ffad..da54564a5 100644 --- a/crates/ibc/src/services/client.rs +++ b/crates/ibc/src/services/client.rs @@ -30,12 +30,28 @@ use std::boxed::Box; use tonic::{Request, Response, Status}; use tracing::trace; -pub struct ClientQueryServer { +pub struct ClientQueryService +where + I: QueryContext + Send + Sync + 'static, + U: UpgradeValidationContext + Send + Sync + 'static, + ::AnyClientState: Into, + ::AnyConsensusState: Into, + ::AnyClientState: Into, + ::AnyConsensusState: Into, +{ ibc_context: I, upgrade_context: U, } -impl ClientQueryServer { +impl ClientQueryService +where + I: QueryContext + Send + Sync + 'static, + U: UpgradeValidationContext + Send + Sync + 'static, + ::AnyClientState: Into, + ::AnyConsensusState: Into, + ::AnyClientState: Into, + ::AnyConsensusState: Into, +{ pub fn new(ibc_context: I, upgrade_context: U) -> Self { Self { ibc_context, @@ -45,7 +61,7 @@ impl ClientQueryServer { } #[tonic::async_trait] -impl ClientQuery for ClientQueryServer +impl ClientQuery for ClientQueryService where I: QueryContext + Send + Sync + 'static, U: UpgradeValidationContext + Send + Sync + 'static, diff --git a/crates/ibc/src/services/connection.rs b/crates/ibc/src/services/connection.rs index 732bbd522..a9c9dec98 100644 --- a/crates/ibc/src/services/connection.rs +++ b/crates/ibc/src/services/connection.rs @@ -32,18 +32,28 @@ use std::boxed::Box; use tonic::{Request, Response, Status}; use tracing::trace; -pub struct ConnectionQueryServer { +pub struct ConnectionQueryService +where + I: QueryContext + Send + Sync + 'static, + ::AnyClientState: Into, + ::AnyConsensusState: Into, +{ ibc_context: I, } -impl ConnectionQueryServer { +impl ConnectionQueryService +where + I: QueryContext + Send + Sync + 'static, + ::AnyClientState: Into, + ::AnyConsensusState: Into, +{ pub fn new(ibc_context: I) -> Self { Self { ibc_context } } } #[tonic::async_trait] -impl ConnectionQuery for ConnectionQueryServer +impl ConnectionQuery for ConnectionQueryService where I: QueryContext + Send + Sync + 'static, ::AnyClientState: Into, From 981b15444bac6c718e257936cd3f3f8f79f523d3 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Tue, 29 Aug 2023 14:47:48 +0200 Subject: [PATCH 25/58] add service doc --- crates/ibc/src/services/mod.rs | 53 ++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/crates/ibc/src/services/mod.rs b/crates/ibc/src/services/mod.rs index 210a35c8a..52fbcf7da 100644 --- a/crates/ibc/src/services/mod.rs +++ b/crates/ibc/src/services/mod.rs @@ -1,3 +1,50 @@ -pub mod channel; -pub mod client; -pub mod connection; +//! Implementation of the gRPC services of core IBC components. +//! +//! The provided structs includes blanket implementation of their corresponding gRPC service traits, +//! if the host implements the following _context_ traits. +//! - [`ValidationContext`](crate::core::ValidationContext) +//! - [`ProvableContext`](crate::core::ProvableContext) +//! - [`QueryContext`](crate::core::QueryContext) +//! - [`UpgradeValidationContext`](crate::hosts::tendermint::upgrade_proposal::UpgradeValidationContext) +//! - Only for [`ClientQuery::upgraded_client_state`](ibc_proto::ibc::core::client::v1::query_server::Query::upgraded_client_state) and [`ClientQuery::upgraded_client_state`](ibc_proto::ibc::core::client::v1::query_server::Query::upgraded_consensus_state) +//! +//! Example +//! ```rust,ignore +//! use ibc_proto::ibc::core::{ +//! channel::v1::query_server::QueryServer as ChannelQueryServer +//! client::v1::query_server::QueryServer as ClientQueryServer, +//! connection::v1::query_server::QueryServer as ConnectionQueryServer, +//! } +//! use ibc::core::{ProvableContext, QueryContext, ValidationContext}; +//! use ibc::hosts::tendermint::upgrade_proposal::UpgradeValidationContext; +//! use ibc::services::{ChannelQueryService, ClientQueryService, ConnectionQueryService}; +//! +//! struct Ibc; +//! impl ValidationContext for Ibc { } +//! impl ProvableContext for Ibc { } +//! impl QueryContext for Ibc { } +//! +//! struct Upgrade; +//! impl UpgradeValidationContext for Upgrade { } +//! +//! let ibc = Ibc::new(); +//! let upgrade = Upgrade::new(); +//! +//! let client_service = ClientQueryServer::new(ClientQueryService::new(ibc, upgrade)) +//! let connection_service = ConnectionQueryServer::new(ConnectionQueryService::new(ibc)) +//! let channel_service = ChannelQueryServer::new(ChannelQueryService::new(ibc)) +//! +//! let grpc_server = tonic::transport::Server::builder() +//! .add_service(client_service) +//! .add_service(connection_service) +//! .add_service(channel_service) +//! .serve(addr); +//! ``` + +mod channel; +mod client; +mod connection; + +pub use channel::ChannelQueryService; +pub use client::ClientQueryService; +pub use connection::ConnectionQueryService; From e2898d9a44bf9b51b150674fe239b41ad881e9be Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Tue, 29 Aug 2023 15:07:57 +0200 Subject: [PATCH 26/58] add context docs --- crates/ibc/src/core/context.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/crates/ibc/src/core/context.rs b/crates/ibc/src/core/context.rs index 20a6d8d59..a6b4bf721 100644 --- a/crates/ibc/src/core/context.rs +++ b/crates/ibc/src/core/context.rs @@ -256,6 +256,8 @@ pub trait ValidationContext { /// Trait used for the [`gRPC query services`](crate::services). #[cfg(feature = "grpc")] pub trait ProvableContext { + /// Returns a proof for the given path at the given height. + /// As this is in the context of IBC, the path is expected to be an [`IbcPath`](Path). fn get_proof(&self, height: Height, path: &Path) -> Option>; } @@ -265,46 +267,70 @@ pub trait ProvableContext { #[cfg(feature = "grpc")] pub trait QueryContext: ProvableContext + ValidationContext { // Client queries + + /// Returns the list of all clients. fn client_states( &self, ) -> Result::AnyClientState)>, ContextError>; + + /// Returns the list of all consensus states for the given client. fn consensus_states( &self, client_id: &ClientId, ) -> Result::AnyConsensusState)>, ContextError>; + + /// Returns the list of all heights at which consensus states for the given client are. fn consensus_state_heights(&self, client_id: &ClientId) -> Result, ContextError>; + + /// Returns the status of the given client. fn client_status(&self, client_id: &ClientId) -> Result; fn allowed_clients(&self) -> Vec; // Connection queries + + /// Returns the list of all connection ends. fn connection_ends(&self) -> Result, ContextError>; + + /// Returns the list of all connection ids of the given client. fn client_connection_ends( &self, client_id: &ClientId, ) -> Result, ContextError>; // Channel queries + + /// Returns the list of all channel ends. fn channel_ends(&self) -> Result, ContextError>; + + /// Returns the list of all channel ends of the given connection. fn connection_channel_ends( &self, connection_id: &ConnectionId, ) -> Result, ContextError>; // Packet queries + + /// Returns the list of all packet commitments for the given channel end. fn packet_commitments( &self, channel_end_path: &ChannelEndPath, ) -> Result, ContextError>; + + /// Filters the list of packet sequencees for the given channel end that are acknowledged. fn packet_acknowledgements( &self, channel_end_path: &ChannelEndPath, sequences: impl IntoIterator, ) -> Result, ContextError>; + + /// Filters the list of packet sequencees for the given channel end that are not received. fn unreceived_packets( &self, channel_end_path: &ChannelEndPath, sequences: impl IntoIterator, ) -> Result, ContextError>; + + /// Filters the list of packet sequencees for the given channel end whose acknowledgement is not received. fn unreceived_acks( &self, channel_end_path: &ChannelEndPath, From 09485a120fe3609442f780623ec6495cb4933879 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Wed, 30 Aug 2023 13:41:28 +0200 Subject: [PATCH 27/58] from impl for tonic status --- crates/ibc/src/services/error.rs | 16 ++++++++++++++++ crates/ibc/src/services/mod.rs | 1 + 2 files changed, 17 insertions(+) create mode 100644 crates/ibc/src/services/error.rs diff --git a/crates/ibc/src/services/error.rs b/crates/ibc/src/services/error.rs new file mode 100644 index 000000000..f458dc288 --- /dev/null +++ b/crates/ibc/src/services/error.rs @@ -0,0 +1,16 @@ +use alloc::string::ToString; + +use crate::core::{ics24_host::identifier::IdentifierError, ContextError}; +use tonic::Status; + +impl From for Status { + fn from(err: IdentifierError) -> Self { + Status::invalid_argument(err.to_string()) + } +} + +impl From for Status { + fn from(err: ContextError) -> Self { + Status::not_found(err.to_string()) + } +} diff --git a/crates/ibc/src/services/mod.rs b/crates/ibc/src/services/mod.rs index 52fbcf7da..12a330c17 100644 --- a/crates/ibc/src/services/mod.rs +++ b/crates/ibc/src/services/mod.rs @@ -44,6 +44,7 @@ mod channel; mod client; mod connection; +mod error; pub use channel::ChannelQueryService; pub use client::ClientQueryService; From 33ff7976ba3172965de54f7afcd3d4d8362737ea Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Wed, 30 Aug 2023 13:42:45 +0200 Subject: [PATCH 28/58] remove redundant map_errs --- crates/ibc/src/services/channel.rs | 448 ++++---------------------- crates/ibc/src/services/client.rs | 101 ++---- crates/ibc/src/services/connection.rs | 134 ++------ 3 files changed, 110 insertions(+), 573 deletions(-) diff --git a/crates/ibc/src/services/channel.rs b/crates/ibc/src/services/channel.rs index 0ab20cd3d..9e551fda2 100644 --- a/crates/ibc/src/services/channel.rs +++ b/crates/ibc/src/services/channel.rs @@ -1,3 +1,4 @@ +use alloc::string::ToString; use ibc_proto::{ google::protobuf::Any, ibc::core::{ @@ -74,35 +75,15 @@ where trace!("Got channel request: {:?}", request); let request_ref = request.get_ref(); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!( - "Invalid channel id: {}", - request_ref.channel_id - )) - })?; + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; - let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) - })?; + let port_id = PortId::from_str(request_ref.port_id.as_str())?; let channel_end_path = ChannelEndPath::new(&port_id, &channel_id); - let channel_end = self - .ibc_context - .channel_end(&channel_end_path) - .map_err(|_| { - Status::not_found(std::format!( - "Channel end not found for channel {}", - channel_id - )) - })?; + let channel_end = self.ibc_context.channel_end(&channel_end_path)?; - let current_height = self.ibc_context.host_height().map_err(|_| { - Status::not_found(std::format!( - "Current height not found for channel {}", - channel_id - )) - })?; + let current_height = self.ibc_context.host_height()?; let proof = self .ibc_context @@ -127,20 +108,12 @@ where ) -> Result, Status> { trace!("Got channels request: {:?}", request); - let channel_ends = self - .ibc_context - .channel_ends() - .map_err(|_| Status::not_found("Channel ends not found"))?; + let channel_ends = self.ibc_context.channel_ends()?; Ok(Response::new(QueryChannelsResponse { channels: channel_ends.into_iter().map(Into::into).collect(), pagination: None, - height: Some( - self.ibc_context - .host_height() - .map_err(|_| Status::not_found("Current height not found"))? - .into(), - ), + height: Some(self.ibc_context.host_height()?.into()), })) } /// ConnectionChannels queries all the channels associated with a connection @@ -153,38 +126,14 @@ where let request_ref = request.get_ref(); - let connection_id = - ConnectionId::from_str(request_ref.connection.as_str()).map_err(|_| { - Status::invalid_argument(std::format!( - "Invalid connection id: {}", - request_ref.connection - )) - })?; + let connection_id = ConnectionId::from_str(request_ref.connection.as_str())?; - let channel_ends = self - .ibc_context - .connection_channel_ends(&connection_id) - .map_err(|_| { - Status::not_found(std::format!( - "Connection channels not found for connection {}", - connection_id - )) - })?; + let channel_ends = self.ibc_context.connection_channel_ends(&connection_id)?; Ok(Response::new(QueryConnectionChannelsResponse { channels: channel_ends.into_iter().map(Into::into).collect(), pagination: None, - height: Some( - self.ibc_context - .host_height() - .map_err(|_| { - Status::not_found(std::format!( - "Current height not found for connection {}", - connection_id - )) - })? - .into(), - ), + height: Some(self.ibc_context.host_height()?.into()), })) } /// ChannelClientState queries for the client state for the channel associated @@ -197,40 +146,18 @@ where let request_ref = request.get_ref(); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!( - "Invalid channel id: {}", - request_ref.channel_id - )) - })?; + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; - let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) - })?; + let port_id = PortId::from_str(request_ref.port_id.as_str())?; let channel_end_path = ChannelEndPath::new(&port_id, &channel_id); - let channel_end = self - .ibc_context - .channel_end(&channel_end_path) - .map_err(|_| { - Status::not_found(std::format!( - "Channel end not found for channel {}", - channel_id - )) - })?; + let channel_end = self.ibc_context.channel_end(&channel_end_path)?; let connection_end = channel_end .connection_hops() .first() - .map(|connection_id| { - self.ibc_context.connection_end(connection_id).map_err(|_| { - Status::not_found(std::format!( - "Connection end not found for connection {}", - connection_id - )) - }) - }) + .map(|connection_id| self.ibc_context.connection_end(connection_id)) .ok_or_else(|| { Status::not_found(std::format!( "Channel {} has no connection hops", @@ -238,22 +165,9 @@ where )) })??; - let client_state = self - .ibc_context - .client_state(connection_end.client_id()) - .map_err(|_| { - Status::not_found(std::format!( - "Client state not found for client {}", - connection_end.client_id() - )) - })?; + let client_state = self.ibc_context.client_state(connection_end.client_id())?; - let current_height = self.ibc_context.host_height().map_err(|_| { - Status::not_found(std::format!( - "Current height not found for client {}", - connection_end.client_id() - )) - })?; + let current_height = self.ibc_context.host_height()?; let proof = self .ibc_context @@ -287,40 +201,21 @@ where let request_ref = request.get_ref(); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!( - "Invalid channel id: {}", - request_ref.channel_id - )) - })?; + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; - let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) - })?; + let port_id = PortId::from_str(request_ref.port_id.as_str())?; + + let height = Height::new(request_ref.revision_number, request_ref.revision_height) + .map_err(|e| Status::invalid_argument(e.to_string()))?; let channel_end_path = ChannelEndPath::new(&port_id, &channel_id); - let channel_end = self - .ibc_context - .channel_end(&channel_end_path) - .map_err(|_| { - Status::not_found(std::format!( - "Channel end not found for channel {}", - channel_id - )) - })?; + let channel_end = self.ibc_context.channel_end(&channel_end_path)?; let connection_end = channel_end .connection_hops() .first() - .map(|connection_id| { - self.ibc_context.connection_end(connection_id).map_err(|_| { - Status::not_found(std::format!( - "Connection end not found for connection {}", - connection_id - )) - }) - }) + .map(|connection_id| self.ibc_context.connection_end(connection_id)) .ok_or_else(|| { Status::not_found(std::format!( "Channel {} has no connection hops", @@ -328,36 +223,11 @@ where )) })??; - let consensus_path = ClientConsensusStatePath::new( - connection_end.client_id(), - &Height::new(request_ref.revision_number, request_ref.revision_height).map_err( - |_| { - Status::invalid_argument(std::format!( - "Invalid height: {}-{}", - request_ref.revision_number, - request_ref.revision_height - )) - }, - )?, - ); - - let consensus_state = self - .ibc_context - .consensus_state(&consensus_path) - .map_err(|_| { - Status::not_found(std::format!( - "Consensus state not found for client {} and revision {}", - connection_end.client_id(), - request_ref.revision_number - )) - })?; + let consensus_path = ClientConsensusStatePath::new(connection_end.client_id(), &height); - let current_height = self.ibc_context.host_height().map_err(|_| { - Status::not_found(std::format!( - "Current height not found for client {}", - connection_end.client_id() - )) - })?; + let consensus_state = self.ibc_context.consensus_state(&consensus_path)?; + + let current_height = self.ibc_context.host_height()?; let proof = self .ibc_context @@ -385,38 +255,17 @@ where let request_ref = request.get_ref(); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!( - "Invalid channel id: {}", - request_ref.channel_id - )) - })?; + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; - let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) - })?; + let port_id = PortId::from_str(request_ref.port_id.as_str())?; let sequence = Sequence::from(request_ref.sequence); let commitment_path = CommitmentPath::new(&port_id, &channel_id, sequence); - let packet_commitment_data = self - .ibc_context - .get_packet_commitment(&commitment_path) - .map_err(|_| { - Status::not_found(std::format!( - "Packet commitment not found for channel {} and sequence {}", - channel_id, - sequence - )) - })?; + let packet_commitment_data = self.ibc_context.get_packet_commitment(&commitment_path)?; - let current_height = self.ibc_context.host_height().map_err(|_| { - Status::not_found(std::format!( - "Current height not found for channel {}", - channel_id - )) - })?; + let current_height = self.ibc_context.host_height()?; let proof = self .ibc_context @@ -445,28 +294,15 @@ where let request_ref = request.get_ref(); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!( - "Invalid channel id: {}", - request_ref.channel_id - )) - })?; + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; - let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) - })?; + let port_id = PortId::from_str(request_ref.port_id.as_str())?; let channel_end_path = ChannelEndPath::new(&port_id, &channel_id); let commitments = self .ibc_context - .packet_commitments(&channel_end_path) - .map_err(|_| { - Status::not_found(std::format!( - "Packet commitments not found for channel {}", - channel_id - )) - })? + .packet_commitments(&channel_end_path)? .into_iter() .map(|path| { self.ibc_context @@ -477,30 +313,13 @@ where sequence: path.sequence.into(), data: commitment.into_vec(), }) - .map_err(|_| { - Status::not_found(std::format!( - "Packet commitment not found for channel {} and sequence {}", - channel_id, - path.sequence - )) - }) }) .collect::>()?; Ok(Response::new(QueryPacketCommitmentsResponse { commitments, pagination: None, - height: Some( - self.ibc_context - .host_height() - .map_err(|_| { - Status::not_found(std::format!( - "Current height not found for channel {}", - channel_id - )) - })? - .into(), - ), + height: Some(self.ibc_context.host_height()?.into()), })) } @@ -512,16 +331,9 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!( - "Invalid channel id: {}", - request_ref.channel_id - )) - })?; + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; - let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) - })?; + let port_id = PortId::from_str(request_ref.port_id.as_str())?; let sequence = Sequence::from(request_ref.sequence); @@ -531,12 +343,7 @@ where // Unreceived packets are not stored let packet_receipt_data = self.ibc_context.get_packet_receipt(&receipt_path); - let current_height = self.ibc_context.host_height().map_err(|_| { - Status::not_found(std::format!( - "Current height not found for channel {}", - channel_id - )) - })?; + let current_height = self.ibc_context.host_height()?; let proof = self .ibc_context @@ -562,16 +369,9 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!( - "Invalid channel id: {}", - request_ref.channel_id - )) - })?; + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; - let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) - })?; + let port_id = PortId::from_str(request_ref.port_id.as_str())?; let sequence = Sequence::from(request_ref.sequence); @@ -579,21 +379,9 @@ where let packet_acknowledgement_data = self .ibc_context - .get_packet_acknowledgement(&acknowledgement_path) - .map_err(|_| { - Status::not_found(std::format!( - "Packet acknowledgement not found for channel {} and sequence {}", - channel_id, - sequence - )) - })?; + .get_packet_acknowledgement(&acknowledgement_path)?; - let current_height = self.ibc_context.host_height().map_err(|_| { - Status::not_found(std::format!( - "Current height not found for channel {}", - channel_id - )) - })?; + let current_height = self.ibc_context.host_height()?; let proof = self .ibc_context @@ -620,16 +408,9 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!( - "Invalid channel id: {}", - request_ref.channel_id - )) - })?; + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; - let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) - })?; + let port_id = PortId::from_str(request_ref.port_id.as_str())?; let commitment_sequences = request_ref .packet_commitment_sequences @@ -641,13 +422,7 @@ where let acknowledgements = self .ibc_context - .packet_acknowledgements(&channel_end_path, commitment_sequences) - .map_err(|_| { - Status::not_found(std::format!( - "Packet acknowledgements not found for channel {}", - channel_id - )) - })? + .packet_acknowledgements(&channel_end_path, commitment_sequences)? .into_iter() .map(|path| { self.ibc_context @@ -658,30 +433,13 @@ where sequence: path.sequence.into(), data: acknowledgement.into_vec(), }) - .map_err(|_| { - Status::not_found(std::format!( - "Packet acknowledgement not found for channel {} and sequence {}", - channel_id, - path.sequence - )) - }) }) .collect::>()?; Ok(Response::new(QueryPacketAcknowledgementsResponse { acknowledgements, pagination: None, - height: Some( - self.ibc_context - .host_height() - .map_err(|_| { - Status::not_found(std::format!( - "Current height not found for channel {}", - channel_id - )) - })? - .into(), - ), + height: Some(self.ibc_context.host_height()?.into()), })) } @@ -697,16 +455,9 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!( - "Invalid channel id: {}", - request_ref.channel_id - )) - })?; + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; - let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) - })?; + let port_id = PortId::from_str(request_ref.port_id.as_str())?; let sequences = request_ref .packet_commitment_sequences @@ -718,27 +469,11 @@ where let unreceived_packets = self .ibc_context - .unreceived_packets(&channel_end_path, sequences) - .map_err(|_| { - Status::not_found(std::format!( - "Unreceived packets not found for channel {}", - channel_id - )) - })?; + .unreceived_packets(&channel_end_path, sequences)?; Ok(Response::new(QueryUnreceivedPacketsResponse { sequences: unreceived_packets.into_iter().map(Into::into).collect(), - height: Some( - self.ibc_context - .host_height() - .map_err(|_| { - Status::not_found(std::format!( - "Current height not found for channel {}", - channel_id - )) - })? - .into(), - ), + height: Some(self.ibc_context.host_height()?.into()), })) } @@ -750,16 +485,9 @@ where ) -> Result, Status> { let request_ref = _request.get_ref(); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!( - "Invalid channel id: {}", - request_ref.channel_id - )) - })?; + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; - let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) - })?; + let port_id = PortId::from_str(request_ref.port_id.as_str())?; let sequences = request_ref .packet_ack_sequences @@ -771,27 +499,11 @@ where let unreceived_acks = self .ibc_context - .unreceived_acks(&channel_end_path, sequences) - .map_err(|_| { - Status::not_found(std::format!( - "Unreceived acks not found for channel {}", - channel_id - )) - })?; + .unreceived_acks(&channel_end_path, sequences)?; Ok(Response::new(QueryUnreceivedAcksResponse { sequences: unreceived_acks.into_iter().map(Into::into).collect(), - height: Some( - self.ibc_context - .host_height() - .map_err(|_| { - Status::not_found(std::format!( - "Current height not found for channel {}", - channel_id - )) - })? - .into(), - ), + height: Some(self.ibc_context.host_height()?.into()), })) } @@ -802,35 +514,17 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!( - "Invalid channel id: {}", - request_ref.channel_id - )) - })?; + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; - let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) - })?; + let port_id = PortId::from_str(request_ref.port_id.as_str())?; let next_seq_recv_path = SeqRecvPath::new(&port_id, &channel_id); let next_sequence_recv = self .ibc_context - .get_next_sequence_recv(&next_seq_recv_path) - .map_err(|_| { - Status::not_found(std::format!( - "Next sequence receive not found for channel {}", - channel_id - )) - })?; + .get_next_sequence_recv(&next_seq_recv_path)?; - let current_height = self.ibc_context.host_height().map_err(|_| { - Status::not_found(std::format!( - "Current height not found for channel {}", - channel_id - )) - })?; + let current_height = self.ibc_context.host_height()?; let proof = self .ibc_context @@ -856,35 +550,17 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!( - "Invalid channel id: {}", - request_ref.channel_id - )) - })?; + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; - let port_id = PortId::from_str(request_ref.port_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!("Invalid port id: {}", request_ref.port_id)) - })?; + let port_id = PortId::from_str(request_ref.port_id.as_str())?; let next_seq_send_path = SeqSendPath::new(&port_id, &channel_id); let next_sequence_send = self .ibc_context - .get_next_sequence_send(&next_seq_send_path) - .map_err(|_| { - Status::not_found(std::format!( - "Next sequence send not found for channel {}", - channel_id - )) - })?; + .get_next_sequence_send(&next_seq_send_path)?; - let current_height = self.ibc_context.host_height().map_err(|_| { - Status::not_found(std::format!( - "Current height not found for channel {}", - channel_id - )) - })?; + let current_height = self.ibc_context.host_height()?; let proof = self .ibc_context diff --git a/crates/ibc/src/services/client.rs b/crates/ibc/src/services/client.rs index da54564a5..edde06096 100644 --- a/crates/ibc/src/services/client.rs +++ b/crates/ibc/src/services/client.rs @@ -1,3 +1,4 @@ +use alloc::string::ToString; use ibc_proto::{ google::protobuf::Any, ibc::core::client::v1::{ @@ -15,11 +16,12 @@ use ibc_proto::{ use crate::{ core::{ + ics02_client::error::ClientError, ics24_host::{ identifier::ClientId, path::{ClientConsensusStatePath, ClientStatePath, Path, UpgradeClientPath}, }, - QueryContext, ValidationContext, + ContextError, QueryContext, ValidationContext, }, hosts::tendermint::upgrade_proposal::UpgradeValidationContext, Height, @@ -78,20 +80,10 @@ where let request_ref = request.get_ref(); - let client_id = ClientId::from_str(request_ref.client_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!("Invalid client id: {}", request_ref.client_id)) - })?; - let client_state = self.ibc_context.client_state(&client_id).map_err(|_| { - Status::not_found(std::format!( - "Client state not found for client {}", - client_id - )) - })?; - - let current_height = self - .ibc_context - .host_height() - .map_err(|_| Status::not_found("Current height not found"))?; + let client_id = ClientId::from_str(request_ref.client_id.as_str())?; + let client_state = self.ibc_context.client_state(&client_id)?; + + let current_height = self.ibc_context.host_height()?; let proof = self .ibc_context @@ -120,10 +112,7 @@ where ) -> Result, Status> { trace!("Got client states request: {:?}", request); - let client_states = self - .ibc_context - .client_states() - .map_err(|_| Status::not_found("Client states not found"))?; + let client_states = self.ibc_context.client_states()?; Ok(Response::new(QueryClientStatesResponse { client_states: client_states @@ -145,34 +134,16 @@ where let request_ref = request.get_ref(); - let client_id = ClientId::from_str(request_ref.client_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!("Invalid client id: {}", request_ref.client_id)) - })?; + let client_id = ClientId::from_str(request_ref.client_id.as_str())?; let height = Height::new(request_ref.revision_number, request_ref.revision_height) - .map_err(|_| { - Status::invalid_argument(std::format!( - "Invalid height: {}-{}", - request_ref.revision_number, - request_ref.revision_height - )) - })?; + .map_err(|e| Status::invalid_argument(e.to_string()))?; let consensus_state = self .ibc_context - .consensus_state(&ClientConsensusStatePath::new(&client_id, &height)) - .map_err(|_| { - Status::not_found(std::format!( - "Consensus state not found for client {} at height {}", - client_id, - height - )) - })?; + .consensus_state(&ClientConsensusStatePath::new(&client_id, &height))?; - let current_height = self - .ibc_context - .host_height() - .map_err(|_| Status::not_found("Current height not found"))?; + let current_height = self.ibc_context.host_height()?; let proof = self .ibc_context @@ -203,16 +174,9 @@ where let request_ref = request.get_ref(); - let client_id = ClientId::from_str(request_ref.client_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!("Invalid client id: {}", request_ref.client_id)) - })?; + let client_id = ClientId::from_str(request_ref.client_id.as_str())?; - let consensus_states = self.ibc_context.consensus_states(&client_id).map_err(|_| { - Status::not_found(std::format!( - "Consensus states not found for client {}", - client_id - )) - })?; + let consensus_states = self.ibc_context.consensus_states(&client_id)?; Ok(Response::new(QueryConsensusStatesResponse { consensus_states: consensus_states @@ -234,19 +198,9 @@ where let request_ref = request.get_ref(); - let client_id = ClientId::from_str(request_ref.client_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!("Invalid client id: {}", request_ref.client_id)) - })?; + let client_id = ClientId::from_str(request_ref.client_id.as_str())?; - let consensus_state_heights = self - .ibc_context - .consensus_state_heights(&client_id) - .map_err(|_| { - Status::not_found(std::format!( - "Consensus state heights not found for client {}", - client_id - )) - })?; + let consensus_state_heights = self.ibc_context.consensus_state_heights(&client_id)?; Ok(Response::new(QueryConsensusStateHeightsResponse { consensus_state_heights: consensus_state_heights @@ -265,16 +219,9 @@ where let request_ref = request.get_ref(); - let client_id = ClientId::from_str(request_ref.client_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!("Invalid client id: {}", request_ref.client_id)) - })?; + let client_id = ClientId::from_str(request_ref.client_id.as_str())?; - let client_status = self.ibc_context.client_status(&client_id).map_err(|_| { - Status::not_found(std::format!( - "Client status not found for client {}", - client_id - )) - })?; + let client_status = self.ibc_context.client_status(&client_id)?; Ok(Response::new(QueryClientStatusResponse { status: std::format!("{}", client_status), @@ -308,14 +255,16 @@ where let plan = self .upgrade_context .upgrade_plan() - .map_err(|_| Status::not_found("Upgrade plan not found"))?; + .map_err(ClientError::from) + .map_err(ContextError::from)?; let upgraded_client_state_path = UpgradeClientPath::UpgradedClientState(plan.height); let upgraded_client_state = self .upgrade_context .upgraded_client_state(&upgraded_client_state_path) - .map_err(|_| Status::not_found("Upgraded client state not found"))?; + .map_err(ClientError::from) + .map_err(ContextError::from)?; Ok(Response::new(QueryUpgradedClientStateResponse { upgraded_client_state: Some(upgraded_client_state.into()), @@ -331,7 +280,8 @@ where let plan = self .upgrade_context .upgrade_plan() - .map_err(|_| Status::not_found("Upgrade plan not found"))?; + .map_err(ClientError::from) + .map_err(ContextError::from)?; let upgraded_consensus_state_path = UpgradeClientPath::UpgradedClientConsensusState(plan.height); @@ -339,7 +289,8 @@ where let upgraded_consensus_state = self .upgrade_context .upgraded_consensus_state(&upgraded_consensus_state_path) - .map_err(|_| Status::not_found("Upgraded consensus state not found"))?; + .map_err(ClientError::from) + .map_err(ContextError::from)?; Ok(Response::new(QueryUpgradedConsensusStateResponse { upgraded_consensus_state: Some(upgraded_consensus_state.into()), diff --git a/crates/ibc/src/services/connection.rs b/crates/ibc/src/services/connection.rs index a9c9dec98..c6b912e9c 100644 --- a/crates/ibc/src/services/connection.rs +++ b/crates/ibc/src/services/connection.rs @@ -1,3 +1,4 @@ +use alloc::string::ToString; use ibc_proto::{ google::protobuf::Any, ibc::core::{ @@ -65,28 +66,11 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - let connection_id = - ConnectionId::from_str(request_ref.connection_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!( - "Invalid connection id: {}", - request_ref.connection_id - )) - })?; + let connection_id = ConnectionId::from_str(request_ref.connection_id.as_str())?; - let connection_end = self - .ibc_context - .connection_end(&connection_id) - .map_err(|_| { - Status::not_found(std::format!( - "Connection end not found for connection {}", - connection_id - )) - })?; + let connection_end = self.ibc_context.connection_end(&connection_id)?; - let current_height = self - .ibc_context - .host_height() - .map_err(|_| Status::not_found("Current height not found"))?; + let current_height = self.ibc_context.host_height()?; let proof = self .ibc_context @@ -114,20 +98,12 @@ where ) -> Result, Status> { trace!("Got connections request: {:?}", request); - let connections = self - .ibc_context - .connection_ends() - .map_err(|_| Status::not_found("Connections not found"))?; + let connections = self.ibc_context.connection_ends()?; Ok(Response::new(QueryConnectionsResponse { connections: connections.into_iter().map(Into::into).collect(), pagination: None, - height: Some( - self.ibc_context - .host_height() - .map_err(|_| Status::not_found("Current height not found"))? - .into(), - ), + height: Some(self.ibc_context.host_height()?.into()), })) } @@ -139,19 +115,11 @@ where let request_ref = request.get_ref(); - let client_id = ClientId::from_str(request_ref.client_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!("Invalid client id: {}", request_ref.client_id)) - })?; + let client_id = ClientId::from_str(request_ref.client_id.as_str())?; - let connections = self - .ibc_context - .client_connection_ends(&client_id) - .map_err(|_| Status::not_found("Connections not found"))?; + let connections = self.ibc_context.client_connection_ends(&client_id)?; - let current_height = self - .ibc_context - .host_height() - .map_err(|_| Status::not_found("Current height not found"))?; + let current_height = self.ibc_context.host_height()?; let proof: alloc::vec::Vec = self .ibc_context @@ -179,38 +147,13 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - let connection_id = - ConnectionId::from_str(request_ref.connection_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!( - "Invalid connection id: {}", - request_ref.connection_id - )) - })?; + let connection_id = ConnectionId::from_str(request_ref.connection_id.as_str())?; - let connection_end = self - .ibc_context - .connection_end(&connection_id) - .map_err(|_| { - Status::not_found(std::format!( - "Connection end not found for connection {}", - connection_id - )) - })?; + let connection_end = self.ibc_context.connection_end(&connection_id)?; - let client_state = self - .ibc_context - .client_state(connection_end.client_id()) - .map_err(|_| { - Status::not_found(std::format!( - "Client state not found for connection {}", - connection_id - )) - })?; + let client_state = self.ibc_context.client_state(connection_end.client_id())?; - let current_height = self - .ibc_context - .host_height() - .map_err(|_| Status::not_found("Current height not found"))?; + let current_height = self.ibc_context.host_height()?; let proof = self .ibc_context @@ -241,51 +184,18 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - let connection_id = - ConnectionId::from_str(request_ref.connection_id.as_str()).map_err(|_| { - Status::invalid_argument(std::format!( - "Invalid connection id: {}", - request_ref.connection_id - )) - })?; + let connection_id = ConnectionId::from_str(request_ref.connection_id.as_str())?; - let connection_end = self - .ibc_context - .connection_end(&connection_id) - .map_err(|_| { - Status::not_found(std::format!( - "Connection end not found for connection {}", - connection_id - )) - })?; + let connection_end = self.ibc_context.connection_end(&connection_id)?; - let consensus_path = ClientConsensusStatePath::new( - connection_end.client_id(), - &Height::new(request_ref.revision_number, request_ref.revision_height).map_err( - |_| { - Status::invalid_argument(std::format!( - "Invalid height: {}-{}", - request_ref.revision_number, - request_ref.revision_height - )) - }, - )?, - ); - - let consensus_state = self - .ibc_context - .consensus_state(&consensus_path) - .map_err(|_| { - Status::not_found(std::format!( - "Consensus state not found for connection {}", - connection_id - )) - })?; + let height = Height::new(request_ref.revision_number, request_ref.revision_height) + .map_err(|e| Status::invalid_argument(e.to_string()))?; - let current_height = self - .ibc_context - .host_height() - .map_err(|_| Status::not_found("Current height not found"))?; + let consensus_path = ClientConsensusStatePath::new(connection_end.client_id(), &height); + + let consensus_state = self.ibc_context.consensus_state(&consensus_path)?; + + let current_height = self.ibc_context.host_height()?; let proof = self .ibc_context From b995f182208a7155ebd04a5c2e9875389b33c05a Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Wed, 30 Aug 2023 13:45:14 +0200 Subject: [PATCH 29/58] fix cargo doc lint --- crates/ibc/src/core/context.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ibc/src/core/context.rs b/crates/ibc/src/core/context.rs index a6b4bf721..414d500c2 100644 --- a/crates/ibc/src/core/context.rs +++ b/crates/ibc/src/core/context.rs @@ -102,7 +102,7 @@ impl std::error::Error for RouterError { /// Context to be implemented by the host that provides all "read-only" methods. /// -/// Trait used for the top-level [`validate`](crate::core::validate) and the [`gRPC query services`](crate::services). +/// Trait used for the top-level [`validate`](crate::core::validate) pub trait ValidationContext { type ClientValidationContext; type E: ClientExecutionContext; From 721b6bbaa30a215cc43d3e1e3edc276682af38eb Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 31 Aug 2023 19:00:26 +0200 Subject: [PATCH 30/58] remove irrelevant comments --- crates/ibc/src/services/channel.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/ibc/src/services/channel.rs b/crates/ibc/src/services/channel.rs index 9e551fda2..0dcdb5d63 100644 --- a/crates/ibc/src/services/channel.rs +++ b/crates/ibc/src/services/channel.rs @@ -445,10 +445,6 @@ where /// UnreceivedPackets returns all the unreceived IBC packets associated with /// a channel and sequences. - /// - /// QUESTION. Currently only works for unordered channels; ordered channels - /// don't use receipts. However, ibc-go does it this way. Investigate if - /// this query only ever makes sense on unordered channels. async fn unreceived_packets( &self, request: Request, From a87d88c0284a3493e1e62da693384f7e60c7a5ca Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Mon, 4 Sep 2023 12:18:02 +0200 Subject: [PATCH 31/58] handle empty sequence list --- crates/ibc/src/core/context.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/ibc/src/core/context.rs b/crates/ibc/src/core/context.rs index 414d500c2..84c6fbf43 100644 --- a/crates/ibc/src/core/context.rs +++ b/crates/ibc/src/core/context.rs @@ -320,21 +320,21 @@ pub trait QueryContext: ProvableContext + ValidationContext { fn packet_acknowledgements( &self, channel_end_path: &ChannelEndPath, - sequences: impl IntoIterator, + sequences: impl ExactSizeIterator, ) -> Result, ContextError>; /// Filters the list of packet sequencees for the given channel end that are not received. fn unreceived_packets( &self, channel_end_path: &ChannelEndPath, - sequences: impl IntoIterator, + sequences: impl ExactSizeIterator, ) -> Result, ContextError>; /// Filters the list of packet sequencees for the given channel end whose acknowledgement is not received. fn unreceived_acks( &self, channel_end_path: &ChannelEndPath, - sequences: impl IntoIterator, + sequences: impl ExactSizeIterator, ) -> Result, ContextError>; } From 5536594fa56aeafc65c778c813654757b0ec4484 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Tue, 5 Sep 2023 10:57:11 +0200 Subject: [PATCH 32/58] a general variant of PackerError --- crates/ibc/src/core/ics04_channel/error.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/ibc/src/core/ics04_channel/error.rs b/crates/ibc/src/core/ics04_channel/error.rs index d8a98a2a7..478c1575f 100644 --- a/crates/ibc/src/core/ics04_channel/error.rs +++ b/crates/ibc/src/core/ics04_channel/error.rs @@ -171,6 +171,8 @@ pub enum PacketError { }, /// Cannot encode sequence `{sequence}` CannotEncodeSequence { sequence: Sequence }, + /// other error: `{description}` + Other { description: String }, } impl From for ChannelError { From 76c139b1257ae16f23edd19f502d41928681dd36 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Tue, 5 Sep 2023 11:40:06 +0200 Subject: [PATCH 33/58] polish comments and logging --- crates/ibc/src/core/context.rs | 12 +++-- crates/ibc/src/services/channel.rs | 73 ++++++++++++++------------- crates/ibc/src/services/client.rs | 36 ++++++++----- crates/ibc/src/services/connection.rs | 18 +++++-- 4 files changed, 83 insertions(+), 56 deletions(-) diff --git a/crates/ibc/src/core/context.rs b/crates/ibc/src/core/context.rs index 84c6fbf43..09e75469e 100644 --- a/crates/ibc/src/core/context.rs +++ b/crates/ibc/src/core/context.rs @@ -256,7 +256,7 @@ pub trait ValidationContext { /// Trait used for the [`gRPC query services`](crate::services). #[cfg(feature = "grpc")] pub trait ProvableContext { - /// Returns a proof for the given path at the given height. + /// Returns the proof for the given path at the given height. /// As this is in the context of IBC, the path is expected to be an [`IbcPath`](Path). fn get_proof(&self, height: Height, path: &Path) -> Option>; } @@ -284,6 +284,8 @@ pub trait QueryContext: ProvableContext + ValidationContext { /// Returns the status of the given client. fn client_status(&self, client_id: &ClientId) -> Result; + + /// Returns the list of supported client types. fn allowed_clients(&self) -> Vec; // Connection queries @@ -316,21 +318,23 @@ pub trait QueryContext: ProvableContext + ValidationContext { channel_end_path: &ChannelEndPath, ) -> Result, ContextError>; - /// Filters the list of packet sequencees for the given channel end that are acknowledged. + /// Filters the list of packet sequences for the given channel end that are acknowledged. + /// Returns all the packet acknowledgements if `sequences` is empty. fn packet_acknowledgements( &self, channel_end_path: &ChannelEndPath, sequences: impl ExactSizeIterator, ) -> Result, ContextError>; - /// Filters the list of packet sequencees for the given channel end that are not received. + /// Filters the packet sequences for the given channel end that are not received. fn unreceived_packets( &self, channel_end_path: &ChannelEndPath, sequences: impl ExactSizeIterator, ) -> Result, ContextError>; - /// Filters the list of packet sequencees for the given channel end whose acknowledgement is not received. + /// Filters the list of packet sequences for the given channel end whose acknowledgement is not received. + /// Returns all the unreceived acknowledgements if `sequences` is empty. fn unreceived_acks( &self, channel_end_path: &ChannelEndPath, diff --git a/crates/ibc/src/services/channel.rs b/crates/ibc/src/services/channel.rs index 0dcdb5d63..83bd0db31 100644 --- a/crates/ibc/src/services/channel.rs +++ b/crates/ibc/src/services/channel.rs @@ -72,9 +72,10 @@ where &self, request: Request, ) -> Result, Status> { - trace!("Got channel request: {:?}", request); let request_ref = request.get_ref(); + trace!("Got channel request: {:?}", &request_ref); + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -101,31 +102,32 @@ where proof_height: Some(current_height.into()), })) } - /// Channels queries all the IBC channels of a chain. + async fn channels( &self, request: Request, ) -> Result, Status> { - trace!("Got channels request: {:?}", request); + let request_ref = request.get_ref(); let channel_ends = self.ibc_context.channel_ends()?; + trace!("Got channels request: {:?}", &request_ref); + Ok(Response::new(QueryChannelsResponse { channels: channel_ends.into_iter().map(Into::into).collect(), pagination: None, height: Some(self.ibc_context.host_height()?.into()), })) } - /// ConnectionChannels queries all the channels associated with a connection - /// end. + async fn connection_channels( &self, request: Request, ) -> Result, Status> { - trace!("Got connection channels request: {:?}", request); - let request_ref = request.get_ref(); + trace!("Got connection channels request: {:?}", &request_ref); + let connection_id = ConnectionId::from_str(request_ref.connection.as_str())?; let channel_ends = self.ibc_context.connection_channel_ends(&connection_id)?; @@ -136,16 +138,15 @@ where height: Some(self.ibc_context.host_height()?.into()), })) } - /// ChannelClientState queries for the client state for the channel associated - /// with the provided channel identifiers. + async fn channel_client_state( &self, request: Request, ) -> Result, Status> { - trace!("Got channel client state request: {:?}", request); - let request_ref = request.get_ref(); + trace!("Got channel client state request: {:?}", &request_ref); + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -191,16 +192,15 @@ where proof_height: Some(current_height.into()), })) } - /// ChannelConsensusState queries for the consensus state for the channel - /// associated with the provided channel identifiers. + async fn channel_consensus_state( &self, request: Request, ) -> Result, Status> { - trace!("Got channel consensus state request: {:?}", request); - let request_ref = request.get_ref(); + trace!("Got channel consensus state request: {:?}", &request_ref); + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -246,15 +246,15 @@ where proof_height: Some(current_height.into()), })) } - /// PacketCommitment queries a stored packet commitment hash. + async fn packet_commitment( &self, request: Request, ) -> Result, Status> { - trace!("Got packet commitment request: {:?}", request); - let request_ref = request.get_ref(); + trace!("Got packet commitment request: {:?}", &request_ref); + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -284,16 +284,14 @@ where })) } - /// PacketCommitments returns all the packet commitments hashes associated - /// with a channel. async fn packet_commitments( &self, request: Request, ) -> Result, Status> { - trace!("Got packet commitments request: {:?}", request); - let request_ref = request.get_ref(); + trace!("Got packet commitments request: {:?}", &request_ref); + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -323,14 +321,14 @@ where })) } - /// PacketReceipt queries if a given packet sequence has been received on the - /// queried chain async fn packet_receipt( &self, request: Request, ) -> Result, Status> { let request_ref = request.get_ref(); + trace!("Got packet receipt request: {:?}", &request_ref); + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -362,13 +360,14 @@ where })) } - /// PacketAcknowledgement queries a stored packet acknowledgement hash. async fn packet_acknowledgement( &self, request: Request, ) -> Result, Status> { let request_ref = request.get_ref(); + trace!("Got packet acknowledgement request: {:?}", &request_ref); + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -400,14 +399,15 @@ where })) } - /// PacketAcknowledgements returns all the packet acknowledgements associated - /// with a channel. + /// Returns all the acknowledgements if sequences is omitted. async fn packet_acknowledgements( &self, request: Request, ) -> Result, Status> { let request_ref = request.get_ref(); + trace!("Got packet acknowledgements request: {:?}", &request_ref); + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -443,14 +443,14 @@ where })) } - /// UnreceivedPackets returns all the unreceived IBC packets associated with - /// a channel and sequences. async fn unreceived_packets( &self, request: Request, ) -> Result, Status> { let request_ref = request.get_ref(); + trace!("Got unreceived packets request: {:?}", &request_ref); + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -473,13 +473,14 @@ where })) } - /// UnreceivedAcks returns all the unreceived IBC acknowledgements associated - /// with a channel and sequences. + /// Returns all the unreceived acknowledgements if sequences is omitted. async fn unreceived_acks( &self, - _request: Request, + request: Request, ) -> Result, Status> { - let request_ref = _request.get_ref(); + let request_ref = request.get_ref(); + + trace!("Got unreceived acks request: {:?}", &request_ref); let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; @@ -503,13 +504,14 @@ where })) } - /// NextSequenceReceive returns the next receive sequence for a given channel. async fn next_sequence_receive( &self, request: Request, ) -> Result, Status> { let request_ref = request.get_ref(); + trace!("Got next sequence receive request: {:?}", &request_ref); + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -539,13 +541,14 @@ where })) } - // NextSequenceSend returns the next send sequence for a given channel. async fn next_sequence_send( &self, request: Request, ) -> Result, Status> { let request_ref = request.get_ref(); + trace!("Got next sequence send request: {:?}", &request_ref); + let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; diff --git a/crates/ibc/src/services/client.rs b/crates/ibc/src/services/client.rs index edde06096..00860486e 100644 --- a/crates/ibc/src/services/client.rs +++ b/crates/ibc/src/services/client.rs @@ -76,10 +76,10 @@ where &self, request: Request, ) -> Result, Status> { - trace!("Got client state request: {:?}", request); - let request_ref = request.get_ref(); + trace!("Got client state request: {:?}", request_ref); + let client_id = ClientId::from_str(request_ref.client_id.as_str())?; let client_state = self.ibc_context.client_state(&client_id)?; @@ -110,7 +110,9 @@ where &self, request: Request, ) -> Result, Status> { - trace!("Got client states request: {:?}", request); + let request_ref = request.get_ref(); + + trace!("Got client states request: {:?}", request_ref); let client_states = self.ibc_context.client_states()?; @@ -130,10 +132,10 @@ where &self, request: Request, ) -> Result, Status> { - trace!("Got consensus state request: {:?}", request); - let request_ref = request.get_ref(); + trace!("Got consensus state request: {:?}", request_ref); + let client_id = ClientId::from_str(request_ref.client_id.as_str())?; let height = Height::new(request_ref.revision_number, request_ref.revision_height) @@ -170,10 +172,10 @@ where &self, request: Request, ) -> Result, Status> { - trace!("Got consensus states request: {:?}", request); - let request_ref = request.get_ref(); + trace!("Got consensus states request: {:?}", request_ref); + let client_id = ClientId::from_str(request_ref.client_id.as_str())?; let consensus_states = self.ibc_context.consensus_states(&client_id)?; @@ -194,10 +196,10 @@ where &self, request: Request, ) -> Result, Status> { - trace!("Got consensus state heights request: {:?}", request); - let request_ref = request.get_ref(); + trace!("Got consensus state heights request: {:?}", request_ref); + let client_id = ClientId::from_str(request_ref.client_id.as_str())?; let consensus_state_heights = self.ibc_context.consensus_state_heights(&client_id)?; @@ -215,10 +217,10 @@ where &self, request: Request, ) -> Result, Status> { - trace!("Got client status request: {:?}", request); - let request_ref = request.get_ref(); + trace!("Got client status request: {:?}", request_ref); + let client_id = ClientId::from_str(request_ref.client_id.as_str())?; let client_status = self.ibc_context.client_status(&client_id)?; @@ -232,7 +234,9 @@ where &self, request: Request, ) -> Result, Status> { - trace!("Got client params request: {:?}", request); + let request_ref = request.get_ref(); + + trace!("Got client params request: {:?}", request_ref); Ok(Response::new(QueryClientParamsResponse { params: Some(ClientParams { @@ -250,7 +254,9 @@ where &self, request: Request, ) -> Result, Status> { - trace!("Got upgraded client state request: {:?}", request); + let request_ref = request.get_ref(); + + trace!("Got upgraded client state request: {:?}", request_ref); let plan = self .upgrade_context @@ -275,7 +281,9 @@ where &self, request: Request, ) -> Result, Status> { - trace!("Got upgraded consensus state request: {:?}", request); + let request_ref = request.get_ref(); + + trace!("Got upgraded consensus state request: {:?}", request_ref); let plan = self .upgrade_context diff --git a/crates/ibc/src/services/connection.rs b/crates/ibc/src/services/connection.rs index c6b912e9c..bc311f74a 100644 --- a/crates/ibc/src/services/connection.rs +++ b/crates/ibc/src/services/connection.rs @@ -66,6 +66,8 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); + trace!("Got connection request: {:?}", request_ref); + let connection_id = ConnectionId::from_str(request_ref.connection_id.as_str())?; let connection_end = self.ibc_context.connection_end(&connection_id)?; @@ -96,7 +98,9 @@ where &self, request: Request, ) -> Result, Status> { - trace!("Got connections request: {:?}", request); + let request_ref = request.get_ref(); + + trace!("Got connections request: {:?}", request_ref); let connections = self.ibc_context.connection_ends()?; @@ -111,7 +115,9 @@ where &self, request: Request, ) -> Result, Status> { - trace!("Got client connections request: {:?}", request); + let request_ref = request.get_ref(); + + trace!("Got client connections request: {:?}", request_ref); let request_ref = request.get_ref(); @@ -147,6 +153,8 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); + trace!("Got connection client state request: {:?}", request_ref); + let connection_id = ConnectionId::from_str(request_ref.connection_id.as_str())?; let connection_end = self.ibc_context.connection_end(&connection_id)?; @@ -184,6 +192,8 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); + trace!("Got connection consensus state request: {:?}", request_ref); + let connection_id = ConnectionId::from_str(request_ref.connection_id.as_str())?; let connection_end = self.ibc_context.connection_end(&connection_id)?; @@ -219,7 +229,9 @@ where &self, request: Request, ) -> Result, Status> { - trace!("Got connection params request: {:?}", request); + let request_ref = request.get_ref(); + + trace!("Got connection params request: {:?}", request_ref); Ok(Response::new(QueryConnectionParamsResponse { params: Some(ConnectionParams { From b3961e4f26546123ac13a361ef5d5118b3630b6e Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 7 Sep 2023 12:47:46 +0200 Subject: [PATCH 34/58] remove grpc from default features --- crates/ibc/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/ibc/Cargo.toml b/crates/ibc/Cargo.toml index a90fcf1a5..be6e1dfae 100644 --- a/crates/ibc/Cargo.toml +++ b/crates/ibc/Cargo.toml @@ -34,7 +34,6 @@ std = [ "primitive-types/std", "tendermint/clock", "tendermint/std", - "grpc", ] parity-scale-codec = ["dep:parity-scale-codec", "dep:scale-info", "ibc-proto/parity-scale-codec"] borsh = ["dep:borsh", "ibc-proto/borsh"] From 576a7541c995b2a7e80ab6f447fed401df320496 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 7 Sep 2023 12:49:40 +0200 Subject: [PATCH 35/58] mv grpc feature gated code under service --- crates/ibc/src/core/context.rs | 99 ---------------------- crates/ibc/src/services/core/context.rs | 104 ++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 99 deletions(-) create mode 100644 crates/ibc/src/services/core/context.rs diff --git a/crates/ibc/src/core/context.rs b/crates/ibc/src/core/context.rs index 09e75469e..d886a2aa9 100644 --- a/crates/ibc/src/core/context.rs +++ b/crates/ibc/src/core/context.rs @@ -34,14 +34,6 @@ use super::ics02_client::consensus_state::ConsensusState; use super::ics02_client::ClientExecutionContext; use super::ics24_host::identifier::PortId; -#[cfg(feature = "grpc")] -use crate::core::{ - ics02_client::{client_state::Status, client_type::ClientType}, - ics03_connection::connection::IdentifiedConnectionEnd, - ics04_channel::channel::IdentifiedChannelEnd, - ics24_host::path::Path, -}; - /// Top-level error #[derive(Debug, Display, From)] pub enum ContextError { @@ -251,97 +243,6 @@ pub trait ValidationContext { fn validate_message_signer(&self, signer: &Signer) -> Result<(), ContextError>; } -/// Context to be implemented by the host to provide proofs in gRPC query responses -/// -/// Trait used for the [`gRPC query services`](crate::services). -#[cfg(feature = "grpc")] -pub trait ProvableContext { - /// Returns the proof for the given path at the given height. - /// As this is in the context of IBC, the path is expected to be an [`IbcPath`](Path). - fn get_proof(&self, height: Height, path: &Path) -> Option>; -} - -/// Context to be implemented by the host that provides gRPC query services. -/// -/// Trait used for the [`gRPC query services`](crate::services). -#[cfg(feature = "grpc")] -pub trait QueryContext: ProvableContext + ValidationContext { - // Client queries - - /// Returns the list of all clients. - fn client_states( - &self, - ) -> Result::AnyClientState)>, ContextError>; - - /// Returns the list of all consensus states for the given client. - fn consensus_states( - &self, - client_id: &ClientId, - ) -> Result::AnyConsensusState)>, ContextError>; - - /// Returns the list of all heights at which consensus states for the given client are. - fn consensus_state_heights(&self, client_id: &ClientId) -> Result, ContextError>; - - /// Returns the status of the given client. - fn client_status(&self, client_id: &ClientId) -> Result; - - /// Returns the list of supported client types. - fn allowed_clients(&self) -> Vec; - - // Connection queries - - /// Returns the list of all connection ends. - fn connection_ends(&self) -> Result, ContextError>; - - /// Returns the list of all connection ids of the given client. - fn client_connection_ends( - &self, - client_id: &ClientId, - ) -> Result, ContextError>; - - // Channel queries - - /// Returns the list of all channel ends. - fn channel_ends(&self) -> Result, ContextError>; - - /// Returns the list of all channel ends of the given connection. - fn connection_channel_ends( - &self, - connection_id: &ConnectionId, - ) -> Result, ContextError>; - - // Packet queries - - /// Returns the list of all packet commitments for the given channel end. - fn packet_commitments( - &self, - channel_end_path: &ChannelEndPath, - ) -> Result, ContextError>; - - /// Filters the list of packet sequences for the given channel end that are acknowledged. - /// Returns all the packet acknowledgements if `sequences` is empty. - fn packet_acknowledgements( - &self, - channel_end_path: &ChannelEndPath, - sequences: impl ExactSizeIterator, - ) -> Result, ContextError>; - - /// Filters the packet sequences for the given channel end that are not received. - fn unreceived_packets( - &self, - channel_end_path: &ChannelEndPath, - sequences: impl ExactSizeIterator, - ) -> Result, ContextError>; - - /// Filters the list of packet sequences for the given channel end whose acknowledgement is not received. - /// Returns all the unreceived acknowledgements if `sequences` is empty. - fn unreceived_acks( - &self, - channel_end_path: &ChannelEndPath, - sequences: impl ExactSizeIterator, - ) -> Result, ContextError>; -} - /// Context to be implemented by the host that provides all "write-only" methods. /// /// Trait used for the top-level [`execute`](crate::core::execute) and [`dispatch`](crate::core::dispatch) diff --git a/crates/ibc/src/services/core/context.rs b/crates/ibc/src/services/core/context.rs new file mode 100644 index 000000000..341a83a7b --- /dev/null +++ b/crates/ibc/src/services/core/context.rs @@ -0,0 +1,104 @@ +use crate::prelude::*; + +use crate::{ + core::{ + ics02_client::{client_state::Status, client_type::ClientType}, + ics03_connection::connection::IdentifiedConnectionEnd, + ics04_channel::{channel::IdentifiedChannelEnd, packet::Sequence}, + ics24_host::{ + identifier::{ClientId, ConnectionId}, + path::{AckPath, ChannelEndPath, CommitmentPath, Path}, + }, + ContextError, ValidationContext, + }, + Height, +}; + +/// Context to be implemented by the host to provide proofs in gRPC query responses +/// +/// Trait used for the [`gRPC query services`](crate::services). +pub trait ProvableContext { + /// Returns the proof for the given path at the given height. + /// As this is in the context of IBC, the path is expected to be an [`IbcPath`](Path). + fn get_proof(&self, height: Height, path: &Path) -> Option>; +} + +/// Context to be implemented by the host that provides gRPC query services. +/// +/// Trait used for the [`gRPC query services`](crate::services). +pub trait QueryContext: ProvableContext + ValidationContext { + // Client queries + + /// Returns the list of all clients. + fn client_states( + &self, + ) -> Result::AnyClientState)>, ContextError>; + + /// Returns the list of all consensus states for the given client. + fn consensus_states( + &self, + client_id: &ClientId, + ) -> Result::AnyConsensusState)>, ContextError>; + + /// Returns the list of all heights at which consensus states for the given client are. + fn consensus_state_heights(&self, client_id: &ClientId) -> Result, ContextError>; + + /// Returns the status of the given client. + fn client_status(&self, client_id: &ClientId) -> Result; + + /// Returns the list of supported client types. + fn allowed_clients(&self) -> Vec; + + // Connection queries + + /// Returns the list of all connection ends. + fn connection_ends(&self) -> Result, ContextError>; + + /// Returns the list of all connection ids of the given client. + fn client_connection_ends( + &self, + client_id: &ClientId, + ) -> Result, ContextError>; + + // Channel queries + + /// Returns the list of all channel ends. + fn channel_ends(&self) -> Result, ContextError>; + + /// Returns the list of all channel ends of the given connection. + fn connection_channel_ends( + &self, + connection_id: &ConnectionId, + ) -> Result, ContextError>; + + // Packet queries + + /// Returns the list of all packet commitments for the given channel end. + fn packet_commitments( + &self, + channel_end_path: &ChannelEndPath, + ) -> Result, ContextError>; + + /// Filters the list of packet sequences for the given channel end that are acknowledged. + /// Returns all the packet acknowledgements if `sequences` is empty. + fn packet_acknowledgements( + &self, + channel_end_path: &ChannelEndPath, + sequences: impl ExactSizeIterator, + ) -> Result, ContextError>; + + /// Filters the packet sequences for the given channel end that are not received. + fn unreceived_packets( + &self, + channel_end_path: &ChannelEndPath, + sequences: impl ExactSizeIterator, + ) -> Result, ContextError>; + + /// Filters the list of packet sequences for the given channel end whose acknowledgement is not received. + /// Returns all the unreceived acknowledgements if `sequences` is empty. + fn unreceived_acks( + &self, + channel_end_path: &ChannelEndPath, + sequences: impl ExactSizeIterator, + ) -> Result, ContextError>; +} From 3ecad3cc4d5304eefdf6e4d4bf6b51656f486a9c Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 7 Sep 2023 12:50:54 +0200 Subject: [PATCH 36/58] mv files --- crates/ibc/src/services/{ => core}/channel.rs | 33 ++++++++----------- crates/ibc/src/services/{ => core}/client.rs | 18 +++++----- .../ibc/src/services/{ => core}/connection.rs | 17 +++++----- 3 files changed, 32 insertions(+), 36 deletions(-) rename crates/ibc/src/services/{ => core}/channel.rs (96%) rename crates/ibc/src/services/{ => core}/client.rs (96%) rename crates/ibc/src/services/{ => core}/connection.rs (96%) diff --git a/crates/ibc/src/services/channel.rs b/crates/ibc/src/services/core/channel.rs similarity index 96% rename from crates/ibc/src/services/channel.rs rename to crates/ibc/src/services/core/channel.rs index 83bd0db31..774afa01f 100644 --- a/crates/ibc/src/services/channel.rs +++ b/crates/ibc/src/services/core/channel.rs @@ -1,4 +1,3 @@ -use alloc::string::ToString; use ibc_proto::{ google::protobuf::Any, ibc::core::{ @@ -21,6 +20,8 @@ use ibc_proto::{ }, }; +use crate::prelude::*; + use crate::{ core::{ ics04_channel::packet::Sequence, @@ -31,12 +32,12 @@ use crate::{ Path, ReceiptPath, SeqRecvPath, SeqSendPath, }, }, - QueryContext, ValidationContext, + ValidationContext, }, + services::core::context::QueryContext, Height, }; -use core::str::FromStr; use std::boxed::Box; use tonic::{Request, Response, Status}; use tracing::trace; @@ -90,7 +91,7 @@ where .ibc_context .get_proof(current_height, &Path::ChannelEnd(channel_end_path)) .ok_or_else(|| { - Status::not_found(std::format!( + Status::not_found(format!( "Channel end proof not found for channel {}", channel_id )) @@ -160,10 +161,7 @@ where .first() .map(|connection_id| self.ibc_context.connection_end(connection_id)) .ok_or_else(|| { - Status::not_found(std::format!( - "Channel {} has no connection hops", - channel_id - )) + Status::not_found(format!("Channel {} has no connection hops", channel_id)) })??; let client_state = self.ibc_context.client_state(connection_end.client_id())?; @@ -177,7 +175,7 @@ where &Path::ClientState(ClientStatePath::new(connection_end.client_id())), ) .ok_or_else(|| { - Status::not_found(std::format!( + Status::not_found(format!( "Client state proof not found for client {}", connection_end.client_id() )) @@ -217,10 +215,7 @@ where .first() .map(|connection_id| self.ibc_context.connection_end(connection_id)) .ok_or_else(|| { - Status::not_found(std::format!( - "Channel {} has no connection hops", - channel_id - )) + Status::not_found(format!("Channel {} has no connection hops", channel_id)) })??; let consensus_path = ClientConsensusStatePath::new(connection_end.client_id(), &height); @@ -233,7 +228,7 @@ where .ibc_context .get_proof(current_height, &Path::ClientConsensusState(consensus_path)) .ok_or_else(|| { - Status::not_found(std::format!( + Status::not_found(format!( "Consensus state proof not found for client {}", connection_end.client_id() )) @@ -271,7 +266,7 @@ where .ibc_context .get_proof(current_height, &Path::Commitment(commitment_path)) .ok_or_else(|| { - Status::not_found(std::format!( + Status::not_found(format!( "Packet commitment proof not found for channel {}", channel_id )) @@ -347,7 +342,7 @@ where .ibc_context .get_proof(current_height, &Path::Receipt(receipt_path)) .ok_or_else(|| { - Status::not_found(std::format!( + Status::not_found(format!( "Packet receipt proof not found for channel {}", channel_id )) @@ -386,7 +381,7 @@ where .ibc_context .get_proof(current_height, &Path::Ack(acknowledgement_path)) .ok_or_else(|| { - Status::not_found(std::format!( + Status::not_found(format!( "Packet acknowledgement proof not found for channel {}", channel_id )) @@ -528,7 +523,7 @@ where .ibc_context .get_proof(current_height, &Path::SeqRecv(next_seq_recv_path)) .ok_or_else(|| { - Status::not_found(std::format!( + Status::not_found(format!( "Next sequence receive proof not found for channel {}", channel_id )) @@ -565,7 +560,7 @@ where .ibc_context .get_proof(current_height, &Path::SeqSend(next_seq_send_path)) .ok_or_else(|| { - Status::not_found(std::format!( + Status::not_found(format!( "Next sequence send proof not found for channel {}", channel_id )) diff --git a/crates/ibc/src/services/client.rs b/crates/ibc/src/services/core/client.rs similarity index 96% rename from crates/ibc/src/services/client.rs rename to crates/ibc/src/services/core/client.rs index 00860486e..e963197a8 100644 --- a/crates/ibc/src/services/client.rs +++ b/crates/ibc/src/services/core/client.rs @@ -1,4 +1,3 @@ -use alloc::string::ToString; use ibc_proto::{ google::protobuf::Any, ibc::core::client::v1::{ @@ -14,6 +13,8 @@ use ibc_proto::{ }, }; +use crate::prelude::*; + use crate::{ core::{ ics02_client::error::ClientError, @@ -21,9 +22,10 @@ use crate::{ identifier::ClientId, path::{ClientConsensusStatePath, ClientStatePath, Path, UpgradeClientPath}, }, - ContextError, QueryContext, ValidationContext, + ContextError, ValidationContext, }, hosts::tendermint::upgrade_proposal::UpgradeValidationContext, + services::core::context::QueryContext, Height, }; @@ -92,10 +94,9 @@ where &Path::ClientState(ClientStatePath::new(&client_id)), ) .ok_or_else(|| { - Status::not_found(std::format!( + Status::not_found(format!( "Client state not found for client {} at height {}", - client_id, - current_height + client_id, current_height )) })?; @@ -154,10 +155,9 @@ where &Path::ClientConsensusState(ClientConsensusStatePath::new(&client_id, &height)), ) .ok_or_else(|| { - Status::not_found(std::format!( + Status::not_found(format!( "Consensus state not found for client {} at height {}", - client_id, - height + client_id, height )) })?; @@ -226,7 +226,7 @@ where let client_status = self.ibc_context.client_status(&client_id)?; Ok(Response::new(QueryClientStatusResponse { - status: std::format!("{}", client_status), + status: format!("{}", client_status), })) } diff --git a/crates/ibc/src/services/connection.rs b/crates/ibc/src/services/core/connection.rs similarity index 96% rename from crates/ibc/src/services/connection.rs rename to crates/ibc/src/services/core/connection.rs index bc311f74a..0d6c8c93a 100644 --- a/crates/ibc/src/services/connection.rs +++ b/crates/ibc/src/services/core/connection.rs @@ -1,4 +1,3 @@ -use alloc::string::ToString; use ibc_proto::{ google::protobuf::Any, ibc::core::{ @@ -23,12 +22,14 @@ use crate::{ Path, }, }, - QueryContext, ValidationContext, + ValidationContext, }, + services::core::context::QueryContext, Height, }; -use core::str::FromStr; +use crate::prelude::*; + use std::boxed::Box; use tonic::{Request, Response, Status}; use tracing::trace; @@ -81,7 +82,7 @@ where &Path::Connection(ConnectionPath::new(&connection_id)), ) .ok_or_else(|| { - Status::not_found(std::format!( + Status::not_found(format!( "Proof not found for connection path {}", connection_id.as_str() )) @@ -127,14 +128,14 @@ where let current_height = self.ibc_context.host_height()?; - let proof: alloc::vec::Vec = self + let proof: Vec = self .ibc_context .get_proof( current_height, &Path::ClientConnection(ClientConnectionPath::new(&client_id)), ) .ok_or_else(|| { - Status::not_found(std::format!( + Status::not_found(format!( "Proof not found for client connection path {}", client_id.as_str() )) @@ -170,7 +171,7 @@ where &Path::ClientState(ClientStatePath::new(connection_end.client_id())), ) .ok_or_else(|| { - Status::not_found(std::format!( + Status::not_found(format!( "Proof not found for client state path {}", connection_end.client_id().as_str() )) @@ -211,7 +212,7 @@ where .ibc_context .get_proof(current_height, &Path::ClientConsensusState(consensus_path)) .ok_or_else(|| { - Status::not_found(std::format!( + Status::not_found(format!( "Proof not found for consensus state path {}", connection_end.client_id().as_str() )) From c6ea817f63d56401110224de86793689487ecaf2 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 7 Sep 2023 12:51:12 +0200 Subject: [PATCH 37/58] update mod files --- crates/ibc/src/services/core/mod.rs | 8 ++++++++ crates/ibc/src/services/mod.rs | 13 ++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) create mode 100644 crates/ibc/src/services/core/mod.rs diff --git a/crates/ibc/src/services/core/mod.rs b/crates/ibc/src/services/core/mod.rs new file mode 100644 index 000000000..4e896761e --- /dev/null +++ b/crates/ibc/src/services/core/mod.rs @@ -0,0 +1,8 @@ +pub mod channel; +pub mod client; +pub mod connection; +pub mod context; + +pub use channel::ChannelQueryService; +pub use client::ClientQueryService; +pub use connection::ConnectionQueryService; diff --git a/crates/ibc/src/services/mod.rs b/crates/ibc/src/services/mod.rs index 12a330c17..ecb65bd44 100644 --- a/crates/ibc/src/services/mod.rs +++ b/crates/ibc/src/services/mod.rs @@ -15,8 +15,9 @@ //! client::v1::query_server::QueryServer as ClientQueryServer, //! connection::v1::query_server::QueryServer as ConnectionQueryServer, //! } -//! use ibc::core::{ProvableContext, QueryContext, ValidationContext}; +//! use ibc::core::ValidationContext; //! use ibc::hosts::tendermint::upgrade_proposal::UpgradeValidationContext; +//! use ibc::services::core::{ProvableContext, QueryContext}; //! use ibc::services::{ChannelQueryService, ClientQueryService, ConnectionQueryService}; //! //! struct Ibc; @@ -41,11 +42,5 @@ //! .serve(addr); //! ``` -mod channel; -mod client; -mod connection; -mod error; - -pub use channel::ChannelQueryService; -pub use client::ClientQueryService; -pub use connection::ConnectionQueryService; +pub mod core; +pub mod error; From 3dab9ed87460a46b8b8f7c56b3b8e487e407ddc3 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 7 Sep 2023 12:52:08 +0200 Subject: [PATCH 38/58] update prelude --- crates/ibc/src/prelude.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/ibc/src/prelude.rs b/crates/ibc/src/prelude.rs index 9ff42a989..803d1fad0 100644 --- a/crates/ibc/src/prelude.rs +++ b/crates/ibc/src/prelude.rs @@ -4,6 +4,7 @@ pub use core::prelude::v1::*; // https://doc.rust-lang.org/src/alloc/prelude/v1.rs.html pub use alloc::borrow::ToOwned; pub use alloc::boxed::Box; +pub use alloc::str::FromStr; pub use alloc::string::{String, ToString}; pub use alloc::vec::Vec; From d6d4a9a030b2bc5a9f58be17ccb9852b5c8d33f2 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 7 Sep 2023 13:01:33 +0200 Subject: [PATCH 39/58] happy cargo doc --- crates/ibc/src/services/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/ibc/src/services/mod.rs b/crates/ibc/src/services/mod.rs index ecb65bd44..6658ead42 100644 --- a/crates/ibc/src/services/mod.rs +++ b/crates/ibc/src/services/mod.rs @@ -3,8 +3,8 @@ //! The provided structs includes blanket implementation of their corresponding gRPC service traits, //! if the host implements the following _context_ traits. //! - [`ValidationContext`](crate::core::ValidationContext) -//! - [`ProvableContext`](crate::core::ProvableContext) -//! - [`QueryContext`](crate::core::QueryContext) +//! - [`ProvableContext`](crate::services::core::context::ProvableContext) +//! - [`QueryContext`](crate::services::core::context::QueryContext) //! - [`UpgradeValidationContext`](crate::hosts::tendermint::upgrade_proposal::UpgradeValidationContext) //! - Only for [`ClientQuery::upgraded_client_state`](ibc_proto::ibc::core::client::v1::query_server::Query::upgraded_client_state) and [`ClientQuery::upgraded_client_state`](ibc_proto::ibc::core::client::v1::query_server::Query::upgraded_consensus_state) //! From 7725e537376bc125dbe041d7b7c4a9f162ad6f32 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 7 Sep 2023 13:13:21 +0200 Subject: [PATCH 40/58] happy cargo fmt --- crates/ibc/src/services/core/channel.rs | 66 +++++++++------------- crates/ibc/src/services/core/client.rs | 55 ++++++++---------- crates/ibc/src/services/core/connection.rs | 50 +++++++--------- crates/ibc/src/services/core/context.rs | 23 +++----- crates/ibc/src/services/error.rs | 4 +- 5 files changed, 82 insertions(+), 116 deletions(-) diff --git a/crates/ibc/src/services/core/channel.rs b/crates/ibc/src/services/core/channel.rs index 774afa01f..11feb2249 100644 --- a/crates/ibc/src/services/core/channel.rs +++ b/crates/ibc/src/services/core/channel.rs @@ -1,47 +1,35 @@ -use ibc_proto::{ - google::protobuf::Any, - ibc::core::{ - channel::v1::{ - query_server::Query as ChannelQuery, PacketState, QueryChannelClientStateRequest, - QueryChannelClientStateResponse, QueryChannelConsensusStateRequest, - QueryChannelConsensusStateResponse, QueryChannelRequest, QueryChannelResponse, - QueryChannelsRequest, QueryChannelsResponse, QueryConnectionChannelsRequest, - QueryConnectionChannelsResponse, QueryNextSequenceReceiveRequest, - QueryNextSequenceReceiveResponse, QueryNextSequenceSendRequest, - QueryNextSequenceSendResponse, QueryPacketAcknowledgementRequest, - QueryPacketAcknowledgementResponse, QueryPacketAcknowledgementsRequest, - QueryPacketAcknowledgementsResponse, QueryPacketCommitmentRequest, - QueryPacketCommitmentResponse, QueryPacketCommitmentsRequest, - QueryPacketCommitmentsResponse, QueryPacketReceiptRequest, QueryPacketReceiptResponse, - QueryUnreceivedAcksRequest, QueryUnreceivedAcksResponse, QueryUnreceivedPacketsRequest, - QueryUnreceivedPacketsResponse, - }, - client::v1::IdentifiedClientState, - }, -}; - -use crate::prelude::*; +use std::boxed::Box; -use crate::{ - core::{ - ics04_channel::packet::Sequence, - ics24_host::{ - identifier::{ChannelId, ConnectionId, PortId}, - path::{ - AckPath, ChannelEndPath, ClientConsensusStatePath, ClientStatePath, CommitmentPath, - Path, ReceiptPath, SeqRecvPath, SeqSendPath, - }, - }, - ValidationContext, - }, - services::core::context::QueryContext, - Height, +use ibc_proto::google::protobuf::Any; +use ibc_proto::ibc::core::channel::v1::query_server::Query as ChannelQuery; +use ibc_proto::ibc::core::channel::v1::{ + PacketState, QueryChannelClientStateRequest, QueryChannelClientStateResponse, + QueryChannelConsensusStateRequest, QueryChannelConsensusStateResponse, QueryChannelRequest, + QueryChannelResponse, QueryChannelsRequest, QueryChannelsResponse, + QueryConnectionChannelsRequest, QueryConnectionChannelsResponse, + QueryNextSequenceReceiveRequest, QueryNextSequenceReceiveResponse, + QueryNextSequenceSendRequest, QueryNextSequenceSendResponse, QueryPacketAcknowledgementRequest, + QueryPacketAcknowledgementResponse, QueryPacketAcknowledgementsRequest, + QueryPacketAcknowledgementsResponse, QueryPacketCommitmentRequest, + QueryPacketCommitmentResponse, QueryPacketCommitmentsRequest, QueryPacketCommitmentsResponse, + QueryPacketReceiptRequest, QueryPacketReceiptResponse, QueryUnreceivedAcksRequest, + QueryUnreceivedAcksResponse, QueryUnreceivedPacketsRequest, QueryUnreceivedPacketsResponse, }; - -use std::boxed::Box; +use ibc_proto::ibc::core::client::v1::IdentifiedClientState; use tonic::{Request, Response, Status}; use tracing::trace; +use crate::core::ics04_channel::packet::Sequence; +use crate::core::ics24_host::identifier::{ChannelId, ConnectionId, PortId}; +use crate::core::ics24_host::path::{ + AckPath, ChannelEndPath, ClientConsensusStatePath, ClientStatePath, CommitmentPath, Path, + ReceiptPath, SeqRecvPath, SeqSendPath, +}; +use crate::core::ValidationContext; +use crate::prelude::*; +use crate::services::core::context::QueryContext; +use crate::Height; + pub struct ChannelQueryService where I: QueryContext + Send + Sync + 'static, diff --git a/crates/ibc/src/services/core/client.rs b/crates/ibc/src/services/core/client.rs index e963197a8..a90ec48f7 100644 --- a/crates/ibc/src/services/core/client.rs +++ b/crates/ibc/src/services/core/client.rs @@ -1,39 +1,32 @@ -use ibc_proto::{ - google::protobuf::Any, - ibc::core::client::v1::{ - query_server::Query as ClientQuery, ConsensusStateWithHeight, IdentifiedClientState, - Params as ClientParams, QueryClientParamsRequest, QueryClientParamsResponse, - QueryClientStateRequest, QueryClientStateResponse, QueryClientStatesRequest, - QueryClientStatesResponse, QueryClientStatusRequest, QueryClientStatusResponse, - QueryConsensusStateHeightsRequest, QueryConsensusStateHeightsResponse, - QueryConsensusStateRequest, QueryConsensusStateResponse, QueryConsensusStatesRequest, - QueryConsensusStatesResponse, QueryUpgradedClientStateRequest, - QueryUpgradedClientStateResponse, QueryUpgradedConsensusStateRequest, - QueryUpgradedConsensusStateResponse, - }, -}; - -use crate::prelude::*; - -use crate::{ - core::{ - ics02_client::error::ClientError, - ics24_host::{ - identifier::ClientId, - path::{ClientConsensusStatePath, ClientStatePath, Path, UpgradeClientPath}, - }, - ContextError, ValidationContext, - }, - hosts::tendermint::upgrade_proposal::UpgradeValidationContext, - services::core::context::QueryContext, - Height, -}; - use core::str::FromStr; use std::boxed::Box; + +use ibc_proto::google::protobuf::Any; +use ibc_proto::ibc::core::client::v1::query_server::Query as ClientQuery; +use ibc_proto::ibc::core::client::v1::{ + ConsensusStateWithHeight, IdentifiedClientState, Params as ClientParams, + QueryClientParamsRequest, QueryClientParamsResponse, QueryClientStateRequest, + QueryClientStateResponse, QueryClientStatesRequest, QueryClientStatesResponse, + QueryClientStatusRequest, QueryClientStatusResponse, QueryConsensusStateHeightsRequest, + QueryConsensusStateHeightsResponse, QueryConsensusStateRequest, QueryConsensusStateResponse, + QueryConsensusStatesRequest, QueryConsensusStatesResponse, QueryUpgradedClientStateRequest, + QueryUpgradedClientStateResponse, QueryUpgradedConsensusStateRequest, + QueryUpgradedConsensusStateResponse, +}; use tonic::{Request, Response, Status}; use tracing::trace; +use crate::core::ics02_client::error::ClientError; +use crate::core::ics24_host::identifier::ClientId; +use crate::core::ics24_host::path::{ + ClientConsensusStatePath, ClientStatePath, Path, UpgradeClientPath, +}; +use crate::core::{ContextError, ValidationContext}; +use crate::hosts::tendermint::upgrade_proposal::UpgradeValidationContext; +use crate::prelude::*; +use crate::services::core::context::QueryContext; +use crate::Height; + pub struct ClientQueryService where I: QueryContext + Send + Sync + 'static, diff --git a/crates/ibc/src/services/core/connection.rs b/crates/ibc/src/services/core/connection.rs index 0d6c8c93a..97beb6c60 100644 --- a/crates/ibc/src/services/core/connection.rs +++ b/crates/ibc/src/services/core/connection.rs @@ -1,39 +1,27 @@ -use ibc_proto::{ - google::protobuf::Any, - ibc::core::{ - client::v1::IdentifiedClientState, - connection::v1::{ - query_server::Query as ConnectionQuery, Params as ConnectionParams, - QueryClientConnectionsRequest, QueryClientConnectionsResponse, - QueryConnectionClientStateRequest, QueryConnectionClientStateResponse, - QueryConnectionConsensusStateRequest, QueryConnectionConsensusStateResponse, - QueryConnectionParamsRequest, QueryConnectionParamsResponse, QueryConnectionRequest, - QueryConnectionResponse, QueryConnectionsRequest, QueryConnectionsResponse, - }, - }, -}; +use std::boxed::Box; -use crate::{ - core::{ - ics24_host::{ - identifier::{ClientId, ConnectionId}, - path::{ - ClientConnectionPath, ClientConsensusStatePath, ClientStatePath, ConnectionPath, - Path, - }, - }, - ValidationContext, - }, - services::core::context::QueryContext, - Height, +use ibc_proto::google::protobuf::Any; +use ibc_proto::ibc::core::client::v1::IdentifiedClientState; +use ibc_proto::ibc::core::connection::v1::query_server::Query as ConnectionQuery; +use ibc_proto::ibc::core::connection::v1::{ + Params as ConnectionParams, QueryClientConnectionsRequest, QueryClientConnectionsResponse, + QueryConnectionClientStateRequest, QueryConnectionClientStateResponse, + QueryConnectionConsensusStateRequest, QueryConnectionConsensusStateResponse, + QueryConnectionParamsRequest, QueryConnectionParamsResponse, QueryConnectionRequest, + QueryConnectionResponse, QueryConnectionsRequest, QueryConnectionsResponse, }; - -use crate::prelude::*; - -use std::boxed::Box; use tonic::{Request, Response, Status}; use tracing::trace; +use crate::core::ics24_host::identifier::{ClientId, ConnectionId}; +use crate::core::ics24_host::path::{ + ClientConnectionPath, ClientConsensusStatePath, ClientStatePath, ConnectionPath, Path, +}; +use crate::core::ValidationContext; +use crate::prelude::*; +use crate::services::core::context::QueryContext; +use crate::Height; + pub struct ConnectionQueryService where I: QueryContext + Send + Sync + 'static, diff --git a/crates/ibc/src/services/core/context.rs b/crates/ibc/src/services/core/context.rs index 341a83a7b..56911beaa 100644 --- a/crates/ibc/src/services/core/context.rs +++ b/crates/ibc/src/services/core/context.rs @@ -1,18 +1,13 @@ +use crate::core::ics02_client::client_state::Status; +use crate::core::ics02_client::client_type::ClientType; +use crate::core::ics03_connection::connection::IdentifiedConnectionEnd; +use crate::core::ics04_channel::channel::IdentifiedChannelEnd; +use crate::core::ics04_channel::packet::Sequence; +use crate::core::ics24_host::identifier::{ClientId, ConnectionId}; +use crate::core::ics24_host::path::{AckPath, ChannelEndPath, CommitmentPath, Path}; +use crate::core::{ContextError, ValidationContext}; use crate::prelude::*; - -use crate::{ - core::{ - ics02_client::{client_state::Status, client_type::ClientType}, - ics03_connection::connection::IdentifiedConnectionEnd, - ics04_channel::{channel::IdentifiedChannelEnd, packet::Sequence}, - ics24_host::{ - identifier::{ClientId, ConnectionId}, - path::{AckPath, ChannelEndPath, CommitmentPath, Path}, - }, - ContextError, ValidationContext, - }, - Height, -}; +use crate::Height; /// Context to be implemented by the host to provide proofs in gRPC query responses /// diff --git a/crates/ibc/src/services/error.rs b/crates/ibc/src/services/error.rs index f458dc288..433a5e321 100644 --- a/crates/ibc/src/services/error.rs +++ b/crates/ibc/src/services/error.rs @@ -1,8 +1,10 @@ use alloc::string::ToString; -use crate::core::{ics24_host::identifier::IdentifierError, ContextError}; use tonic::Status; +use crate::core::ics24_host::identifier::IdentifierError; +use crate::core::ContextError; + impl From for Status { fn from(err: IdentifierError) -> Self { Status::invalid_argument(err.to_string()) From e94deaa511aaab53b3c6f3c2b2be05b73086ed7d Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 7 Sep 2023 13:45:21 +0200 Subject: [PATCH 41/58] support latest_height flag --- crates/ibc/src/services/core/client.rs | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/crates/ibc/src/services/core/client.rs b/crates/ibc/src/services/core/client.rs index a90ec48f7..3d8d91b63 100644 --- a/crates/ibc/src/services/core/client.rs +++ b/crates/ibc/src/services/core/client.rs @@ -132,12 +132,26 @@ where let client_id = ClientId::from_str(request_ref.client_id.as_str())?; - let height = Height::new(request_ref.revision_number, request_ref.revision_height) - .map_err(|e| Status::invalid_argument(e.to_string()))?; - - let consensus_state = self - .ibc_context - .consensus_state(&ClientConsensusStatePath::new(&client_id, &height))?; + let (height, consensus_state) = if request_ref.latest_height { + self.ibc_context + .consensus_states(&client_id)? + .into_iter() + .max_by_key(|(h, _)| *h) + .ok_or_else(|| { + Status::not_found(format!( + "Consensus state not found for client {}", + client_id + )) + })? + } else { + let height = Height::new(request_ref.revision_number, request_ref.revision_height) + .map_err(|e| Status::invalid_argument(e.to_string()))?; + let consensus_state = self + .ibc_context + .consensus_state(&ClientConsensusStatePath::new(&client_id, &height))?; + + (height, consensus_state) + }; let current_height = self.ibc_context.host_height()?; From 7b62cbb0a0ced611d527d6ad95f1142d08b8df93 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 7 Sep 2023 15:04:37 +0200 Subject: [PATCH 42/58] rm redundant trait method --- crates/ibc/src/services/core/channel.rs | 16 ++++++++++++++-- crates/ibc/src/services/core/context.rs | 6 ------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/crates/ibc/src/services/core/channel.rs b/crates/ibc/src/services/core/channel.rs index 11feb2249..1cedea3ef 100644 --- a/crates/ibc/src/services/core/channel.rs +++ b/crates/ibc/src/services/core/channel.rs @@ -119,10 +119,22 @@ where let connection_id = ConnectionId::from_str(request_ref.connection.as_str())?; - let channel_ends = self.ibc_context.connection_channel_ends(&connection_id)?; + let all_channel_ends = self.ibc_context.channel_ends()?; + + let connection_channel_ends = all_channel_ends + .into_iter() + .filter(|channel_end| { + channel_end + .channel_end + .connection_hops() + .iter() + .any(|connection_hop| connection_hop == &connection_id) + }) + .map(Into::into) + .collect(); Ok(Response::new(QueryConnectionChannelsResponse { - channels: channel_ends.into_iter().map(Into::into).collect(), + channels: connection_channel_ends, pagination: None, height: Some(self.ibc_context.host_height()?.into()), })) diff --git a/crates/ibc/src/services/core/context.rs b/crates/ibc/src/services/core/context.rs index 56911beaa..6cc18b59e 100644 --- a/crates/ibc/src/services/core/context.rs +++ b/crates/ibc/src/services/core/context.rs @@ -60,12 +60,6 @@ pub trait QueryContext: ProvableContext + ValidationContext { /// Returns the list of all channel ends. fn channel_ends(&self) -> Result, ContextError>; - /// Returns the list of all channel ends of the given connection. - fn connection_channel_ends( - &self, - connection_id: &ConnectionId, - ) -> Result, ContextError>; - // Packet queries /// Returns the list of all packet commitments for the given channel end. From db0d453ffb6170923dca8c52dbf34e209f9c9ec7 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Fri, 8 Sep 2023 12:58:15 +0200 Subject: [PATCH 43/58] comment on grpc feature --- crates/ibc/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ibc/Cargo.toml b/crates/ibc/Cargo.toml index be6e1dfae..f5267c1d1 100644 --- a/crates/ibc/Cargo.toml +++ b/crates/ibc/Cargo.toml @@ -37,7 +37,7 @@ std = [ ] parity-scale-codec = ["dep:parity-scale-codec", "dep:scale-info", "ibc-proto/parity-scale-codec"] borsh = ["dep:borsh", "ibc-proto/borsh"] - +# includes gRPC services for IBC core grpc = ["dep:tonic", "ibc-proto/server"] # This feature is required for token transfer (ICS-20) From 5546eb7d9aa0ab9f9738a8b5fd7c669e79b99e3d Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Fri, 8 Sep 2023 13:05:00 +0200 Subject: [PATCH 44/58] todo comment for pagination --- crates/ibc/src/services/core/channel.rs | 14 ++++++++++---- crates/ibc/src/services/core/client.rs | 5 +++++ crates/ibc/src/services/core/connection.rs | 5 ++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/crates/ibc/src/services/core/channel.rs b/crates/ibc/src/services/core/channel.rs index 1cedea3ef..7972e50d8 100644 --- a/crates/ibc/src/services/core/channel.rs +++ b/crates/ibc/src/services/core/channel.rs @@ -30,6 +30,8 @@ use crate::prelude::*; use crate::services::core::context::QueryContext; use crate::Height; +// TODO(rano): currently the services don't support pagination, so we return all the results. + pub struct ChannelQueryService where I: QueryContext + Send + Sync + 'static, @@ -104,8 +106,9 @@ where Ok(Response::new(QueryChannelsResponse { channels: channel_ends.into_iter().map(Into::into).collect(), - pagination: None, height: Some(self.ibc_context.host_height()?.into()), + // no support for pagination yet + pagination: None, })) } @@ -135,8 +138,9 @@ where Ok(Response::new(QueryConnectionChannelsResponse { channels: connection_channel_ends, - pagination: None, height: Some(self.ibc_context.host_height()?.into()), + // no support for pagination yet + pagination: None, })) } @@ -311,8 +315,9 @@ where Ok(Response::new(QueryPacketCommitmentsResponse { commitments, - pagination: None, height: Some(self.ibc_context.host_height()?.into()), + // no support for pagination yet + pagination: None, })) } @@ -433,8 +438,9 @@ where Ok(Response::new(QueryPacketAcknowledgementsResponse { acknowledgements, - pagination: None, height: Some(self.ibc_context.host_height()?.into()), + // no support for pagination yet + pagination: None, })) } diff --git a/crates/ibc/src/services/core/client.rs b/crates/ibc/src/services/core/client.rs index 3d8d91b63..46bf09751 100644 --- a/crates/ibc/src/services/core/client.rs +++ b/crates/ibc/src/services/core/client.rs @@ -27,6 +27,8 @@ use crate::prelude::*; use crate::services::core::context::QueryContext; use crate::Height; +// TODO(rano): currently the services don't support pagination, so we return all the results. + pub struct ClientQueryService where I: QueryContext + Send + Sync + 'static, @@ -118,6 +120,7 @@ where client_state: Some(state.into()), }) .collect(), + // no support for pagination yet pagination: None, })) } @@ -195,6 +198,7 @@ where consensus_state: Some(state.into()), }) .collect(), + // no support for pagination yet pagination: None, })) } @@ -216,6 +220,7 @@ where .into_iter() .map(|height| height.into()) .collect(), + // no support for pagination yet pagination: None, })) } diff --git a/crates/ibc/src/services/core/connection.rs b/crates/ibc/src/services/core/connection.rs index 97beb6c60..d60df59ad 100644 --- a/crates/ibc/src/services/core/connection.rs +++ b/crates/ibc/src/services/core/connection.rs @@ -22,6 +22,8 @@ use crate::prelude::*; use crate::services::core::context::QueryContext; use crate::Height; +// TODO(rano): currently the services don't support pagination, so we return all the results. + pub struct ConnectionQueryService where I: QueryContext + Send + Sync + 'static, @@ -95,8 +97,9 @@ where Ok(Response::new(QueryConnectionsResponse { connections: connections.into_iter().map(Into::into).collect(), - pagination: None, height: Some(self.ibc_context.host_height()?.into()), + // no support for pagination yet + pagination: None, })) } From ddf40d241d69d1aee8f9df88af3587ca074032f3 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Fri, 8 Sep 2023 13:10:39 +0200 Subject: [PATCH 45/58] update client_status query --- crates/ibc/src/services/core/client.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/ibc/src/services/core/client.rs b/crates/ibc/src/services/core/client.rs index 46bf09751..51ffcf8cc 100644 --- a/crates/ibc/src/services/core/client.rs +++ b/crates/ibc/src/services/core/client.rs @@ -16,6 +16,7 @@ use ibc_proto::ibc::core::client::v1::{ use tonic::{Request, Response, Status}; use tracing::trace; +use crate::core::ics02_client::client_state::ClientStateValidation; use crate::core::ics02_client::error::ClientError; use crate::core::ics24_host::identifier::ClientId; use crate::core::ics24_host::path::{ @@ -235,7 +236,11 @@ where let client_id = ClientId::from_str(request_ref.client_id.as_str())?; - let client_status = self.ibc_context.client_status(&client_id)?; + let client_state = self.ibc_context.client_state(&client_id)?; + let client_validation_ctx = self.ibc_context.get_client_validation_context(); + let client_status = client_state + .status(client_validation_ctx, &client_id) + .map_err(ContextError::from)?; Ok(Response::new(QueryClientStatusResponse { status: format!("{}", client_status), From cb64ee18e404d22cae568dfd7a56222a5e61b707 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Fri, 8 Sep 2023 13:13:31 +0200 Subject: [PATCH 46/58] rm redundant trait method --- crates/ibc/src/services/core/context.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/ibc/src/services/core/context.rs b/crates/ibc/src/services/core/context.rs index 6cc18b59e..400fbd0a2 100644 --- a/crates/ibc/src/services/core/context.rs +++ b/crates/ibc/src/services/core/context.rs @@ -1,4 +1,3 @@ -use crate::core::ics02_client::client_state::Status; use crate::core::ics02_client::client_type::ClientType; use crate::core::ics03_connection::connection::IdentifiedConnectionEnd; use crate::core::ics04_channel::channel::IdentifiedChannelEnd; @@ -38,9 +37,6 @@ pub trait QueryContext: ProvableContext + ValidationContext { /// Returns the list of all heights at which consensus states for the given client are. fn consensus_state_heights(&self, client_id: &ClientId) -> Result, ContextError>; - /// Returns the status of the given client. - fn client_status(&self, client_id: &ClientId) -> Result; - /// Returns the list of supported client types. fn allowed_clients(&self) -> Vec; From 0ffa8543fec6c42de85625eb89a1916ce267a9c6 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Fri, 8 Sep 2023 13:48:25 +0200 Subject: [PATCH 47/58] add changelog entry --- .changelog/unreleased/features/842-impl-grpc-services.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/features/842-impl-grpc-services.md diff --git a/.changelog/unreleased/features/842-impl-grpc-services.md b/.changelog/unreleased/features/842-impl-grpc-services.md new file mode 100644 index 000000000..d6bb2b9e7 --- /dev/null +++ b/.changelog/unreleased/features/842-impl-grpc-services.md @@ -0,0 +1,2 @@ +- Blanket implementation of core gRPC services + ([\#842](https://github.com/cosmos/ibc-rs/pull/842)) \ No newline at end of file From 49b2e250beaf02c0867cfe512a7ececab0c16c2e Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Mon, 11 Sep 2023 14:51:11 +0200 Subject: [PATCH 48/58] nitpick --- crates/ibc/src/core/ics02_client/handler/create_client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ibc/src/core/ics02_client/handler/create_client.rs b/crates/ibc/src/core/ics02_client/handler/create_client.rs index e3ee280ab..bae748f7c 100644 --- a/crates/ibc/src/core/ics02_client/handler/create_client.rs +++ b/crates/ibc/src/core/ics02_client/handler/create_client.rs @@ -69,7 +69,7 @@ where let client_id = ClientId::new(client_type.clone(), id_counter).map_err(|e| { ContextError::from(ClientError::ClientIdentifierConstructor { - client_type: client_state.client_type(), + client_type: client_type.clone(), counter: id_counter, validation_error: e, }) From 9975840c265503384fa9968f69327227bf98c0eb Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Tue, 12 Sep 2023 10:52:01 +0200 Subject: [PATCH 49/58] rm allowed_clients --- crates/ibc/src/services/core/context.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/ibc/src/services/core/context.rs b/crates/ibc/src/services/core/context.rs index 400fbd0a2..66ad3ccb4 100644 --- a/crates/ibc/src/services/core/context.rs +++ b/crates/ibc/src/services/core/context.rs @@ -1,4 +1,3 @@ -use crate::core::ics02_client::client_type::ClientType; use crate::core::ics03_connection::connection::IdentifiedConnectionEnd; use crate::core::ics04_channel::channel::IdentifiedChannelEnd; use crate::core::ics04_channel::packet::Sequence; @@ -37,9 +36,6 @@ pub trait QueryContext: ProvableContext + ValidationContext { /// Returns the list of all heights at which consensus states for the given client are. fn consensus_state_heights(&self, client_id: &ClientId) -> Result, ContextError>; - /// Returns the list of supported client types. - fn allowed_clients(&self) -> Vec; - // Connection queries /// Returns the list of all connection ends. From 7b9f3759677173c770767dc8a7eccd11b01d5257 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Tue, 12 Sep 2023 10:52:17 +0200 Subject: [PATCH 50/58] update client params query --- crates/ibc/src/services/core/client.rs | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/crates/ibc/src/services/core/client.rs b/crates/ibc/src/services/core/client.rs index 51ffcf8cc..5799977f5 100644 --- a/crates/ibc/src/services/core/client.rs +++ b/crates/ibc/src/services/core/client.rs @@ -4,10 +4,10 @@ use std::boxed::Box; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::core::client::v1::query_server::Query as ClientQuery; use ibc_proto::ibc::core::client::v1::{ - ConsensusStateWithHeight, IdentifiedClientState, Params as ClientParams, - QueryClientParamsRequest, QueryClientParamsResponse, QueryClientStateRequest, - QueryClientStateResponse, QueryClientStatesRequest, QueryClientStatesResponse, - QueryClientStatusRequest, QueryClientStatusResponse, QueryConsensusStateHeightsRequest, + ConsensusStateWithHeight, IdentifiedClientState, QueryClientParamsRequest, + QueryClientParamsResponse, QueryClientStateRequest, QueryClientStateResponse, + QueryClientStatesRequest, QueryClientStatesResponse, QueryClientStatusRequest, + QueryClientStatusResponse, QueryConsensusStateHeightsRequest, QueryConsensusStateHeightsResponse, QueryConsensusStateRequest, QueryConsensusStateResponse, QueryConsensusStatesRequest, QueryConsensusStatesResponse, QueryUpgradedClientStateRequest, QueryUpgradedClientStateResponse, QueryUpgradedConsensusStateRequest, @@ -255,16 +255,9 @@ where trace!("Got client params request: {:?}", request_ref); - Ok(Response::new(QueryClientParamsResponse { - params: Some(ClientParams { - allowed_clients: self - .ibc_context - .allowed_clients() - .into_iter() - .map(|x| x.as_str().into()) - .collect(), - }), - })) + Err(Status::unimplemented( + "Querying ClientParams is not supported yet", + )) } async fn upgraded_client_state( From f8f8afe15087a0d9d05cd2204c74dcec5bf560e7 Mon Sep 17 00:00:00 2001 From: Rano | Ranadeep Date: Tue, 12 Sep 2023 10:53:28 +0200 Subject: [PATCH 51/58] update error message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Philippe Laferrière Signed-off-by: Rano | Ranadeep --- crates/ibc/src/services/core/client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ibc/src/services/core/client.rs b/crates/ibc/src/services/core/client.rs index 5799977f5..c9383698a 100644 --- a/crates/ibc/src/services/core/client.rs +++ b/crates/ibc/src/services/core/client.rs @@ -91,7 +91,7 @@ where ) .ok_or_else(|| { Status::not_found(format!( - "Client state not found for client {} at height {}", + "Proof unavailable for client {} at height {}", client_id, current_height )) })?; From 63cbb64018fdd9ad62f6659bb16553f5343aaea7 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Tue, 12 Sep 2023 10:56:51 +0200 Subject: [PATCH 52/58] revert immut ref on validate will be fixed in separate PR --- crates/ibc/src/core/handler.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/ibc/src/core/handler.rs b/crates/ibc/src/core/handler.rs index 75cd23aa7..faa3216a6 100644 --- a/crates/ibc/src/core/handler.rs +++ b/crates/ibc/src/core/handler.rs @@ -51,7 +51,11 @@ pub fn dispatch( /// That is, the state transition of message `i` must be applied before /// message `i+1` is validated. This is equivalent to calling /// `dispatch()` on each successively. -pub fn validate(ctx: &Ctx, router: &impl Router, msg: MsgEnvelope) -> Result<(), RouterError> +pub fn validate( + ctx: &Ctx, + router: &mut impl Router, + msg: MsgEnvelope, +) -> Result<(), RouterError> where Ctx: ValidationContext, { From 4f35d9f3afbdaf581797b35b27e57f3d75a09ec0 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Tue, 12 Sep 2023 19:42:41 +0200 Subject: [PATCH 53/58] rm tracing use --- crates/ibc/src/services/core/channel.rs | 33 +------------------- crates/ibc/src/services/core/client.rs | 35 +++------------------- crates/ibc/src/services/core/connection.rs | 23 ++------------ 3 files changed, 7 insertions(+), 84 deletions(-) diff --git a/crates/ibc/src/services/core/channel.rs b/crates/ibc/src/services/core/channel.rs index 7972e50d8..9f23677e6 100644 --- a/crates/ibc/src/services/core/channel.rs +++ b/crates/ibc/src/services/core/channel.rs @@ -17,7 +17,6 @@ use ibc_proto::ibc::core::channel::v1::{ }; use ibc_proto::ibc::core::client::v1::IdentifiedClientState; use tonic::{Request, Response, Status}; -use tracing::trace; use crate::core::ics04_channel::packet::Sequence; use crate::core::ics24_host::identifier::{ChannelId, ConnectionId, PortId}; @@ -65,8 +64,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got channel request: {:?}", &request_ref); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -96,14 +93,10 @@ where async fn channels( &self, - request: Request, + _request: Request, ) -> Result, Status> { - let request_ref = request.get_ref(); - let channel_ends = self.ibc_context.channel_ends()?; - trace!("Got channels request: {:?}", &request_ref); - Ok(Response::new(QueryChannelsResponse { channels: channel_ends.into_iter().map(Into::into).collect(), height: Some(self.ibc_context.host_height()?.into()), @@ -118,8 +111,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got connection channels request: {:?}", &request_ref); - let connection_id = ConnectionId::from_str(request_ref.connection.as_str())?; let all_channel_ends = self.ibc_context.channel_ends()?; @@ -150,8 +141,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got channel client state request: {:?}", &request_ref); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -201,8 +190,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got channel consensus state request: {:?}", &request_ref); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -252,8 +239,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got packet commitment request: {:?}", &request_ref); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -289,8 +274,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got packet commitments request: {:?}", &request_ref); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -327,8 +310,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got packet receipt request: {:?}", &request_ref); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -366,8 +347,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got packet acknowledgement request: {:?}", &request_ref); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -406,8 +385,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got packet acknowledgements request: {:?}", &request_ref); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -450,8 +427,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got unreceived packets request: {:?}", &request_ref); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -481,8 +456,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got unreceived acks request: {:?}", &request_ref); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -511,8 +484,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got next sequence receive request: {:?}", &request_ref); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; @@ -548,8 +519,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got next sequence send request: {:?}", &request_ref); - let channel_id = ChannelId::from_str(request_ref.channel_id.as_str())?; let port_id = PortId::from_str(request_ref.port_id.as_str())?; diff --git a/crates/ibc/src/services/core/client.rs b/crates/ibc/src/services/core/client.rs index c9383698a..db19b7474 100644 --- a/crates/ibc/src/services/core/client.rs +++ b/crates/ibc/src/services/core/client.rs @@ -14,7 +14,6 @@ use ibc_proto::ibc::core::client::v1::{ QueryUpgradedConsensusStateResponse, }; use tonic::{Request, Response, Status}; -use tracing::trace; use crate::core::ics02_client::client_state::ClientStateValidation; use crate::core::ics02_client::error::ClientError; @@ -76,8 +75,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got client state request: {:?}", request_ref); - let client_id = ClientId::from_str(request_ref.client_id.as_str())?; let client_state = self.ibc_context.client_state(&client_id)?; @@ -105,12 +102,8 @@ where async fn client_states( &self, - request: Request, + _request: Request, ) -> Result, Status> { - let request_ref = request.get_ref(); - - trace!("Got client states request: {:?}", request_ref); - let client_states = self.ibc_context.client_states()?; Ok(Response::new(QueryClientStatesResponse { @@ -132,8 +125,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got consensus state request: {:?}", request_ref); - let client_id = ClientId::from_str(request_ref.client_id.as_str())?; let (height, consensus_state) = if request_ref.latest_height { @@ -185,8 +176,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got consensus states request: {:?}", request_ref); - let client_id = ClientId::from_str(request_ref.client_id.as_str())?; let consensus_states = self.ibc_context.consensus_states(&client_id)?; @@ -210,8 +199,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got consensus state heights request: {:?}", request_ref); - let client_id = ClientId::from_str(request_ref.client_id.as_str())?; let consensus_state_heights = self.ibc_context.consensus_state_heights(&client_id)?; @@ -232,8 +219,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got client status request: {:?}", request_ref); - let client_id = ClientId::from_str(request_ref.client_id.as_str())?; let client_state = self.ibc_context.client_state(&client_id)?; @@ -249,12 +234,8 @@ where async fn client_params( &self, - request: Request, + _request: Request, ) -> Result, Status> { - let request_ref = request.get_ref(); - - trace!("Got client params request: {:?}", request_ref); - Err(Status::unimplemented( "Querying ClientParams is not supported yet", )) @@ -262,12 +243,8 @@ where async fn upgraded_client_state( &self, - request: Request, + _request: Request, ) -> Result, Status> { - let request_ref = request.get_ref(); - - trace!("Got upgraded client state request: {:?}", request_ref); - let plan = self .upgrade_context .upgrade_plan() @@ -289,12 +266,8 @@ where async fn upgraded_consensus_state( &self, - request: Request, + _request: Request, ) -> Result, Status> { - let request_ref = request.get_ref(); - - trace!("Got upgraded consensus state request: {:?}", request_ref); - let plan = self .upgrade_context .upgrade_plan() diff --git a/crates/ibc/src/services/core/connection.rs b/crates/ibc/src/services/core/connection.rs index d60df59ad..baf3234f3 100644 --- a/crates/ibc/src/services/core/connection.rs +++ b/crates/ibc/src/services/core/connection.rs @@ -11,7 +11,6 @@ use ibc_proto::ibc::core::connection::v1::{ QueryConnectionResponse, QueryConnectionsRequest, QueryConnectionsResponse, }; use tonic::{Request, Response, Status}; -use tracing::trace; use crate::core::ics24_host::identifier::{ClientId, ConnectionId}; use crate::core::ics24_host::path::{ @@ -57,8 +56,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got connection request: {:?}", request_ref); - let connection_id = ConnectionId::from_str(request_ref.connection_id.as_str())?; let connection_end = self.ibc_context.connection_end(&connection_id)?; @@ -87,12 +84,8 @@ where async fn connections( &self, - request: Request, + _request: Request, ) -> Result, Status> { - let request_ref = request.get_ref(); - - trace!("Got connections request: {:?}", request_ref); - let connections = self.ibc_context.connection_ends()?; Ok(Response::new(QueryConnectionsResponse { @@ -109,10 +102,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got client connections request: {:?}", request_ref); - - let request_ref = request.get_ref(); - let client_id = ClientId::from_str(request_ref.client_id.as_str())?; let connections = self.ibc_context.client_connection_ends(&client_id)?; @@ -145,8 +134,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got connection client state request: {:?}", request_ref); - let connection_id = ConnectionId::from_str(request_ref.connection_id.as_str())?; let connection_end = self.ibc_context.connection_end(&connection_id)?; @@ -184,8 +171,6 @@ where ) -> Result, Status> { let request_ref = request.get_ref(); - trace!("Got connection consensus state request: {:?}", request_ref); - let connection_id = ConnectionId::from_str(request_ref.connection_id.as_str())?; let connection_end = self.ibc_context.connection_end(&connection_id)?; @@ -219,12 +204,8 @@ where async fn connection_params( &self, - request: Request, + _request: Request, ) -> Result, Status> { - let request_ref = request.get_ref(); - - trace!("Got connection params request: {:?}", request_ref); - Ok(Response::new(QueryConnectionParamsResponse { params: Some(ConnectionParams { max_expected_time_per_block: self From b7bd700cee140e5ccb3383646abf020757d8705e Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Wed, 13 Sep 2023 10:50:34 +0200 Subject: [PATCH 54/58] document thread-safe params --- crates/ibc/src/services/core/channel.rs | 1 + crates/ibc/src/services/core/client.rs | 1 + crates/ibc/src/services/core/connection.rs | 1 + crates/ibc/src/services/mod.rs | 6 ++++-- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/crates/ibc/src/services/core/channel.rs b/crates/ibc/src/services/core/channel.rs index 9f23677e6..be38c6012 100644 --- a/crates/ibc/src/services/core/channel.rs +++ b/crates/ibc/src/services/core/channel.rs @@ -46,6 +46,7 @@ where ::AnyClientState: Into, ::AnyConsensusState: Into, { + /// `ibc_context` must be thread-safe. Possibly wrapped in `Arc>` or `Arc>` or similar. pub fn new(ibc_context: I) -> Self { Self { ibc_context } } diff --git a/crates/ibc/src/services/core/client.rs b/crates/ibc/src/services/core/client.rs index db19b7474..c7964f55e 100644 --- a/crates/ibc/src/services/core/client.rs +++ b/crates/ibc/src/services/core/client.rs @@ -51,6 +51,7 @@ where ::AnyClientState: Into, ::AnyConsensusState: Into, { + /// `ibc_context` and `upgrade_context` must be thread-safe. Possibly wrapped in `Arc>` or `Arc>` or similar. pub fn new(ibc_context: I, upgrade_context: U) -> Self { Self { ibc_context, diff --git a/crates/ibc/src/services/core/connection.rs b/crates/ibc/src/services/core/connection.rs index baf3234f3..68bad07fb 100644 --- a/crates/ibc/src/services/core/connection.rs +++ b/crates/ibc/src/services/core/connection.rs @@ -38,6 +38,7 @@ where ::AnyClientState: Into, ::AnyConsensusState: Into, { + /// `ibc_context` must be thread-safe. Possibly wrapped in `Arc>` or `Arc>` or similar. pub fn new(ibc_context: I) -> Self { Self { ibc_context } } diff --git a/crates/ibc/src/services/mod.rs b/crates/ibc/src/services/mod.rs index 6658ead42..d90ad3055 100644 --- a/crates/ibc/src/services/mod.rs +++ b/crates/ibc/src/services/mod.rs @@ -31,8 +31,10 @@ //! let ibc = Ibc::new(); //! let upgrade = Upgrade::new(); //! -//! let client_service = ClientQueryServer::new(ClientQueryService::new(ibc, upgrade)) -//! let connection_service = ConnectionQueryServer::new(ConnectionQueryService::new(ibc)) +//! // `ibc` and `upgrade` must be thread-safe +//! +//! let client_service = ClientQueryServer::new(ClientQueryService::new(ibc.clone(), upgrade)) +//! let connection_service = ConnectionQueryServer::new(ConnectionQueryService::new(ibc.clone())) //! let channel_service = ChannelQueryServer::new(ChannelQueryService::new(ibc)) //! //! let grpc_server = tonic::transport::Server::builder() From 75ca4cab18d958424b164c6417019ec4b58ff8a7 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Wed, 13 Sep 2023 16:53:53 +0200 Subject: [PATCH 55/58] point changelog entry to issue --- .changelog/unreleased/features/842-impl-grpc-services.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changelog/unreleased/features/842-impl-grpc-services.md b/.changelog/unreleased/features/842-impl-grpc-services.md index d6bb2b9e7..081992300 100644 --- a/.changelog/unreleased/features/842-impl-grpc-services.md +++ b/.changelog/unreleased/features/842-impl-grpc-services.md @@ -1,2 +1,2 @@ - Blanket implementation of core gRPC services - ([\#842](https://github.com/cosmos/ibc-rs/pull/842)) \ No newline at end of file + ([\#686](https://github.com/cosmos/ibc-rs/issues/686)) \ No newline at end of file From 292abf7897945c9af1d2da8c3427ae92a6a9c453 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 14 Sep 2023 16:19:19 +0200 Subject: [PATCH 56/58] rm FromStr from prelude --- crates/ibc/src/prelude.rs | 1 - crates/ibc/src/services/core/channel.rs | 1 + crates/ibc/src/services/core/connection.rs | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/ibc/src/prelude.rs b/crates/ibc/src/prelude.rs index 803d1fad0..9ff42a989 100644 --- a/crates/ibc/src/prelude.rs +++ b/crates/ibc/src/prelude.rs @@ -4,7 +4,6 @@ pub use core::prelude::v1::*; // https://doc.rust-lang.org/src/alloc/prelude/v1.rs.html pub use alloc::borrow::ToOwned; pub use alloc::boxed::Box; -pub use alloc::str::FromStr; pub use alloc::string::{String, ToString}; pub use alloc::vec::Vec; diff --git a/crates/ibc/src/services/core/channel.rs b/crates/ibc/src/services/core/channel.rs index be38c6012..b7e1a957b 100644 --- a/crates/ibc/src/services/core/channel.rs +++ b/crates/ibc/src/services/core/channel.rs @@ -1,3 +1,4 @@ +use alloc::str::FromStr; use std::boxed::Box; use ibc_proto::google::protobuf::Any; diff --git a/crates/ibc/src/services/core/connection.rs b/crates/ibc/src/services/core/connection.rs index 68bad07fb..294808f32 100644 --- a/crates/ibc/src/services/core/connection.rs +++ b/crates/ibc/src/services/core/connection.rs @@ -1,3 +1,4 @@ +use alloc::str::FromStr; use std::boxed::Box; use ibc_proto::google::protobuf::Any; From 7513fc89cc391cb1dd4aceb9a4e6cb0840826253 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 14 Sep 2023 16:49:55 +0200 Subject: [PATCH 57/58] doc strings with correct explanations --- crates/ibc/src/services/core/channel.rs | 9 ++++++++- crates/ibc/src/services/core/client.rs | 9 ++++++++- crates/ibc/src/services/core/connection.rs | 9 ++++++++- crates/ibc/src/services/core/context.rs | 2 ++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/crates/ibc/src/services/core/channel.rs b/crates/ibc/src/services/core/channel.rs index b7e1a957b..3442f569d 100644 --- a/crates/ibc/src/services/core/channel.rs +++ b/crates/ibc/src/services/core/channel.rs @@ -1,3 +1,7 @@ +//! [`ChannelQueryService`](ChannelQueryService) takes a generic `I` to store `ibc_context` that implements [`QueryContext`](QueryContext). +//! `I` must be a type where writes from one thread are readable from another. +//! This means using `Arc>` or `Arc>` in most cases. + use alloc::str::FromStr; use std::boxed::Box; @@ -32,6 +36,8 @@ use crate::Height; // TODO(rano): currently the services don't support pagination, so we return all the results. +/// The generic `I` must be a type where writes from one thread are readable from another. +/// This means using `Arc>` or `Arc>` in most cases. pub struct ChannelQueryService where I: QueryContext + Send + Sync + 'static, @@ -47,7 +53,8 @@ where ::AnyClientState: Into, ::AnyConsensusState: Into, { - /// `ibc_context` must be thread-safe. Possibly wrapped in `Arc>` or `Arc>` or similar. + /// The parameter `ibc_context` must be a type where writes from one thread are readable from another. + /// This means using `Arc>` or `Arc>` in most cases. pub fn new(ibc_context: I) -> Self { Self { ibc_context } } diff --git a/crates/ibc/src/services/core/client.rs b/crates/ibc/src/services/core/client.rs index c7964f55e..11a7ce548 100644 --- a/crates/ibc/src/services/core/client.rs +++ b/crates/ibc/src/services/core/client.rs @@ -1,3 +1,7 @@ +//! [`ClientQueryService`](ClientQueryService) takes generics `I` and `U` to store `ibc_context` and `upgrade_context` that implement [`QueryContext`](QueryContext) and [`UpgradeValidationContext`](UpgradeValidationContext) respectively. +//! `I` must be a type where writes from one thread are readable from another. +//! This means using `Arc>` or `Arc>` in most cases. + use core::str::FromStr; use std::boxed::Box; @@ -29,6 +33,8 @@ use crate::Height; // TODO(rano): currently the services don't support pagination, so we return all the results. +/// Generics `I` and `U` must be a type where writes from one thread are readable from another. +/// This means using `Arc>` or `Arc>` in most cases. pub struct ClientQueryService where I: QueryContext + Send + Sync + 'static, @@ -51,7 +57,8 @@ where ::AnyClientState: Into, ::AnyConsensusState: Into, { - /// `ibc_context` and `upgrade_context` must be thread-safe. Possibly wrapped in `Arc>` or `Arc>` or similar. + /// Parameters `ibc_context` and `upgrade_context` must be a type where writes from one thread are readable from another. + /// This means using `Arc>` or `Arc>` in most cases. pub fn new(ibc_context: I, upgrade_context: U) -> Self { Self { ibc_context, diff --git a/crates/ibc/src/services/core/connection.rs b/crates/ibc/src/services/core/connection.rs index 294808f32..eaf77ca65 100644 --- a/crates/ibc/src/services/core/connection.rs +++ b/crates/ibc/src/services/core/connection.rs @@ -1,3 +1,7 @@ +//! [`ConnectionQueryService`](ConnectionQueryService) takes a generic `I` to store `ibc_context` that implements [`QueryContext`](QueryContext). +//! `I` must be a type where writes from one thread are readable from another. +//! This means using `Arc>` or `Arc>` in most cases. + use alloc::str::FromStr; use std::boxed::Box; @@ -24,6 +28,8 @@ use crate::Height; // TODO(rano): currently the services don't support pagination, so we return all the results. +/// The generic `I` must be a type where writes from one thread are readable from another. +/// This means using `Arc>` or `Arc>` in most cases. pub struct ConnectionQueryService where I: QueryContext + Send + Sync + 'static, @@ -39,7 +45,8 @@ where ::AnyClientState: Into, ::AnyConsensusState: Into, { - /// `ibc_context` must be thread-safe. Possibly wrapped in `Arc>` or `Arc>` or similar. + /// The parameter `ibc_context` must be a type where writes from one thread are readable from another. + /// This means using `Arc>` or `Arc>` in most cases. pub fn new(ibc_context: I) -> Self { Self { ibc_context } } diff --git a/crates/ibc/src/services/core/context.rs b/crates/ibc/src/services/core/context.rs index 66ad3ccb4..14632f25f 100644 --- a/crates/ibc/src/services/core/context.rs +++ b/crates/ibc/src/services/core/context.rs @@ -1,3 +1,5 @@ +//! Required traits for blanket implementations of [`gRPC query services`](crate::services::core). + use crate::core::ics03_connection::connection::IdentifiedConnectionEnd; use crate::core::ics04_channel::channel::IdentifiedChannelEnd; use crate::core::ics04_channel::packet::Sequence; From 9ebe9e570cd1f4bca08f1e29a4452f7a429b1495 Mon Sep 17 00:00:00 2001 From: Ranadeep Biswas Date: Thu, 14 Sep 2023 16:53:05 +0200 Subject: [PATCH 58/58] rm reexports --- crates/ibc/src/services/core/mod.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/ibc/src/services/core/mod.rs b/crates/ibc/src/services/core/mod.rs index 4e896761e..4404ef3e9 100644 --- a/crates/ibc/src/services/core/mod.rs +++ b/crates/ibc/src/services/core/mod.rs @@ -2,7 +2,3 @@ pub mod channel; pub mod client; pub mod connection; pub mod context; - -pub use channel::ChannelQueryService; -pub use client::ClientQueryService; -pub use connection::ConnectionQueryService;