1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/// IBC "app handlers" for the IBC component.
///
/// An app handler defines an interface for any IBC application to consume verified IBC events from
/// the core IBC component. IBC applications listen to channel events that occur on the Port ID
/// that they have subscribed to, and apply application-specific state transition logic.
///
/// The primary IBC application is the Ics20 transfer application, which allows for interchain
/// token transfers.
use anyhow::Result;
use async_trait::async_trait;
use cnidarium::{StateRead, StateWrite};
use ibc_types::core::channel::msgs::{
    MsgAcknowledgement, MsgChannelCloseConfirm, MsgChannelCloseInit, MsgChannelOpenAck,
    MsgChannelOpenConfirm, MsgChannelOpenInit, MsgChannelOpenTry, MsgRecvPacket, MsgTimeout,
};

/// AppHandlerCheck defines the interface for an IBC application to consume IBC channel and packet
/// events, and apply their validation logic. This validation logic is used for stateful validation
/// only.
#[async_trait]
pub trait AppHandlerCheck: Send + Sync {
    async fn chan_open_init_check<S: StateRead>(state: S, msg: &MsgChannelOpenInit) -> Result<()>;
    async fn chan_open_try_check<S: StateRead>(state: S, msg: &MsgChannelOpenTry) -> Result<()>;
    async fn chan_open_ack_check<S: StateRead>(state: S, msg: &MsgChannelOpenAck) -> Result<()>;
    async fn chan_open_confirm_check<S: StateRead>(
        state: S,
        msg: &MsgChannelOpenConfirm,
    ) -> Result<()>;
    async fn chan_close_confirm_check<S: StateRead>(
        state: S,
        msg: &MsgChannelCloseConfirm,
    ) -> Result<()>;
    async fn chan_close_init_check<S: StateRead>(state: S, msg: &MsgChannelCloseInit)
        -> Result<()>;

    async fn recv_packet_check<S: StateRead>(state: S, msg: &MsgRecvPacket) -> Result<()>;
    async fn timeout_packet_check<S: StateRead>(state: S, msg: &MsgTimeout) -> Result<()>;
    async fn acknowledge_packet_check<S: StateRead>(
        state: S,
        msg: &MsgAcknowledgement,
    ) -> Result<()>;
}

// AppHandlerExecute defines the interface for an IBC application to consume IBC channel and packet
// events and apply their state transition logic. The IBC component will only call these methods
// once the transaction has been validated using the AppHandlerCheck interface.
#[async_trait]
pub trait AppHandlerExecute: Send + Sync {
    async fn chan_open_init_execute<S: StateWrite>(state: S, msg: &MsgChannelOpenInit);
    async fn chan_open_try_execute<S: StateWrite>(state: S, msg: &MsgChannelOpenTry);
    async fn chan_open_ack_execute<S: StateWrite>(state: S, msg: &MsgChannelOpenAck);
    async fn chan_open_confirm_execute<S: StateWrite>(state: S, msg: &MsgChannelOpenConfirm);
    async fn chan_close_confirm_execute<S: StateWrite>(state: S, msg: &MsgChannelCloseConfirm);
    async fn chan_close_init_execute<S: StateWrite>(state: S, msg: &MsgChannelCloseInit);

    async fn recv_packet_execute<S: StateWrite>(state: S, msg: &MsgRecvPacket) -> Result<()>;
    async fn timeout_packet_execute<S: StateWrite>(state: S, msg: &MsgTimeout) -> Result<()>;
    async fn acknowledge_packet_execute<S: StateWrite>(
        state: S,
        msg: &MsgAcknowledgement,
    ) -> Result<()>;
}

pub trait AppHandler: AppHandlerCheck + AppHandlerExecute {}