penumbra_sdk_app/
action_handler.rs

1use std::sync::Arc;
2
3use anyhow::Result;
4use async_trait::async_trait;
5use cnidarium::{StateRead, StateWrite};
6
7mod actions;
8mod transaction;
9
10/// Stub: to be replaced with impls of cnidarium_component::ActionHandler
11///
12/// This trait should move to that crate, but the orphan rules make it tricky to
13/// move it before we finish splitting all the crates: if we move the trait now,
14/// existing impls in this crate on foreign types will all break. But without
15/// moving it, we can't start splitting up the crate at all.  Solution:
16/// duplicate the trait here and there, and provide a generic impl of this trait
17/// for anything implementing the copy of the trait in the other crate.  Later,
18/// we can delete this trait entirely.
19///
20/// Currently, there are only three impls, all of which are entangled with app-level data:
21///
22/// - ProposalSubmit (which is entangled with the whole-application state)
23/// - Action (which needs to slot in the PenumbraHost for IBC action handling)
24/// - Transaction (which depends on the above)
25#[async_trait]
26pub trait AppActionHandler {
27    type CheckStatelessContext: Clone + Send + Sync + 'static;
28    async fn check_stateless(&self, context: Self::CheckStatelessContext) -> Result<()>;
29    async fn check_historical<S: StateRead + 'static>(&self, _state: Arc<S>) -> Result<()> {
30        return Ok(());
31    }
32    async fn check_and_execute<S: StateWrite>(&self, state: S) -> Result<()>;
33}
34
35use cnidarium_component::ActionHandler as ComponentActionHandler;
36
37#[async_trait]
38impl<'a, T: ComponentActionHandler + Sync> AppActionHandler for crate::Compat<'a, T> {
39    type CheckStatelessContext = T::CheckStatelessContext;
40    async fn check_stateless(&self, context: Self::CheckStatelessContext) -> Result<()> {
41        ComponentActionHandler::check_stateless(self.0, context).await
42    }
43    async fn check_historical<S: StateRead + 'static>(&self, state: Arc<S>) -> Result<()> {
44        ComponentActionHandler::check_historical(self.0, state).await
45    }
46    async fn check_and_execute<S: StateWrite>(&self, state: S) -> Result<()> {
47        ComponentActionHandler::check_and_execute(self.0, state).await
48    }
49}