ibc-test-framework 0.32.2

Framework for writing integration tests for IBC relayers
use crate::chain::cli::authz::{authz_grant, exec_grant, query_authz_grant};
use crate::chain::cli::transfer::generate_transfer_from_chain_tx;
use crate::error::Error;
use crate::prelude::*;
use crate::types::tagged::MonoTagged;

use super::bootstrap::ChainBootstrapMethodsExt;

const WAIT_GRANT_ATTEMPTS: u16 = 5;

pub trait AuthzMethodsExt<Chain> {
    fn authz_grant(
        &self,
        granter: &str,
        grantee: &str,
        msg_type: &str,
        fees: &str,
    ) -> Result<(), Error>;

    fn assert_eventual_grant(
        &self,
        granter: &str,
        grantee: &str,
        msg_type: &str,
    ) -> Result<(), Error>;

    fn exec_ibc_transfer_grant<Counterparty>(
        &self,
        granter: &str,
        grantee: &str,
        port: &PortId,
        channel: &ChannelId,
        recipient: &MonoTagged<Counterparty, &WalletAddress>,
        token: &TaggedTokenRef<Chain>,
        fees: &str,
    ) -> Result<(), Error>;
}

impl<Chain: Send> AuthzMethodsExt<Chain> for MonoTagged<Chain, &ChainDriver> {
    fn authz_grant(
        &self,
        granter: &str,
        grantee: &str,
        msg_type: &str,
        fees: &str,
    ) -> Result<(), Error> {
        authz_grant(
            self.value().chain_id.as_str(),
            &self.value().command_path,
            &self.value().home_path,
            &self.value().rpc_listen_address(),
            granter,
            grantee,
            msg_type,
            fees,
        )
    }

    fn assert_eventual_grant(
        &self,
        granter: &str,
        grantee: &str,
        msg_type: &str,
    ) -> Result<(), Error> {
        assert_eventually_succeed(
            &format!("successful grant from granter {granter} to grantee {grantee}"),
            WAIT_GRANT_ATTEMPTS,
            Duration::from_secs(1),
            || {
                query_authz_grant(
                    self.value().chain_id.as_str(),
                    &self.value().command_path,
                    &self.value().home_path,
                    &self.value().rpc_listen_address(),
                    granter,
                    grantee,
                    msg_type,
                )
            },
        )?;

        Ok(())
    }

    fn exec_ibc_transfer_grant<Counterparty>(
        &self,
        granter: &str,
        grantee: &str,
        port: &PortId,
        channel: &ChannelId,
        recipient: &MonoTagged<Counterparty, &WalletAddress>,
        token: &TaggedTokenRef<Chain>,
        fees: &str,
    ) -> Result<(), Error> {
        let ibc_transfer_tx = generate_transfer_from_chain_tx(
            self.value().chain_id.as_str(),
            &self.value().command_path,
            &self.value().home_path,
            &self.value().rpc_listen_address(),
            granter,
            port.as_ref(),
            channel.as_ref(),
            recipient.value().as_str(),
            &token.value().to_string(),
        )?;

        let ibc_transfer_tx_filename = "ibc-transfer.json";

        self.value()
            .write_file(ibc_transfer_tx_filename, &ibc_transfer_tx)?;

        exec_grant(
            self.value().chain_id.as_str(),
            &self.value().command_path,
            &self.value().home_path,
            &self.value().rpc_listen_address(),
            &format!("{}/{ibc_transfer_tx_filename}", self.value().home_path),
            grantee,
            fees,
        )?;

        Ok(())
    }
}