abci-rs 0.11.3

A Rust crate for creating ABCI applications
Documentation
use std::sync::Arc;

#[cfg(feature = "use-async-std")]
use async_std::task::spawn_blocking;
use async_trait::async_trait;
#[cfg(feature = "use-smol")]
use smol::unblock as spawn_blocking;
#[cfg(feature = "use-tokio")]
use tokio::task::spawn_blocking;

use crate::{
    async_api::{
        Consensus as AsyncConsensus, Info as AsyncInfo, Mempool as AsyncMempool,
        Snapshot as AsyncSnapshot,
    },
    sync_api::{Consensus, Info, Mempool, Snapshot},
    types::*,
};

macro_rules! spawn_blocking {
    ($expr: expr) => {{
        cfg_if::cfg_if! {
            if #[cfg(any(feature = "use-async-std", feature = "use-smol"))] {
                spawn_blocking($expr).await
            } else if #[cfg(feature = "use-tokio")] {
                spawn_blocking($expr).await.expect("Failed to execute blocking task")
            }
        }
    }};
}

pub struct AsyncConsensusImpl<C>
where
    C: Consensus + Send + Sync + 'static,
{
    inner: Arc<C>,
}

impl<C> AsyncConsensusImpl<C>
where
    C: Consensus + Send + Sync,
{
    pub fn new(inner: C) -> Self {
        Self {
            inner: Arc::new(inner),
        }
    }
}

#[async_trait]
impl<C> AsyncConsensus for AsyncConsensusImpl<C>
where
    C: Consensus + Send + Sync + 'static,
{
    async fn echo(&self, echo_request: RequestEcho) -> ResponseEcho {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.echo(echo_request))
    }

    async fn init_chain(&self, init_chain_request: RequestInitChain) -> ResponseInitChain {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.init_chain(init_chain_request))
    }

    async fn begin_block(&self, begin_block_request: RequestBeginBlock) -> ResponseBeginBlock {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.begin_block(begin_block_request))
    }

    async fn deliver_tx(&self, deliver_tx_request: RequestDeliverTx) -> ResponseDeliverTx {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.deliver_tx(deliver_tx_request))
    }

    async fn end_block(&self, end_block_request: RequestEndBlock) -> ResponseEndBlock {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.end_block(end_block_request))
    }

    async fn commit(&self, commit_request: RequestCommit) -> ResponseCommit {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.commit(commit_request))
    }

    async fn flush(&self, flush_request: RequestFlush) -> ResponseFlush {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.flush(flush_request))
    }
}

pub struct AsyncInfoImpl<I>
where
    I: Info + Send + Sync + 'static,
{
    inner: Arc<I>,
}

impl<I> AsyncInfoImpl<I>
where
    I: Info + Send + Sync,
{
    pub fn new(inner: I) -> Self {
        Self {
            inner: Arc::new(inner),
        }
    }
}

#[async_trait]
impl<I> AsyncInfo for AsyncInfoImpl<I>
where
    I: Info + Send + Sync + 'static,
{
    async fn echo(&self, echo_request: RequestEcho) -> ResponseEcho {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.echo(echo_request))
    }

    async fn info(&self, info_request: RequestInfo) -> ResponseInfo {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.info(info_request))
    }

    async fn set_option(&self, set_option_request: RequestSetOption) -> ResponseSetOption {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.set_option(set_option_request))
    }

    async fn query(&self, query_request: RequestQuery) -> ResponseQuery {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.query(query_request))
    }

    async fn flush(&self, flush_request: RequestFlush) -> ResponseFlush {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.flush(flush_request))
    }
}

pub struct AsyncMempoolImpl<M>
where
    M: Mempool + Send + Sync + 'static,
{
    inner: Arc<M>,
}

impl<M> AsyncMempoolImpl<M>
where
    M: Mempool + Send + Sync,
{
    pub fn new(inner: M) -> Self {
        Self {
            inner: Arc::new(inner),
        }
    }
}

#[async_trait]
impl<M> AsyncMempool for AsyncMempoolImpl<M>
where
    M: Mempool + Send + Sync + 'static,
{
    async fn echo(&self, echo_request: RequestEcho) -> ResponseEcho {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.echo(echo_request))
    }

    async fn check_tx(&self, check_tx_request: RequestCheckTx) -> ResponseCheckTx {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.check_tx(check_tx_request))
    }

    async fn flush(&self, flush_request: RequestFlush) -> ResponseFlush {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.flush(flush_request))
    }
}

pub struct AsyncSnapshotImpl<S>
where
    S: Snapshot + Send + Sync + 'static,
{
    inner: Arc<S>,
}

impl<S> AsyncSnapshotImpl<S>
where
    S: Snapshot + Send + Sync,
{
    pub fn new(inner: S) -> Self {
        Self {
            inner: Arc::new(inner),
        }
    }
}

#[async_trait]
impl<S> AsyncSnapshot for AsyncSnapshotImpl<S>
where
    S: Snapshot + Send + Sync + 'static,
{
    async fn echo(&self, echo_request: RequestEcho) -> ResponseEcho {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.echo(echo_request))
    }

    async fn list_snapshots(
        &self,
        list_snapshots_request: RequestListSnapshots,
    ) -> ResponseListSnapshots {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.list_snapshots(list_snapshots_request))
    }

    async fn offer_snapshot(
        &self,
        offer_snapshot_request: RequestOfferSnapshot,
    ) -> ResponseOfferSnapshot {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.offer_snapshot(offer_snapshot_request))
    }

    async fn load_snapshot_chunk(
        &self,
        load_snapshot_chunk_request: RequestLoadSnapshotChunk,
    ) -> ResponseLoadSnapshotChunk {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.load_snapshot_chunk(load_snapshot_chunk_request))
    }

    async fn apply_snapshot_chunk(
        &self,
        apply_snapshot_chunk_request: RequestApplySnapshotChunk,
    ) -> ResponseApplySnapshotChunk {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.apply_snapshot_chunk(apply_snapshot_chunk_request))
    }

    async fn flush(&self, flush_request: RequestFlush) -> ResponseFlush {
        let inner = self.inner.clone();
        spawn_blocking!(move || inner.flush(flush_request))
    }
}