Skip to content

Commit

Permalink
Use gRPC to query connection end (#1048)
Browse files Browse the repository at this point in the history
  • Loading branch information
soareschen authored Jun 14, 2021
1 parent 6681151 commit 3c7cd0f
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 8 deletions.
56 changes: 52 additions & 4 deletions relayer/src/chain/cosmos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use tendermint_rpc::query::Query;
use tendermint_rpc::{endpoint::broadcast::tx_commit::Response, Client, HttpClient, Order};
use tokio::runtime::Runtime as TokioRuntime;
use tonic::codegen::http::Uri;
use tonic::Code;

use ibc::downcast;
use ibc::events::{from_tx_response_event, IbcEvent};
Expand Down Expand Up @@ -751,11 +752,58 @@ impl Chain for CosmosSdkChain {
connection_id: &ConnectionId,
height: ICSHeight,
) -> Result<ConnectionEnd, Error> {
let res = self.query(Path::Connections(connection_id.clone()), height, false)?;
let connection_end = ConnectionEnd::decode_vec(&res.value)
.map_err(|e| Kind::Query(format!("connection '{}'", connection_id)).context(e))?;
async fn do_query_connection(
chain: &CosmosSdkChain,
connection_id: &ConnectionId,
height: ICSHeight,
) -> Result<ConnectionEnd, Error> {
use ibc_proto::ibc::core::connection::v1 as connection;
use tonic::{metadata::MetadataValue, IntoRequest};

let mut client =
connection::query_client::QueryClient::connect(chain.grpc_addr.clone())
.await
.map_err(|e| Kind::Grpc.context(e))?;

let mut request = connection::QueryConnectionRequest {
connection_id: connection_id.to_string(),
}
.into_request();

let height_param = MetadataValue::from_str(&height.revision_height.to_string())
.map_err(|e| Kind::Grpc.context(e))?;

request
.metadata_mut()
.insert("x-cosmos-block-height", height_param);

let response = client.connection(request).await.map_err(|e| {
if e.code() == Code::NotFound {
Kind::ConnectionNotFound(connection_id.clone()).into()
} else {
Kind::Grpc.context(e)
}
})?;

match response.into_inner().connection {
Some(raw_connection) => {
let connection_end = raw_connection
.try_into()
.map_err(|e| Kind::Grpc.context(e))?;

Ok(connection_end)
}
None => {
// When no connection is found, the GRPC call itself should return
// the NotFound error code. Nevertheless even if the call is successful,
// the connection field may not be present, because in protobuf3
// everything is optional.
Err(Kind::ConnectionNotFound(connection_id.clone()).into())
}
}
}

Ok(connection_end)
self.block_on(async { do_query_connection(self, connection_id, height).await })
}

fn query_connection_channels(
Expand Down
8 changes: 4 additions & 4 deletions relayer/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use ibc::ics03_connection::msgs::conn_open_try::MsgConnectionOpenTry;
use ibc::ics24_host::identifier::{ChainId, ClientId, ConnectionId};
use ibc::timestamp::ZERO_DURATION;
use ibc::tx_msg::Msg;
use ibc::Height as ICSHeight;

use crate::chain::handle::ChainHandle;
use crate::error::Error;
Expand Down Expand Up @@ -389,7 +388,7 @@ impl Connection {
// Retrieve existing connection if any
let dst_connection = self
.dst_chain()
.query_connection(self.dst_connection_id(), ICSHeight::default())
.query_connection(self.dst_connection_id(), Height::zero())
.map_err(|e| ConnectionError::QueryError(self.dst_chain().id(), e))?;

// Check if a connection is expected to exist on destination chain
Expand Down Expand Up @@ -494,7 +493,7 @@ impl Connection {
pub fn build_conn_try(&self) -> Result<Vec<Any>, ConnectionError> {
let src_connection = self
.src_chain()
.query_connection(self.src_connection_id(), ICSHeight::default())
.query_connection(self.src_connection_id(), Height::zero())
.map_err(|e| ConnectionError::QueryError(self.src_chain().id(), e))?;

// TODO - check that the src connection is consistent with the try options
Expand Down Expand Up @@ -626,7 +625,7 @@ impl Connection {

let src_connection = self
.src_chain()
.query_connection(self.src_connection_id(), ICSHeight::default())
.query_connection(self.src_connection_id(), Height::zero())
.map_err(|e| ConnectionError::QueryError(self.src_chain().id(), e))?;

// TODO - check that the src connection is consistent with the ack options
Expand Down Expand Up @@ -724,6 +723,7 @@ impl Connection {
.src_chain()
.query_latest_height()
.map_err(|e| ConnectionError::QueryError(self.src_chain().id(), e))?;

let _src_connection = self
.src_chain()
.query_connection(self.src_connection_id(), query_height)
Expand Down
3 changes: 3 additions & 0 deletions relayer/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ pub enum Kind {
#[error("Failed to create client {0}")]
CreateClient(String),

#[error("Connection not found: {0}")]
ConnectionNotFound(ConnectionId),

/// Common failures to all connection messages
#[error("Failed to build conn open message {0}: {1}")]
ConnOpen(ConnectionId, String),
Expand Down

0 comments on commit 3c7cd0f

Please sign in to comment.