penumbra_governance/action_handler/
deposit_claim.rsuse anyhow::Result;
use async_trait::async_trait;
use cnidarium::StateWrite;
use penumbra_proto::StateWriteProto as _;
use penumbra_shielded_pool::component::AssetRegistry;
use crate::action_handler::ActionHandler;
use crate::component::{StateReadExt as _, StateWriteExt as _};
use crate::event;
use crate::{
proposal_state::Outcome, proposal_state::State as ProposalState, ProposalDepositClaim,
ProposalNft,
};
#[async_trait]
impl ActionHandler for ProposalDepositClaim {
type CheckStatelessContext = ();
async fn check_stateless(&self, _context: ()) -> Result<()> {
Ok(())
}
async fn check_and_execute<S: StateWrite>(&self, mut state: S) -> Result<()> {
state.check_proposal_claimable(self.proposal).await?;
state
.check_proposal_claim_valid_deposit(self.proposal, self.deposit_amount)
.await?;
let ProposalDepositClaim {
proposal,
deposit_amount: _, outcome: resupplied_outcome,
} = self;
if let Some(ProposalState::Finished { outcome }) = state.proposal_state(*proposal).await? {
if *resupplied_outcome != outcome.as_ref().map(|_| ()) {
anyhow::bail!(
"proposal {} has outcome {:?}, but deposit claim has outcome {:?}",
proposal,
outcome,
resupplied_outcome
);
}
state
.register_denom(
&match &outcome {
Outcome::Passed => ProposalNft::passed(*proposal),
Outcome::Failed { .. } => ProposalNft::failed(*proposal),
Outcome::Slashed { .. } => ProposalNft::slashed(*proposal),
}
.denom(),
)
.await;
state.put_proposal_state(*proposal, ProposalState::Claimed { outcome });
state.record_proto(event::proposal_deposit_claim(self));
} else {
anyhow::bail!("proposal {} is not in finished state", proposal);
}
Ok(())
}
}