penumbra_sdk_app/
community_pool_ext.rs

1use anyhow::Result;
2use async_trait::async_trait;
3
4use cnidarium::{StateRead, StateWrite};
5use futures::{StreamExt, TryStreamExt};
6use penumbra_sdk_governance::state_key;
7use penumbra_sdk_proto::{StateReadProto, StateWriteProto};
8use penumbra_sdk_sct::component::clock::EpochRead;
9use penumbra_sdk_transaction::Transaction;
10
11// Note: These should live in `penumbra-governance` in the `StateReadExt` and `StateWriteExt`
12// traits, however that would result in a circular dependency since the below methods
13// require use of `penumbra-transaction::Transaction`, which has `penumbra-governance` as a
14// dependency.
15#[async_trait]
16pub trait CommunityPoolStateReadExt: StateRead + penumbra_sdk_stake::StateReadExt {
17    /// Get all the transactions set to be delivered in this block (scheduled in last block).
18    async fn pending_community_pool_transactions(&self) -> Result<Vec<Transaction>> {
19        // Get the proposal IDs of the Community Pool transactions we are about to deliver.
20        let prefix = state_key::deliver_community_pool_transactions_at_height(
21            self.get_block_height().await?,
22        );
23        let proposals: Vec<u64> = self
24            .prefix_proto::<u64>(&prefix)
25            .map(|result| anyhow::Ok(result?.1))
26            .try_collect()
27            .await?;
28
29        // For each one, look up the corresponding built transaction, and return the list.
30        let mut transactions = Vec::new();
31        for proposal in proposals {
32            transactions.push(
33                self.get(&state_key::community_pool_transaction(proposal))
34                    .await?
35                    .ok_or_else(|| {
36                        anyhow::anyhow!("no transaction found for proposal {}", proposal)
37                    })?,
38            );
39        }
40        Ok(transactions)
41    }
42}
43
44impl<T: StateRead + penumbra_sdk_stake::StateReadExt + ?Sized> CommunityPoolStateReadExt for T {}
45
46#[async_trait]
47pub trait CommunityPoolStateWriteExt: StateWrite {
48    /// Get all the transactions set to be delivered in this block (scheduled in last block).
49    fn put_community_pool_transaction(&mut self, proposal: u64, transaction: Transaction) {
50        self.put(state_key::community_pool_transaction(proposal), transaction);
51    }
52}
53
54impl<T: StateWrite + ?Sized> CommunityPoolStateWriteExt for T {}