From 298ee4509e33da9b6bd2205f1c2ed93d3532de4c Mon Sep 17 00:00:00 2001 From: redshiftzero Date: Thu, 21 Sep 2023 14:38:54 -0400 Subject: [PATCH] governance: move DAO related view functions to app crate The reason for this is that previously the `put_dao_transaction` and `pending_dao_transactions` methods were defined in the `StateReadExt` and `StateWriteExt` traits in `penumbra-governance`. However, they require `Transaction` from `penumbra-transaction` which would result in a circular dependency. Instead, we make a tiny extension trait in the app crate with these two functions. --- .../app/src/action_handler/actions/submit.rs | 1 + crates/core/app/src/app/mod.rs | 1 + crates/core/app/src/dao_ext.rs | 53 +++++++++++++++++++ crates/core/app/src/lib.rs | 2 + 4 files changed, 57 insertions(+) create mode 100644 crates/core/app/src/dao_ext.rs diff --git a/crates/core/app/src/action_handler/actions/submit.rs b/crates/core/app/src/action_handler/actions/submit.rs index 0d842d7368..ffec362be4 100644 --- a/crates/core/app/src/action_handler/actions/submit.rs +++ b/crates/core/app/src/action_handler/actions/submit.rs @@ -20,6 +20,7 @@ use penumbra_transaction::Transaction; use penumbra_transaction::{AuthorizationData, WitnessData}; use crate::action_handler::ActionHandler; +use crate::dao_ext::DaoStateWriteExt; use penumbra_governance::{ component::{StateReadExt as _, StateWriteExt as _}, proposal::{Proposal, ProposalPayload}, diff --git a/crates/core/app/src/app/mod.rs b/crates/core/app/src/app/mod.rs index ad726a3805..f375a08c4d 100644 --- a/crates/core/app/src/app/mod.rs +++ b/crates/core/app/src/app/mod.rs @@ -24,6 +24,7 @@ use tendermint::validator::Update; use tracing::Instrument; use crate::action_handler::ActionHandler; +use crate::DaoStateReadExt; pub mod state_key; diff --git a/crates/core/app/src/dao_ext.rs b/crates/core/app/src/dao_ext.rs new file mode 100644 index 0000000000..a08255e142 --- /dev/null +++ b/crates/core/app/src/dao_ext.rs @@ -0,0 +1,53 @@ +use anyhow::Result; +use async_trait::async_trait; + +use futures::{StreamExt, TryStreamExt}; +use penumbra_chain::component::StateReadExt; +use penumbra_governance::state_key; +use penumbra_proto::{StateReadProto, StateWriteProto}; +use penumbra_storage::{StateRead, StateWrite}; +use penumbra_transaction::Transaction; + +// Note: These should live in `penumbra-governance` in the `StateReadExt` and `StateWriteExt` +// traits, however that would result in a circular dependency since the below methods +// require use of `penumbra-transaction::Transaction`, which has `penumbra-governance` as a +// dependency. + +#[async_trait] +pub trait DaoStateReadExt: StateRead + penumbra_stake::StateReadExt { + /// Get all the transactions set to be delivered in this block (scheduled in last block). + async fn pending_dao_transactions(&self) -> Result> { + // Get the proposal IDs of the DAO transactions we are about to deliver. + let prefix = state_key::deliver_dao_transactions_at_height(self.get_block_height().await?); + let proposals: Vec = self + .prefix_proto::(&prefix) + .map(|result| anyhow::Ok(result?.1)) + .try_collect() + .await?; + + // For each one, look up the corresponding built transaction, and return the list. + let mut transactions = Vec::new(); + for proposal in proposals { + transactions.push( + self.get(&state_key::dao_transaction(proposal)) + .await? + .ok_or_else(|| { + anyhow::anyhow!("no transaction found for proposal {}", proposal) + })?, + ); + } + Ok(transactions) + } +} + +impl DaoStateReadExt for T {} + +#[async_trait] +pub trait DaoStateWriteExt: StateWrite { + /// Get all the transactions set to be delivered in this block (scheduled in last block). + fn put_dao_transaction(&mut self, proposal: u64, transaction: Transaction) { + self.put(state_key::dao_transaction(proposal), transaction); + } +} + +impl DaoStateWriteExt for T {} diff --git a/crates/core/app/src/lib.rs b/crates/core/app/src/lib.rs index a128501396..160a5aed32 100644 --- a/crates/core/app/src/lib.rs +++ b/crates/core/app/src/lib.rs @@ -1,9 +1,11 @@ #![deny(clippy::unwrap_used)] mod action_handler; +mod dao_ext; mod mock_client; mod temp_storage_ext; pub use action_handler::ActionHandler; +pub use dao_ext::DaoStateReadExt; pub use mock_client::MockClient; pub use temp_storage_ext::TempStorageExt;