From d525a4da0112ec0762fb8c4c39c2f8eeeb043ccb Mon Sep 17 00:00:00 2001 From: Judd Keppel Date: Fri, 15 Nov 2024 14:04:39 -0600 Subject: [PATCH 1/3] Add raw client update method to IBC module --- src/ibc/mod.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/ibc/mod.rs b/src/ibc/mod.rs index fab7631d..1af057a6 100644 --- a/src/ibc/mod.rs +++ b/src/ibc/mod.rs @@ -204,6 +204,40 @@ impl Ibc { Ok(self.transfer_mut().incoming_transfer_mut().take()) } + pub fn update_client_from_header( + &mut self, + client_index: u64, + rev_number: u64, + header_json: &str, + ) -> crate::Result<()> { + let client_id: ClientId = ClientId::new("07-tendermint", client_index).unwrap(); + let header: orga::cosmrs::tendermint::block::Header = serde_json::from_str(header_json)?; + let mut client = self + .ctx + .clients + .get_mut(client_id.into())? + .ok_or(Error::Ibc("Client not found".to_string()))?; + let height = Height::new(rev_number, header.height.value()).unwrap(); + client.updates.insert( + height.into(), + ( + WrappedTimestamp { + inner: header.time.try_into().unwrap(), + }, + height.into(), + ), + )?; + + let consensus_state = WrappedConsensusState { + inner: header.into(), + }; + client + .consensus_states + .insert(height.into(), consensus_state)?; + + Ok(()) + } + fn signer(&mut self) -> crate::Result
{ self.context::() .ok_or_else(|| Error::Coins("No Signer context available".into()))? From 134dec7464d77d6bad6d0c2ec93d359c7e54de05 Mon Sep 17 00:00:00 2001 From: Judd Keppel Date: Fri, 15 Nov 2024 14:04:53 -0600 Subject: [PATCH 2/3] Revert gRPC client changes --- src/ibc/service.rs | 91 +++++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 45 deletions(-) diff --git a/src/ibc/service.rs b/src/ibc/service.rs index cb969778..02ecadc6 100644 --- a/src/ibc/service.rs +++ b/src/ibc/service.rs @@ -128,7 +128,7 @@ impl From for tonic::Status { } pub struct IbcClientService { - pub ibc: C, + pub ibc: fn() -> C, } #[tonic::async_trait] @@ -144,8 +144,9 @@ impl + 'static> ClientQuery for IbcClientService { &self, _request: Request, ) -> Result, Status> { + let ibc = (self.ibc)(); let res = QueryClientStatesResponse { - client_states: self.ibc.query(|ibc| ibc.query_client_states()).await?, + client_states: ibc.query(|ibc| ibc.query_client_states()).await?, ..Default::default() }; Ok(Response::new(res)) @@ -161,8 +162,9 @@ impl + 'static> ClientQuery for IbcClientService { let revision_number = request.revision_number; let revision_height = request.revision_height; - let consensus_state = self - .ibc + let ibc = (self.ibc)(); + + let consensus_state = ibc .query(|ibc| { ibc.query_consensus_state( client_id.clone().into(), @@ -185,6 +187,7 @@ impl + 'static> ClientQuery for IbcClientService { &self, request: Request, ) -> Result, Status> { + let ibc = (self.ibc)(); let client_id: ClientId = request .into_inner() .client_id @@ -192,8 +195,7 @@ impl + 'static> ClientQuery for IbcClientService { .map_err(|_| Status::invalid_argument("Invalid client ID".to_string()))?; let res = QueryConsensusStatesResponse { - consensus_states: self - .ibc + consensus_states: ibc .query(|ibc| ibc.query_consensus_states(client_id.clone().into())) .await?, ..Default::default() @@ -215,9 +217,9 @@ impl + 'static> ClientQuery for IbcClientService { let request = request.into_inner(); let client_id = ClientId::from_str(&request.client_id) .map_err(|_| Status::invalid_argument("Invalid client ID".to_string()))?; + let ibc = (self.ibc)(); - let client_status = self - .ibc + let client_status = ibc .query(|ibc| ibc.query_client_status(client_id.clone().into())) .await?; @@ -251,7 +253,7 @@ impl + 'static> ClientQuery for IbcClientService { } pub struct IbcConnectionService { - ibc: C, + ibc: fn() -> C, } #[tonic::async_trait] @@ -260,12 +262,12 @@ impl + 'static> ConnectionQuery for IbcConnectionService, ) -> Result, Status> { + let ibc = (self.ibc)(); let conn_id = ConnectionId::from_str(&request.into_inner().connection_id) .map_err(|_| Status::invalid_argument("Invalid connection ID".to_string()))?; Ok(Response::new(QueryConnectionResponse { - connection: self - .ibc + connection: ibc .query(|ibc| ibc.query_connection(conn_id.clone().into())) .await? .map(Into::into), @@ -277,8 +279,9 @@ impl + 'static> ConnectionQuery for IbcConnectionService, ) -> Result, Status> { + let ibc = (self.ibc)(); Ok(Response::new(QueryConnectionsResponse { - connections: self.ibc.query(|ibc| ibc.query_all_connections()).await?, + connections: ibc.query(|ibc| ibc.query_all_connections()).await?, ..Default::default() })) } @@ -287,13 +290,13 @@ impl + 'static> ConnectionQuery for IbcConnectionService, ) -> Result, Status> { + let ibc = (self.ibc)(); let client_id: ClientId = request .into_inner() .client_id .parse() .map_err(|_| Status::invalid_argument("Invalid client ID".to_string()))?; - let connection_ids = self - .ibc + let connection_ids = ibc .query(|ibc| ibc.query_client_connections(client_id.clone().into())) .await?; @@ -326,7 +329,7 @@ impl + 'static> ConnectionQuery for IbcConnectionService { - ibc: C, + ibc: fn() -> C, revision_number: u64, } @@ -336,6 +339,7 @@ impl + 'static> ChannelQuery for IbcChannelService { &self, request: Request, ) -> Result, Status> { + let ibc = (self.ibc)(); let request = request.into_inner(); let port_id = PortId::from_str(&request.port_id) .map_err(|_| Status::invalid_argument("invalid port id"))?; @@ -345,8 +349,7 @@ impl + 'static> ChannelQuery for IbcChannelService { let path = ChannelEndPath(port_id, channel_id); Ok(Response::new(QueryChannelResponse { - channel: self - .ibc + channel: ibc .query(|ibc| ibc.query_channel(path.clone().into())) .await?, ..Default::default() @@ -357,9 +360,9 @@ impl + 'static> ChannelQuery for IbcChannelService { &self, _request: Request, ) -> Result, Status> { + let ibc = (self.ibc)(); let revision_number = self.revision_number; - let (channels, height) = self - .ibc + let (channels, height) = ibc .query(|ibc| Ok((ibc.query_all_channels()?, ibc.height))) .await?; @@ -377,12 +380,12 @@ impl + 'static> ChannelQuery for IbcChannelService { &self, request: Request, ) -> Result, Status> { + let ibc = (self.ibc)(); let revision_number = self.revision_number; let conn_id = ConnectionId::from_str(&request.get_ref().connection) .map_err(|_| Status::invalid_argument("invalid connection id"))?; - let (channels, height) = self - .ibc + let (channels, height) = ibc .query(|ibc| { Ok(( ibc.query_connection_channels(conn_id.clone().into())?, @@ -404,6 +407,7 @@ impl + 'static> ChannelQuery for IbcChannelService { &self, request: Request, ) -> Result, Status> { + let ibc = (self.ibc)(); let request = request.into_inner(); let port_id = PortId::from_str(&request.port_id) .map_err(|_| Status::invalid_argument("invalid port id"))?; @@ -411,8 +415,7 @@ impl + 'static> ChannelQuery for IbcChannelService { .map_err(|_| Status::invalid_argument("invalid channel id"))?; let path = ChannelEndPath(port_id, channel_id); - let channel: Channel = self - .ibc + let channel: Channel = ibc .query(|ibc| Ok(ibc.query_channel(path.clone().into()))) .await?? .ok_or_else(|| Status::not_found("channel not found"))?; @@ -420,16 +423,14 @@ impl + 'static> ChannelQuery for IbcChannelService { .connection_hops .first() .ok_or_else(|| Status::not_found("channel does not have a connection hop"))?; - let connection_end: ConnectionEnd = self - .ibc + let connection_end: ConnectionEnd = ibc .query(|ibc| { Ok(ibc.query_connection(ConnectionId::from_str(connection_id).unwrap().into())) }) .await?? .ok_or_else(|| Status::not_found("connection not found"))?; let client_id = connection_end.client_id(); - let client_state = self - .ibc + let client_state = ibc .query(|ibc| { Ok(ibc .clients @@ -472,6 +473,7 @@ impl + 'static> ChannelQuery for IbcChannelService { &self, request: Request, ) -> Result, Status> { + let ibc = (self.ibc)(); let revision_number = self.revision_number; let request = request.into_inner(); let port_id = PortId::from_str(&request.port_id) @@ -481,8 +483,7 @@ impl + 'static> ChannelQuery for IbcChannelService { let path = PortChannel::new(port_id, channel_id); - let (commitments, height) = self - .ibc + let (commitments, height) = ibc .query(|ibc| Ok((ibc.query_packet_commitments(path.clone())?, ibc.height))) .await?; @@ -507,10 +508,10 @@ impl + 'static> ChannelQuery for IbcChannelService { .map_err(|_| Status::invalid_argument("invalid channel id"))?; let sequence = Sequence::from(request.sequence); + let ibc = (self.ibc)(); let receipt_path = ReceiptPath::new(&port_id, &channel_id, sequence); - let receipt = self - .ibc + let receipt = ibc .query(|ibc| Ok(ibc.get_packet_receipt(&receipt_path.clone())?)) .await; @@ -534,6 +535,7 @@ impl + 'static> ChannelQuery for IbcChannelService { &self, request: Request, ) -> Result, Status> { + let ibc = (self.ibc)(); let revision_number = self.revision_number; let request = request.into_inner(); let port_id = PortId::from_str(&request.port_id) @@ -543,8 +545,7 @@ impl + 'static> ChannelQuery for IbcChannelService { let sequences = request.packet_commitment_sequences; let path = PortChannel::new(port_id, channel_id); - let (acknowledgements, height) = self - .ibc + let (acknowledgements, height) = ibc .query(|ibc| { Ok(( ibc.query_packet_acks(sequences.clone().try_into().unwrap(), path.clone())?, @@ -567,6 +568,7 @@ impl + 'static> ChannelQuery for IbcChannelService { &self, request: Request, ) -> Result, Status> { + let ibc = (self.ibc)(); let revision_number = self.revision_number; let request = request.into_inner(); let port_id = PortId::from_str(&request.port_id) @@ -576,8 +578,7 @@ impl + 'static> ChannelQuery for IbcChannelService { let sequences_to_check: Vec = request.packet_commitment_sequences; let path = PortChannel::new(port_id, channel_id); - let (sequences, height) = self - .ibc + let (sequences, height) = ibc .query(|ibc| { Ok(( ibc.query_unreceived_packets( @@ -602,6 +603,7 @@ impl + 'static> ChannelQuery for IbcChannelService { &self, request: Request, ) -> Result, Status> { + let ibc = (self.ibc)(); let revision_number = self.revision_number; let request = request.into_inner(); let port_id = PortId::from_str(&request.port_id) @@ -611,8 +613,7 @@ impl + 'static> ChannelQuery for IbcChannelService { let sequences_to_check: Vec = request.packet_ack_sequences; let path = PortChannel::new(port_id, channel_id); - let (sequences, height) = self - .ibc + let (sequences, height) = ibc .query(|ibc| { Ok(( ibc.query_unreceived_acks( @@ -637,14 +638,14 @@ impl + 'static> ChannelQuery for IbcChannelService { &self, request: Request, ) -> Result, Status> { + let ibc_client = (self.ibc)(); let request_inner = request.into_inner(); let port_id = PortId::from_str(&request_inner.port_id) .map_err(|_| Status::invalid_argument("invalid port id"))?; let channel_id = ChannelId::from_str(&request_inner.channel_id) .map_err(|_| Status::invalid_argument("invalid channel id"))?; let res = QueryNextSequenceReceiveResponse { - next_sequence_receive: self - .ibc + next_sequence_receive: ibc_client .query(|ibc| { ibc.query_next_sequence_receive(PortChannel::new( port_id.clone(), @@ -661,14 +662,14 @@ impl + 'static> ChannelQuery for IbcChannelService { &self, request: Request, ) -> Result, Status> { + let ibc_client = (self.ibc)(); let request_inner = request.into_inner(); let port_id = PortId::from_str(&request_inner.port_id) .map_err(|_| Status::invalid_argument("invalid port id"))?; let channel_id = ChannelId::from_str(&request_inner.channel_id) .map_err(|_| Status::invalid_argument("invalid channel id"))?; let res = QueryNextSequenceSendResponse { - next_sequence_send: self - .ibc + next_sequence_send: ibc_client .query(|ibc| { ibc.query_next_sequence_send(PortChannel::new( port_id.clone(), @@ -1156,20 +1157,20 @@ pub struct GrpcOpts { } /// Start the gRPC server. -pub async fn start_grpc + 'static, F: Fn() -> C>(client: F, opts: &GrpcOpts) { +pub async fn start_grpc + 'static>(client: fn() -> C, opts: &GrpcOpts) { use tonic::transport::Server; let auth_service = AuthQueryServer::new(AuthService {}); let bank_service = BankQueryServer::new(BankService {}); let staking_service = StakingQueryServer::new(StakingService {}); - let ibc_client_service = ClientQueryServer::new(IbcClientService { ibc: client() }); - let ibc_connection_service = ConnectionQueryServer::new(IbcConnectionService { ibc: client() }); + let ibc_client_service = ClientQueryServer::new(IbcClientService { ibc: client }); + let ibc_connection_service = ConnectionQueryServer::new(IbcConnectionService { ibc: client }); let revision_number = opts .chain_id .rsplit_once('-') .map(|(_, n)| n.parse::().unwrap_or(0)) .unwrap_or(0); let ibc_channel_service = ChannelQueryServer::new(IbcChannelService { - ibc: client(), + ibc: client, revision_number, }); let health_service = HealthServer::new(AppHealthService {}); From 52a81fd4ba64af2609a2d2d2e3b79adbfa55450a Mon Sep 17 00:00:00 2001 From: Judd Keppel Date: Fri, 15 Nov 2024 19:46:25 -0600 Subject: [PATCH 3/3] Update client state --- src/ibc/mod.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/ibc/mod.rs b/src/ibc/mod.rs index 1af057a6..946607f7 100644 --- a/src/ibc/mod.rs +++ b/src/ibc/mod.rs @@ -231,6 +231,23 @@ impl Ibc { let consensus_state = WrappedConsensusState { inner: header.into(), }; + + let mut client_state = client + .client_state + .get(Default::default())? + .ok_or(Error::Ibc("Client not found".to_string()))? + .inner + .inner() + .clone(); + + client_state.latest_height = height; + client.client_state.insert( + Default::default(), + WrappedClientState { + inner: client_state.into(), + }, + )?; + client .consensus_states .insert(height.into(), consensus_state)?;