penumbra_sdk_stake/undelegate_claim/
action.rs1use penumbra_sdk_asset::balance;
2use penumbra_sdk_proto::{penumbra::core::component::stake::v1 as pb, DomainType};
3use penumbra_sdk_txhash::{EffectHash, EffectingData};
4use serde::{Deserialize, Serialize};
5
6use crate::{IdentityKey, Penalty, UndelegateClaimProof};
7
8#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
9#[serde(try_from = "pb::UndelegateClaimBody", into = "pb::UndelegateClaimBody")]
10pub struct UndelegateClaimBody {
11 pub validator_identity: IdentityKey,
13 pub penalty: Penalty,
15 pub balance_commitment: balance::Commitment,
17 pub unbonding_start_height: u64,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
22#[serde(try_from = "pb::UndelegateClaim", into = "pb::UndelegateClaim")]
23pub struct UndelegateClaim {
24 pub body: UndelegateClaimBody,
25 pub proof: UndelegateClaimProof,
26}
27
28impl EffectingData for UndelegateClaimBody {
29 fn effect_hash(&self) -> EffectHash {
30 EffectHash::from_proto_effecting_data(&self.to_proto())
31 }
32}
33impl EffectingData for UndelegateClaim {
34 fn effect_hash(&self) -> EffectHash {
35 self.body.effect_hash()
38 }
39}
40
41impl DomainType for UndelegateClaimBody {
42 type Proto = pb::UndelegateClaimBody;
43}
44
45impl From<UndelegateClaimBody> for pb::UndelegateClaimBody {
46 #[allow(deprecated)]
47 fn from(d: UndelegateClaimBody) -> Self {
48 pb::UndelegateClaimBody {
49 validator_identity: Some(d.validator_identity.into()),
50 start_epoch_index: 0,
51 penalty: Some(d.penalty.into()),
52 balance_commitment: Some(d.balance_commitment.into()),
53 unbonding_start_height: d.unbonding_start_height,
54 }
55 }
56}
57
58impl TryFrom<pb::UndelegateClaimBody> for UndelegateClaimBody {
59 type Error = anyhow::Error;
60 fn try_from(d: pb::UndelegateClaimBody) -> Result<Self, Self::Error> {
61 Ok(Self {
62 validator_identity: d
63 .validator_identity
64 .ok_or_else(|| anyhow::anyhow!("missing validator identity"))?
65 .try_into()?,
66 penalty: d
67 .penalty
68 .ok_or_else(|| anyhow::anyhow!("missing penalty"))?
69 .try_into()?,
70 balance_commitment: d
71 .balance_commitment
72 .ok_or_else(|| anyhow::anyhow!("missing balance_commitment"))?
73 .try_into()?,
74 unbonding_start_height: d.unbonding_start_height,
75 })
76 }
77}
78
79impl DomainType for UndelegateClaim {
80 type Proto = pb::UndelegateClaim;
81}
82
83impl From<UndelegateClaim> for pb::UndelegateClaim {
84 fn from(d: UndelegateClaim) -> Self {
85 pb::UndelegateClaim {
86 body: Some(d.body.into()),
87 proof: d.proof.encode_to_vec(),
88 }
89 }
90}
91
92impl TryFrom<pb::UndelegateClaim> for UndelegateClaim {
93 type Error = anyhow::Error;
94 fn try_from(d: pb::UndelegateClaim) -> Result<Self, Self::Error> {
95 Ok(Self {
96 body: d
97 .body
98 .ok_or_else(|| anyhow::anyhow!("missing body"))?
99 .try_into()?,
100 proof: UndelegateClaimProof::decode(d.proof.as_slice())?,
101 })
102 }
103}