penumbra_sdk_ibc/component/msg_handler/
connection_open_init.rs1use anyhow::{Context, Result};
2use async_trait::async_trait;
3use ibc_types::core::connection::{
4 events, msgs::MsgConnectionOpenInit, ConnectionEnd, ConnectionId, Version,
5};
6
7use crate::component::{
8 client::StateReadExt as _,
9 connection::{StateReadExt as _, StateWriteExt as _},
10 connection_counter::SUPPORTED_VERSIONS,
11 MsgHandler,
12};
13
14use cnidarium::StateWrite;
15use ibc_types::core::connection::State as ConnectionState;
16
17#[async_trait]
18impl MsgHandler for MsgConnectionOpenInit {
19 async fn check_stateless<H>(&self) -> Result<()> {
20 version_is_supported(self)?;
21
22 Ok(())
23 }
24
25 async fn try_execute<S: StateWrite, AH, HI>(&self, mut state: S) -> Result<()> {
26 tracing::debug!(msg = ?self);
27
28 state.get_client_state(&self.client_id_on_a).await?;
30 state.get_client_type(&self.client_id_on_a).await?;
31
32 let connection_id = ConnectionId::new(
33 state
34 .get_connection_counter()
35 .await
36 .context("unable to get connection counter")?
37 .0,
38 );
39
40 let compatible_versions = vec![Version::default()];
41
42 let new_connection_end = ConnectionEnd {
43 state: ConnectionState::Init,
44 client_id: self.client_id_on_a.clone(),
45 counterparty: self.counterparty.clone(),
46 versions: compatible_versions,
47 delay_period: self.delay_period,
48 };
49
50 state
52 .put_new_connection(&connection_id, new_connection_end)
53 .await
54 .context("unable to put new connection")?;
55
56 state.record(
57 events::ConnectionOpenInit {
58 connection_id: connection_id.clone(),
59 client_id_on_a: self.client_id_on_a.clone(),
60 client_id_on_b: self.counterparty.client_id.clone(),
61 }
62 .into(),
63 );
64
65 Ok(())
66 }
67}
68
69fn version_is_supported(msg: &MsgConnectionOpenInit) -> anyhow::Result<()> {
70 if msg.version.is_none() {
75 return Ok(());
76 }
77
78 if !SUPPORTED_VERSIONS.contains(
79 msg.version
80 .as_ref()
81 .ok_or_else(|| anyhow::anyhow!("invalid version"))?,
82 ) {
83 Err(anyhow::anyhow!(
84 "unsupported version: in ConnectionOpenInit",
85 ))
86 } else {
87 Ok(())
88 }
89}