penumbra_sdk_governance/proposal_submit/
action.rs1use serde::{Deserialize, Serialize};
2
3use penumbra_sdk_asset::{Balance, Value, STAKING_TOKEN_ASSET_ID};
4use penumbra_sdk_num::Amount;
5use penumbra_sdk_proto::{penumbra::core::component::governance::v1 as pb, DomainType};
6use penumbra_sdk_txhash::{EffectHash, EffectingData};
7
8use crate::proposal::Proposal;
9
10use crate::ProposalNft;
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
16#[serde(try_from = "pb::ProposalSubmit", into = "pb::ProposalSubmit")]
17pub struct ProposalSubmit {
18 pub proposal: Proposal,
20 pub deposit_amount: Amount,
22}
23
24impl EffectingData for ProposalSubmit {
25 fn effect_hash(&self) -> EffectHash {
26 EffectHash::from_proto_effecting_data(&self.to_proto())
27 }
28}
29
30impl ProposalSubmit {
31 pub fn balance(&self) -> Balance {
33 let deposit = self.deposit_value();
34 let proposal_nft = self.proposal_nft_value();
35
36 Balance::from(proposal_nft) - Balance::from(deposit)
40 }
41
42 fn deposit_value(&self) -> Value {
44 Value {
45 amount: self.deposit_amount,
46 asset_id: *STAKING_TOKEN_ASSET_ID,
47 }
48 }
49
50 pub fn proposal_nft_value(&self) -> Value {
52 Value {
53 amount: Amount::from(1u64),
54 asset_id: ProposalNft::deposit(self.proposal.id).denom().into(),
55 }
56 }
57}
58
59impl From<ProposalSubmit> for pb::ProposalSubmit {
60 fn from(value: ProposalSubmit) -> pb::ProposalSubmit {
61 pb::ProposalSubmit {
62 proposal: Some(value.proposal.into()),
63 deposit_amount: Some(value.deposit_amount.into()),
64 }
65 }
66}
67
68impl TryFrom<pb::ProposalSubmit> for ProposalSubmit {
69 type Error = anyhow::Error;
70
71 fn try_from(msg: pb::ProposalSubmit) -> Result<Self, Self::Error> {
72 Ok(ProposalSubmit {
73 proposal: msg
74 .proposal
75 .ok_or_else(|| anyhow::anyhow!("missing proposal in `Propose`"))?
76 .try_into()?,
77 deposit_amount: msg
78 .deposit_amount
79 .ok_or_else(|| anyhow::anyhow!("missing deposit amount in `Propose`"))?
80 .try_into()?,
81 })
82 }
83}
84
85impl DomainType for ProposalSubmit {
86 type Proto = pb::ProposalSubmit;
87}