penumbra_sdk_ibc/component/action_handler/
ibc_action.rs1use std::sync::Arc;
2
3use anyhow::{ensure, Context, Result};
4use cnidarium::{StateRead, StateWrite};
5
6use crate::{
7 component::{app_handler::AppHandler, HostInterface, MsgHandler as _},
8 IbcRelay, IbcRelayWithHandlers, StateReadExt as _,
9};
10
11impl<AH: AppHandler, HI: HostInterface> IbcRelayWithHandlers<AH, HI> {
12 pub async fn check_stateless(&self, _context: ()) -> Result<()> {
13 let action = self.action();
14 match action {
15 IbcRelay::CreateClient(msg) => msg.check_stateless::<AH>().await?,
16 IbcRelay::UpdateClient(msg) => msg.check_stateless::<AH>().await?,
17 IbcRelay::UpgradeClient(msg) => msg.check_stateless::<AH>().await?,
18 IbcRelay::SubmitMisbehavior(msg) => msg.check_stateless::<AH>().await?,
19 IbcRelay::ConnectionOpenInit(msg) => msg.check_stateless::<AH>().await?,
20 IbcRelay::ConnectionOpenTry(msg) => msg.check_stateless::<AH>().await?,
21 IbcRelay::ConnectionOpenAck(msg) => msg.check_stateless::<AH>().await?,
22 IbcRelay::ConnectionOpenConfirm(msg) => msg.check_stateless::<AH>().await?,
23 IbcRelay::ChannelOpenInit(msg) => msg.check_stateless::<AH>().await?,
24 IbcRelay::ChannelOpenTry(msg) => msg.check_stateless::<AH>().await?,
25 IbcRelay::ChannelOpenAck(msg) => msg.check_stateless::<AH>().await?,
26 IbcRelay::ChannelOpenConfirm(msg) => msg.check_stateless::<AH>().await?,
27 IbcRelay::ChannelCloseInit(msg) => msg.check_stateless::<AH>().await?,
28 IbcRelay::ChannelCloseConfirm(msg) => msg.check_stateless::<AH>().await?,
29 IbcRelay::RecvPacket(msg) => msg.check_stateless::<AH>().await?,
30 IbcRelay::Acknowledgement(msg) => msg.check_stateless::<AH>().await?,
31 IbcRelay::Timeout(msg) => msg.check_stateless::<AH>().await?,
32 IbcRelay::Unknown(msg) => {
33 anyhow::bail!("unknown IBC message type: {}", msg.type_url)
34 }
35 }
36
37 Ok(())
38 }
39
40 pub async fn check_historical<S: StateRead + 'static>(&self, state: Arc<S>) -> Result<()> {
41 ensure!(
44 state.get_ibc_params().await?.ibc_enabled,
45 "transaction contains IBC actions, but IBC is not enabled"
46 );
47 Ok(())
48 }
49
50 pub async fn check_and_execute<S: StateWrite>(&self, state: S) -> Result<()> {
51 let action = self.action();
52 match action {
53 IbcRelay::CreateClient(msg) => msg
54 .try_execute::<S, AH, HI>(state)
55 .await
56 .context("failed to execute MsgCreateClient")?,
57 IbcRelay::UpdateClient(msg) => msg
58 .try_execute::<S, AH, HI>(state)
59 .await
60 .context("failed to execute MsgUpdateClient")?,
61 IbcRelay::UpgradeClient(msg) => msg
62 .try_execute::<S, AH, HI>(state)
63 .await
64 .context("failed to execute MsgUpgradeClient")?,
65 IbcRelay::SubmitMisbehavior(msg) => msg
66 .try_execute::<S, AH, HI>(state)
67 .await
68 .context("failed to execute MsgSubmitMisbehaviour")?,
69 IbcRelay::ConnectionOpenInit(msg) => msg
70 .try_execute::<S, AH, HI>(state)
71 .await
72 .context("failed to execute MsgConnectionOpenInit")?,
73 IbcRelay::ConnectionOpenTry(msg) => msg
74 .try_execute::<S, AH, HI>(state)
75 .await
76 .context("failed to execute MsgConnectionOpenTry")?,
77 IbcRelay::ConnectionOpenAck(msg) => msg
78 .try_execute::<S, AH, HI>(state)
79 .await
80 .context("failed to execute MsgConnectionOpenAck")?,
81 IbcRelay::ConnectionOpenConfirm(msg) => msg
82 .try_execute::<S, AH, HI>(state)
83 .await
84 .context("failed to execute MsgConnectionOpenConfirm")?,
85 IbcRelay::ChannelOpenInit(msg) => msg
86 .try_execute::<S, AH, HI>(state)
87 .await
88 .context("failed to execute MsgChannelOpenInit")?,
89 IbcRelay::ChannelOpenTry(msg) => msg
90 .try_execute::<S, AH, HI>(state)
91 .await
92 .context("failed to execute MsgChannelOpenTry")?,
93 IbcRelay::ChannelOpenAck(msg) => msg
94 .try_execute::<S, AH, HI>(state)
95 .await
96 .context("failed to execute MsgChannelOpenAck")?,
97 IbcRelay::ChannelOpenConfirm(msg) => msg
98 .try_execute::<S, AH, HI>(state)
99 .await
100 .context("failed to execute MsgChannelOpenConfirm")?,
101 IbcRelay::ChannelCloseInit(msg) => msg
102 .try_execute::<S, AH, HI>(state)
103 .await
104 .context("failed to execute MsgChannelCloseInit")?,
105 IbcRelay::ChannelCloseConfirm(msg) => msg
106 .try_execute::<S, AH, HI>(state)
107 .await
108 .context("failed to execute MsgChannelCloseConfirm")?,
109 IbcRelay::RecvPacket(msg) => msg
110 .try_execute::<S, AH, HI>(state)
111 .await
112 .context("failed to execute MsgRecvPacket")?,
113 IbcRelay::Acknowledgement(msg) => msg
114 .try_execute::<S, AH, HI>(state)
115 .await
116 .context("failed to execute MsgAcknowledgement")?,
117 IbcRelay::Timeout(msg) => msg
118 .try_execute::<S, AH, HI>(state)
119 .await
120 .context("failed to execute MsgTimeout")?,
121 IbcRelay::Unknown(msg) => {
122 anyhow::bail!("unknown IBC message type: {}", msg.type_url)
123 }
124 }
125
126 Ok(())
127 }
128}