penumbra_sdk_stake/
event.rs

1use crate::{
2    rate::RateData,
3    validator::{BondingState, State, Validator},
4    Delegate, IdentityKey, Penalty, Undelegate,
5};
6use anyhow::{anyhow, Context as _};
7use penumbra_sdk_num::Amount;
8use penumbra_sdk_proto::{core::component::stake::v1 as pb, DomainType, Name as _};
9use tendermint::abci::types::Misbehavior;
10
11#[derive(Clone, Debug)]
12pub struct EventValidatorStateChange {
13    pub identity_key: IdentityKey,
14    pub state: State,
15}
16
17impl TryFrom<pb::EventValidatorStateChange> for EventValidatorStateChange {
18    type Error = anyhow::Error;
19
20    fn try_from(value: pb::EventValidatorStateChange) -> Result<Self, Self::Error> {
21        fn inner(
22            value: pb::EventValidatorStateChange,
23        ) -> anyhow::Result<EventValidatorStateChange> {
24            Ok(EventValidatorStateChange {
25                identity_key: value
26                    .identity_key
27                    .ok_or(anyhow!("missing `identity_key`"))?
28                    .try_into()?,
29                state: value.state.ok_or(anyhow!("missing `state`"))?.try_into()?,
30            })
31        }
32        inner(value).context(format!("parsing {}", pb::EventValidatorStateChange::NAME))
33    }
34}
35
36impl From<EventValidatorStateChange> for pb::EventValidatorStateChange {
37    fn from(value: EventValidatorStateChange) -> Self {
38        Self {
39            identity_key: Some(value.identity_key.into()),
40            state: Some(value.state.into()),
41        }
42    }
43}
44
45impl DomainType for EventValidatorStateChange {
46    type Proto = pb::EventValidatorStateChange;
47}
48
49#[derive(Clone, Debug)]
50pub struct EventValidatorVotingPowerChange {
51    pub identity_key: IdentityKey,
52    pub voting_power: Amount,
53}
54
55impl TryFrom<pb::EventValidatorVotingPowerChange> for EventValidatorVotingPowerChange {
56    type Error = anyhow::Error;
57
58    fn try_from(value: pb::EventValidatorVotingPowerChange) -> Result<Self, Self::Error> {
59        fn inner(
60            value: pb::EventValidatorVotingPowerChange,
61        ) -> anyhow::Result<EventValidatorVotingPowerChange> {
62            Ok(EventValidatorVotingPowerChange {
63                identity_key: value
64                    .identity_key
65                    .ok_or(anyhow!("missing `identity_key`"))?
66                    .try_into()?,
67                voting_power: value
68                    .voting_power
69                    .ok_or(anyhow!("missing `voting_power`"))?
70                    .try_into()?,
71            })
72        }
73        inner(value).context(format!(
74            "parsing {}",
75            pb::EventValidatorVotingPowerChange::NAME
76        ))
77    }
78}
79
80impl From<EventValidatorVotingPowerChange> for pb::EventValidatorVotingPowerChange {
81    fn from(value: EventValidatorVotingPowerChange) -> Self {
82        Self {
83            identity_key: Some(value.identity_key.into()),
84            voting_power: Some(value.voting_power.into()),
85        }
86    }
87}
88
89impl DomainType for EventValidatorVotingPowerChange {
90    type Proto = pb::EventValidatorVotingPowerChange;
91}
92
93#[derive(Clone, Debug)]
94pub struct EventValidatorBondingStateChange {
95    pub identity_key: IdentityKey,
96    pub bonding_state: BondingState,
97}
98
99impl TryFrom<pb::EventValidatorBondingStateChange> for EventValidatorBondingStateChange {
100    type Error = anyhow::Error;
101
102    fn try_from(value: pb::EventValidatorBondingStateChange) -> Result<Self, Self::Error> {
103        fn inner(
104            value: pb::EventValidatorBondingStateChange,
105        ) -> anyhow::Result<EventValidatorBondingStateChange> {
106            Ok(EventValidatorBondingStateChange {
107                identity_key: value
108                    .identity_key
109                    .ok_or(anyhow!("missing `identity_key`"))?
110                    .try_into()?,
111                bonding_state: value
112                    .bonding_state
113                    .ok_or(anyhow!("missing `bonding_state`"))?
114                    .try_into()?,
115            })
116        }
117        inner(value).context(format!(
118            "parsing {}",
119            pb::EventValidatorBondingStateChange::NAME
120        ))
121    }
122}
123
124impl From<EventValidatorBondingStateChange> for pb::EventValidatorBondingStateChange {
125    fn from(value: EventValidatorBondingStateChange) -> Self {
126        Self {
127            identity_key: Some(value.identity_key.into()),
128            bonding_state: Some(value.bonding_state.into()),
129        }
130    }
131}
132
133impl DomainType for EventValidatorBondingStateChange {
134    type Proto = pb::EventValidatorBondingStateChange;
135}
136
137#[derive(Clone, Debug)]
138pub struct EventRateDataChange {
139    pub identity_key: IdentityKey,
140    pub rate_data: RateData,
141}
142
143impl TryFrom<pb::EventRateDataChange> for EventRateDataChange {
144    type Error = anyhow::Error;
145
146    fn try_from(value: pb::EventRateDataChange) -> Result<Self, Self::Error> {
147        fn inner(value: pb::EventRateDataChange) -> anyhow::Result<EventRateDataChange> {
148            Ok(EventRateDataChange {
149                identity_key: value
150                    .identity_key
151                    .ok_or(anyhow!("missing `identity_key`"))?
152                    .try_into()?,
153                rate_data: value
154                    .rate_data
155                    .ok_or(anyhow!("missing `rate_data`"))?
156                    .try_into()?,
157            })
158        }
159        inner(value).context(format!("parsing {}", pb::EventRateDataChange::NAME))
160    }
161}
162
163impl From<EventRateDataChange> for pb::EventRateDataChange {
164    fn from(value: EventRateDataChange) -> Self {
165        Self {
166            identity_key: Some(value.identity_key.into()),
167            rate_data: Some(value.rate_data.into()),
168        }
169    }
170}
171
172impl DomainType for EventRateDataChange {
173    type Proto = pb::EventRateDataChange;
174}
175
176#[derive(Clone, Debug)]
177pub struct EventValidatorDefinitionUpload {
178    pub validator: Validator,
179}
180
181impl TryFrom<pb::EventValidatorDefinitionUpload> for EventValidatorDefinitionUpload {
182    type Error = anyhow::Error;
183
184    fn try_from(value: pb::EventValidatorDefinitionUpload) -> Result<Self, Self::Error> {
185        fn inner(
186            value: pb::EventValidatorDefinitionUpload,
187        ) -> anyhow::Result<EventValidatorDefinitionUpload> {
188            Ok(EventValidatorDefinitionUpload {
189                validator: value
190                    .validator
191                    .ok_or(anyhow!("missing `validator`"))?
192                    .try_into()?,
193            })
194        }
195        inner(value).context(format!(
196            "parsing {}",
197            pb::EventValidatorDefinitionUpload::NAME
198        ))
199    }
200}
201
202impl From<EventValidatorDefinitionUpload> for pb::EventValidatorDefinitionUpload {
203    fn from(value: EventValidatorDefinitionUpload) -> Self {
204        Self {
205            validator: Some(value.validator.into()),
206        }
207    }
208}
209
210impl DomainType for EventValidatorDefinitionUpload {
211    type Proto = pb::EventValidatorDefinitionUpload;
212}
213
214#[derive(Clone, Debug)]
215pub struct EventValidatorMissedBlock {
216    pub identity_key: IdentityKey,
217}
218
219impl TryFrom<pb::EventValidatorMissedBlock> for EventValidatorMissedBlock {
220    type Error = anyhow::Error;
221
222    fn try_from(value: pb::EventValidatorMissedBlock) -> Result<Self, Self::Error> {
223        fn inner(
224            value: pb::EventValidatorMissedBlock,
225        ) -> anyhow::Result<EventValidatorMissedBlock> {
226            Ok(EventValidatorMissedBlock {
227                identity_key: value
228                    .identity_key
229                    .ok_or(anyhow!("missing `identity_key`"))?
230                    .try_into()?,
231            })
232        }
233        inner(value).context(format!("parsing {}", pb::EventValidatorMissedBlock::NAME))
234    }
235}
236
237impl From<EventValidatorMissedBlock> for pb::EventValidatorMissedBlock {
238    fn from(value: EventValidatorMissedBlock) -> Self {
239        Self {
240            identity_key: Some(value.identity_key.into()),
241        }
242    }
243}
244
245impl DomainType for EventValidatorMissedBlock {
246    type Proto = pb::EventValidatorMissedBlock;
247}
248
249#[derive(Clone, Debug)]
250pub struct EventDelegate {
251    pub identity_key: IdentityKey,
252    pub amount: Amount,
253}
254
255impl From<&Delegate> for EventDelegate {
256    fn from(value: &Delegate) -> Self {
257        Self {
258            identity_key: value.validator_identity,
259            amount: value.unbonded_amount,
260        }
261    }
262}
263
264impl TryFrom<pb::EventDelegate> for EventDelegate {
265    type Error = anyhow::Error;
266
267    fn try_from(value: pb::EventDelegate) -> Result<Self, Self::Error> {
268        fn inner(value: pb::EventDelegate) -> anyhow::Result<EventDelegate> {
269            Ok(EventDelegate {
270                identity_key: value
271                    .identity_key
272                    .ok_or(anyhow!("missing `identity_key`"))?
273                    .try_into()?,
274                amount: value
275                    .amount
276                    .ok_or(anyhow!("missing `amount`"))?
277                    .try_into()?,
278            })
279        }
280        inner(value).context(format!("parsing {}", pb::EventDelegate::NAME))
281    }
282}
283
284impl From<EventDelegate> for pb::EventDelegate {
285    fn from(value: EventDelegate) -> Self {
286        Self {
287            identity_key: Some(value.identity_key.into()),
288            amount: Some(value.amount.into()),
289        }
290    }
291}
292
293impl DomainType for EventDelegate {
294    type Proto = pb::EventDelegate;
295}
296
297#[derive(Clone, Debug)]
298pub struct EventUndelegate {
299    pub identity_key: IdentityKey,
300    pub amount: Amount,
301}
302
303impl From<&Undelegate> for EventUndelegate {
304    fn from(value: &Undelegate) -> Self {
305        Self {
306            identity_key: value.validator_identity,
307            amount: value.unbonded_amount,
308        }
309    }
310}
311
312impl TryFrom<pb::EventUndelegate> for EventUndelegate {
313    type Error = anyhow::Error;
314
315    fn try_from(value: pb::EventUndelegate) -> Result<Self, Self::Error> {
316        fn inner(value: pb::EventUndelegate) -> anyhow::Result<EventUndelegate> {
317            Ok(EventUndelegate {
318                identity_key: value
319                    .identity_key
320                    .ok_or(anyhow!("missing `identity_key`"))?
321                    .try_into()?,
322                amount: value
323                    .amount
324                    .ok_or(anyhow!("missing `amount`"))?
325                    .try_into()?,
326            })
327        }
328        inner(value).context(format!("parsing {}", pb::EventUndelegate::NAME))
329    }
330}
331
332impl From<EventUndelegate> for pb::EventUndelegate {
333    fn from(value: EventUndelegate) -> Self {
334        Self {
335            identity_key: Some(value.identity_key.into()),
336            amount: Some(value.amount.into()),
337        }
338    }
339}
340
341impl DomainType for EventUndelegate {
342    type Proto = pb::EventUndelegate;
343}
344
345#[derive(Clone, Debug)]
346pub struct EventTombstoneValidator {
347    pub evidence_height: u64,
348    pub current_height: u64,
349    pub identity_key: IdentityKey,
350    pub address: Vec<u8>,
351    pub voting_power: u64,
352}
353
354impl EventTombstoneValidator {
355    pub fn from_evidence(
356        current_height: u64,
357        identity_key: IdentityKey,
358        evidence: &Misbehavior,
359    ) -> Self {
360        Self {
361            evidence_height: evidence.height.value(),
362            current_height,
363            identity_key,
364            address: evidence.validator.address.to_vec(),
365            voting_power: evidence.validator.power.value(),
366        }
367    }
368}
369
370impl TryFrom<pb::EventTombstoneValidator> for EventTombstoneValidator {
371    type Error = anyhow::Error;
372
373    fn try_from(value: pb::EventTombstoneValidator) -> Result<Self, Self::Error> {
374        fn inner(value: pb::EventTombstoneValidator) -> anyhow::Result<EventTombstoneValidator> {
375            Ok(EventTombstoneValidator {
376                evidence_height: value.evidence_height,
377                current_height: value.current_height,
378                identity_key: value
379                    .identity_key
380                    .ok_or(anyhow!("missing `identity_key`"))?
381                    .try_into()?,
382                address: value.address,
383                voting_power: value.voting_power,
384            })
385        }
386        inner(value).context(format!("parsing {}", pb::EventTombstoneValidator::NAME))
387    }
388}
389
390impl From<EventTombstoneValidator> for pb::EventTombstoneValidator {
391    fn from(value: EventTombstoneValidator) -> Self {
392        Self {
393            evidence_height: value.evidence_height,
394            current_height: value.current_height,
395            identity_key: Some(value.identity_key.into()),
396            address: value.address,
397            voting_power: value.voting_power,
398        }
399    }
400}
401
402impl DomainType for EventTombstoneValidator {
403    type Proto = pb::EventTombstoneValidator;
404}
405
406#[derive(Clone, Debug)]
407pub struct EventSlashingPenaltyApplied {
408    pub identity_key: IdentityKey,
409    pub epoch_index: u64,
410    pub new_penalty: Penalty,
411}
412
413impl TryFrom<pb::EventSlashingPenaltyApplied> for EventSlashingPenaltyApplied {
414    type Error = anyhow::Error;
415
416    fn try_from(value: pb::EventSlashingPenaltyApplied) -> Result<Self, Self::Error> {
417        fn inner(
418            value: pb::EventSlashingPenaltyApplied,
419        ) -> anyhow::Result<EventSlashingPenaltyApplied> {
420            Ok(EventSlashingPenaltyApplied {
421                identity_key: value
422                    .identity_key
423                    .ok_or(anyhow!("missing `identity_key`"))?
424                    .try_into()?,
425                epoch_index: value.epoch_index,
426                new_penalty: value
427                    .new_penalty
428                    .ok_or(anyhow!("missing `new_penalty`"))?
429                    .try_into()?,
430            })
431        }
432        inner(value).context(format!("parsing {}", pb::EventSlashingPenaltyApplied::NAME))
433    }
434}
435
436impl From<EventSlashingPenaltyApplied> for pb::EventSlashingPenaltyApplied {
437    fn from(value: EventSlashingPenaltyApplied) -> Self {
438        Self {
439            identity_key: Some(value.identity_key.into()),
440            epoch_index: value.epoch_index,
441            new_penalty: Some(value.new_penalty.into()),
442        }
443    }
444}
445
446impl DomainType for EventSlashingPenaltyApplied {
447    type Proto = pb::EventSlashingPenaltyApplied;
448}