From 4d77f792614cf48fa24456341a2dcae664f60a4b Mon Sep 17 00:00:00 2001 From: Ava Howell Date: Wed, 3 Jan 2024 18:05:05 -0800 Subject: [PATCH] ibc: implement next_sequence_send query --- .../ibc/src/component/rpc/consensus_query.rs | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/crates/core/component/ibc/src/component/rpc/consensus_query.rs b/crates/core/component/ibc/src/component/rpc/consensus_query.rs index 3c0beb3616..bc22c31b53 100644 --- a/crates/core/component/ibc/src/component/rpc/consensus_query.rs +++ b/crates/core/component/ibc/src/component/rpc/consensus_query.rs @@ -18,7 +18,7 @@ use ibc_proto::ibc::core::channel::v1::{ use ibc_proto::ibc::core::client::v1::{Height, IdentifiedClientState}; use ibc_types::path::{ AckPath, ChannelEndPath, ClientConsensusStatePath, ClientStatePath, CommitmentPath, - ReceiptPath, SeqRecvPath, + ReceiptPath, SeqRecvPath, SeqSendPath, }; use ibc_types::DomainType; @@ -26,7 +26,6 @@ use ibc_types::core::channel::{ChannelId, IdentifiedChannelEnd, PortId}; use ibc_types::core::connection::ConnectionId; use prost::Message; -use sha2::digest::generic_array::functional::MappedSequence; use std::str::FromStr; @@ -719,8 +718,36 @@ impl ConsensusQuery for IbcQuery { /// NextSequenceSend returns the next send sequence for a given channel. async fn next_sequence_send( &self, - _request: tonic::Request, + request: tonic::Request, ) -> std::result::Result, tonic::Status> { - Err(tonic::Status::unimplemented("not implemented")) + let snapshot = self.0.latest_snapshot(); + + let channel_id = ChannelId::from_str(request.get_ref().channel_id.as_str()) + .map_err(|e| tonic::Status::aborted(format!("invalid channel id: {e}")))?; + let port_id = PortId::from_str(request.get_ref().port_id.as_str()) + .map_err(|e| tonic::Status::aborted(format!("invalid port id: {e}")))?; + + let (next_send_sequence, proof) = snapshot + .get_with_proof( + IBC_COMMITMENT_PREFIX + .apply_string(SeqSendPath::new(&port_id, &channel_id).to_string()) + .as_bytes() + .to_vec(), + ) + .await + .map_err(|e| tonic::Status::aborted(format!("couldn't get channel: {e}")))?; + + let next_send_sequence = next_send_sequence + .map(|seq_bytes| u64::from_be_bytes(seq_bytes.try_into().expect("invalid sequence"))) + .ok_or_else(|| tonic::Status::aborted("next receive sequence not found"))?; + + Ok(tonic::Response::new(QueryNextSequenceSendResponse { + next_sequence_send: next_send_sequence, + proof: proof.encode_to_vec(), + proof_height: Some(Height { + revision_number: 0, + revision_height: snapshot.version(), + }), + })) } }