Skip to content

Commit

Permalink
governance: move DAO related view functions to app crate
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
redshiftzero committed Sep 21, 2023
1 parent 2406ba4 commit 298ee45
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 0 deletions.
1 change: 1 addition & 0 deletions crates/core/app/src/action_handler/actions/submit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down
1 change: 1 addition & 0 deletions crates/core/app/src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use tendermint::validator::Update;
use tracing::Instrument;

use crate::action_handler::ActionHandler;
use crate::DaoStateReadExt;

pub mod state_key;

Expand Down
53 changes: 53 additions & 0 deletions crates/core/app/src/dao_ext.rs
Original file line number Diff line number Diff line change
@@ -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<Vec<Transaction>> {
// 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<u64> = self
.prefix_proto::<u64>(&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<T: StateRead + penumbra_stake::StateReadExt + ?Sized> 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<T: StateWrite + ?Sized> DaoStateWriteExt for T {}
2 changes: 2 additions & 0 deletions crates/core/app/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down

0 comments on commit 298ee45

Please sign in to comment.