penumbra_governance/proposal_withdraw/
action.rsuse serde::{Deserialize, Serialize};
use penumbra_asset::{Balance, Value};
use penumbra_num::Amount;
use penumbra_proto::{penumbra::core::component::governance::v1 as pb, DomainType};
use penumbra_txhash::{EffectHash, EffectingData};
use crate::ProposalNft;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(try_from = "pb::ProposalWithdraw", into = "pb::ProposalWithdraw")]
pub struct ProposalWithdraw {
pub proposal: u64,
pub reason: String,
}
impl EffectingData for ProposalWithdraw {
fn effect_hash(&self) -> EffectHash {
EffectHash::from_proto_effecting_data(&self.to_proto())
}
}
impl From<ProposalWithdraw> for pb::ProposalWithdraw {
fn from(value: ProposalWithdraw) -> pb::ProposalWithdraw {
pb::ProposalWithdraw {
proposal: value.proposal,
reason: value.reason,
}
}
}
impl ProposalWithdraw {
pub fn balance(&self) -> Balance {
let voting_proposal_nft = self.voting_proposal_nft_value();
let withdrawn_proposal_nft = self.withdrawn_proposal_nft();
Balance::from(withdrawn_proposal_nft) - Balance::from(voting_proposal_nft)
}
fn voting_proposal_nft_value(&self) -> Value {
Value {
amount: Amount::from(1u64),
asset_id: ProposalNft::deposit(self.proposal).denom().into(),
}
}
fn withdrawn_proposal_nft(&self) -> Value {
Value {
amount: Amount::from(1u64),
asset_id: ProposalNft::unbonding_deposit(self.proposal).denom().into(),
}
}
}
impl TryFrom<pb::ProposalWithdraw> for ProposalWithdraw {
type Error = anyhow::Error;
fn try_from(msg: pb::ProposalWithdraw) -> Result<Self, Self::Error> {
Ok(ProposalWithdraw {
proposal: msg.proposal,
reason: msg.reason,
})
}
}
impl DomainType for ProposalWithdraw {
type Proto = pb::ProposalWithdraw;
}