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}