ibc-relayer 0.32.2

Implementation of an IBC Relayer in Rust, as a library
use tendermint::{account, block::Height};
use tendermint_light_client::{
    components::io::{AtHeight, Io, IoError, ProdIo},
    types::LightBlock,
};

#[derive(Clone, Debug)]
pub enum AnyIo {
    Prod(ProdIo),
    RestartAware(RestartAwareIo),
}

impl AnyIo {
    pub fn rpc_client(&self) -> &tendermint_rpc::HttpClient {
        match self {
            AnyIo::Prod(io) => io.rpc_client(),
            AnyIo::RestartAware(io) => io.rpc_client(),
        }
    }

    pub fn fetch_validator_set(
        &self,
        height: AtHeight,
        proposer_address: Option<account::Id>,
    ) -> Result<tendermint::validator::Set, IoError> {
        match self {
            AnyIo::Prod(io) => io.fetch_validator_set(height, proposer_address),
            AnyIo::RestartAware(io) => io.fetch_validator_set(height, proposer_address),
        }
    }
}

impl Io for AnyIo {
    fn fetch_light_block(&self, height: AtHeight) -> Result<LightBlock, IoError> {
        match self {
            AnyIo::Prod(io) => io.fetch_light_block(height),
            AnyIo::RestartAware(io) => io.fetch_light_block(height),
        }
    }
}

#[derive(Clone, Debug)]
pub struct RestartAwareIo {
    restart_height: Height,
    live_io: ProdIo,
    archive_io: ProdIo,
}

impl RestartAwareIo {
    pub fn new(restart_height: Height, live_io: ProdIo, archive_io: ProdIo) -> Self {
        Self {
            restart_height,
            live_io,
            archive_io,
        }
    }

    pub fn rpc_client(&self) -> &tendermint_rpc::HttpClient {
        self.live_io.rpc_client()
    }

    pub fn fetch_validator_set(
        &self,
        height: AtHeight,
        proposer_address: Option<account::Id>,
    ) -> Result<tendermint::validator::Set, IoError> {
        let io = match height {
            AtHeight::At(height) if height <= self.restart_height => &self.archive_io,
            _ => &self.live_io,
        };

        io.fetch_validator_set(height, proposer_address)
    }
}

impl Io for RestartAwareIo {
    fn fetch_light_block(&self, height: AtHeight) -> Result<LightBlock, IoError> {
        let io = match height {
            AtHeight::At(height) if height <= self.restart_height => &self.archive_io,
            _ => &self.live_io,
        };

        io.fetch_light_block(height)
    }
}