1use bytes::Bytes;
9use serde::{Deserialize, Serialize};
10
11use super::{Code, Event};
12use crate::{
13 block::{self, BlockIdFlag},
14 prelude::*,
15 serializers, vote, Signature, Time,
16};
17
18#[derive(Clone, PartialEq, Eq, Debug)]
22pub struct Validator {
23 pub address: [u8; 20],
25 pub power: vote::Power,
27}
28
29#[derive(Clone, PartialEq, Eq, Debug)]
33pub struct VoteInfo {
34 pub validator: Validator,
36 pub sig_info: BlockSignatureInfo,
38}
39
40#[derive(Clone, PartialEq, Eq, Debug)]
45pub struct ExtendedVoteInfo {
46 pub validator: Validator,
48 pub sig_info: BlockSignatureInfo,
50 pub vote_extension: Bytes,
55 pub extension_signature: Option<Signature>,
60}
61
62#[derive(Copy, Clone, Debug, PartialEq, Eq)]
63pub enum BlockSignatureInfo {
65 Flag(BlockIdFlag),
74 LegacySigned,
80}
81
82impl BlockSignatureInfo {
83 pub fn is_signed(&self) -> bool {
85 use BlockIdFlag::*;
86
87 match self {
88 BlockSignatureInfo::Flag(Commit) | BlockSignatureInfo::Flag(Nil) => true,
89 BlockSignatureInfo::Flag(Absent) => false,
90 BlockSignatureInfo::LegacySigned => true,
91 }
92 }
93}
94
95#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
102#[repr(i32)]
103pub enum MisbehaviorKind {
104 Unknown = 0,
106 DuplicateVote = 1,
109 LightClientAttack = 2,
111}
112
113#[derive(Clone, PartialEq, Eq, Debug)]
117pub struct Misbehavior {
118 pub kind: MisbehaviorKind,
123 pub validator: Validator,
125 pub height: block::Height,
127 pub time: Time,
129 pub total_voting_power: vote::Power,
135}
136
137#[derive(Clone, PartialEq, Eq, Debug)]
141pub struct CommitInfo {
142 pub round: block::Round,
147 pub votes: Vec<VoteInfo>,
150}
151
152#[derive(Clone, PartialEq, Eq, Debug)]
156pub struct ExtendedCommitInfo {
157 pub round: block::Round,
162 pub votes: Vec<ExtendedVoteInfo>,
165}
166
167#[derive(Clone, PartialEq, Eq, Debug)]
173pub struct Snapshot {
174 pub height: block::Height,
176 pub format: u32,
181 pub chunks: u32,
183 pub hash: Bytes,
189 pub metadata: Bytes,
191}
192
193#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize)]
200pub struct ExecTxResult {
201 #[serde(default)]
207 pub code: Code,
208
209 #[serde(default, with = "serializers::nullable")]
211 pub data: Bytes,
212
213 #[serde(default)]
217 pub log: String,
218
219 #[serde(default)]
223 pub info: String,
224 #[serde(default, with = "serializers::from_str")]
226 pub gas_wanted: i64,
227
228 #[serde(default, with = "serializers::from_str")]
230 pub gas_used: i64,
231
232 #[serde(default)]
234 pub events: Vec<Event>,
235
236 #[serde(default)]
238 pub codespace: String,
239}
240
241mod v0_34 {
246 use super::{
247 BlockSignatureInfo, CommitInfo, Misbehavior, MisbehaviorKind, Snapshot, Validator, VoteInfo,
248 };
249 use crate::{block::BlockIdFlag, prelude::*, Error};
250 use tendermint_proto::v0_34::abci as pb;
251 use tendermint_proto::Protobuf;
252
253 use bytes::Bytes;
254
255 impl From<Validator> for pb::Validator {
256 fn from(v: Validator) -> Self {
257 Self {
258 address: Bytes::copy_from_slice(&v.address[..]),
259 power: v.power.into(),
260 }
261 }
262 }
263
264 impl TryFrom<pb::Validator> for Validator {
265 type Error = Error;
266
267 fn try_from(vu: pb::Validator) -> Result<Self, Self::Error> {
268 let address = if vu.address.len() == 20 {
269 let mut bytes = [0u8; 20];
270 bytes.copy_from_slice(&vu.address);
271 bytes
272 } else {
273 return Err(Error::invalid_account_id_length());
274 };
275
276 Ok(Self {
277 address,
278 power: vu.power.try_into()?,
279 })
280 }
281 }
282
283 impl Protobuf<pb::Validator> for Validator {}
284
285 impl From<VoteInfo> for pb::VoteInfo {
286 fn from(vi: VoteInfo) -> Self {
287 Self {
288 validator: Some(vi.validator.into()),
289 signed_last_block: vi.sig_info.is_signed(),
290 }
291 }
292 }
293
294 impl TryFrom<pb::VoteInfo> for VoteInfo {
295 type Error = Error;
296
297 fn try_from(vi: pb::VoteInfo) -> Result<Self, Self::Error> {
298 let sig_info = if vi.signed_last_block {
299 BlockSignatureInfo::LegacySigned
300 } else {
301 BlockSignatureInfo::Flag(BlockIdFlag::Absent)
302 };
303 Ok(Self {
304 validator: vi
305 .validator
306 .ok_or_else(Error::missing_validator)?
307 .try_into()?,
308 sig_info,
309 })
310 }
311 }
312
313 impl Protobuf<pb::VoteInfo> for VoteInfo {}
314
315 impl From<Misbehavior> for pb::Evidence {
316 fn from(evidence: Misbehavior) -> Self {
317 Self {
318 r#type: evidence.kind as i32,
319 validator: Some(evidence.validator.into()),
320 height: evidence.height.into(),
321 time: Some(evidence.time.into()),
322 total_voting_power: evidence.total_voting_power.into(),
323 }
324 }
325 }
326
327 impl TryFrom<pb::Evidence> for Misbehavior {
328 type Error = Error;
329
330 fn try_from(evidence: pb::Evidence) -> Result<Self, Self::Error> {
331 let kind = match evidence.r#type {
332 0 => MisbehaviorKind::Unknown,
333 1 => MisbehaviorKind::DuplicateVote,
334 2 => MisbehaviorKind::LightClientAttack,
335 _ => return Err(Error::invalid_evidence()),
336 };
337
338 Ok(Self {
339 kind,
340 validator: evidence
341 .validator
342 .ok_or_else(Error::missing_validator)?
343 .try_into()?,
344 height: evidence.height.try_into()?,
345 time: evidence
346 .time
347 .ok_or_else(Error::missing_timestamp)?
348 .try_into()?,
349 total_voting_power: evidence.total_voting_power.try_into()?,
350 })
351 }
352 }
353
354 impl Protobuf<pb::Evidence> for Misbehavior {}
355
356 impl From<CommitInfo> for pb::LastCommitInfo {
357 fn from(lci: CommitInfo) -> Self {
358 Self {
359 round: lci.round.into(),
360 votes: lci.votes.into_iter().map(Into::into).collect(),
361 }
362 }
363 }
364
365 impl TryFrom<pb::LastCommitInfo> for CommitInfo {
366 type Error = Error;
367
368 fn try_from(lci: pb::LastCommitInfo) -> Result<Self, Self::Error> {
369 Ok(Self {
370 round: lci.round.try_into()?,
371 votes: lci
372 .votes
373 .into_iter()
374 .map(TryInto::try_into)
375 .collect::<Result<_, _>>()?,
376 })
377 }
378 }
379
380 impl Protobuf<pb::LastCommitInfo> for CommitInfo {}
381
382 impl From<Snapshot> for pb::Snapshot {
383 fn from(snapshot: Snapshot) -> Self {
384 Self {
385 height: snapshot.height.into(),
386 format: snapshot.format,
387 chunks: snapshot.chunks,
388 hash: snapshot.hash,
389 metadata: snapshot.metadata,
390 }
391 }
392 }
393
394 impl TryFrom<pb::Snapshot> for Snapshot {
395 type Error = Error;
396
397 fn try_from(snapshot: pb::Snapshot) -> Result<Self, Self::Error> {
398 Ok(Self {
399 height: snapshot.height.try_into()?,
400 format: snapshot.format,
401 chunks: snapshot.chunks,
402 hash: snapshot.hash,
403 metadata: snapshot.metadata,
404 })
405 }
406 }
407
408 impl Protobuf<pb::Snapshot> for Snapshot {}
409}
410
411mod v0_37 {
412 use super::{
413 BlockSignatureInfo, CommitInfo, ExtendedCommitInfo, ExtendedVoteInfo, Misbehavior,
414 MisbehaviorKind, Snapshot, Validator, VoteInfo,
415 };
416 use crate::{block::BlockIdFlag, prelude::*, Error};
417 use tendermint_proto::v0_37::abci as pb;
418 use tendermint_proto::Protobuf;
419
420 use bytes::Bytes;
421
422 impl From<Validator> for pb::Validator {
423 fn from(v: Validator) -> Self {
424 Self {
425 address: Bytes::copy_from_slice(&v.address[..]),
426 power: v.power.into(),
427 }
428 }
429 }
430
431 impl TryFrom<pb::Validator> for Validator {
432 type Error = Error;
433
434 fn try_from(vu: pb::Validator) -> Result<Self, Self::Error> {
435 let address = if vu.address.len() == 20 {
436 let mut bytes = [0u8; 20];
437 bytes.copy_from_slice(&vu.address);
438 bytes
439 } else {
440 return Err(Error::invalid_account_id_length());
441 };
442
443 Ok(Self {
444 address,
445 power: vu.power.try_into()?,
446 })
447 }
448 }
449
450 impl Protobuf<pb::Validator> for Validator {}
451
452 impl From<VoteInfo> for pb::VoteInfo {
453 fn from(vi: VoteInfo) -> Self {
454 Self {
455 validator: Some(vi.validator.into()),
456 signed_last_block: vi.sig_info.is_signed(),
457 }
458 }
459 }
460
461 impl TryFrom<pb::VoteInfo> for VoteInfo {
462 type Error = Error;
463
464 fn try_from(vi: pb::VoteInfo) -> Result<Self, Self::Error> {
465 let sig_info = if vi.signed_last_block {
466 BlockSignatureInfo::LegacySigned
467 } else {
468 BlockSignatureInfo::Flag(BlockIdFlag::Absent)
469 };
470 Ok(Self {
471 validator: vi
472 .validator
473 .ok_or_else(Error::missing_validator)?
474 .try_into()?,
475 sig_info,
476 })
477 }
478 }
479
480 impl Protobuf<pb::VoteInfo> for VoteInfo {}
481
482 impl From<ExtendedVoteInfo> for pb::ExtendedVoteInfo {
486 fn from(vi: ExtendedVoteInfo) -> Self {
487 Self {
488 validator: Some(vi.validator.into()),
489 signed_last_block: vi.sig_info.is_signed(),
490 vote_extension: Default::default(),
491 }
492 }
493 }
494
495 impl TryFrom<pb::ExtendedVoteInfo> for ExtendedVoteInfo {
496 type Error = Error;
497
498 fn try_from(vi: pb::ExtendedVoteInfo) -> Result<Self, Self::Error> {
499 let sig_info = if vi.signed_last_block {
500 BlockSignatureInfo::LegacySigned
501 } else {
502 BlockSignatureInfo::Flag(BlockIdFlag::Absent)
503 };
504 Ok(Self {
505 validator: vi
506 .validator
507 .ok_or_else(Error::missing_validator)?
508 .try_into()?,
509 sig_info,
510 vote_extension: Default::default(),
511 extension_signature: None,
512 })
513 }
514 }
515
516 impl Protobuf<pb::ExtendedVoteInfo> for ExtendedVoteInfo {}
517
518 impl From<Misbehavior> for pb::Misbehavior {
519 fn from(evidence: Misbehavior) -> Self {
520 Self {
521 r#type: evidence.kind as i32,
522 validator: Some(evidence.validator.into()),
523 height: evidence.height.into(),
524 time: Some(evidence.time.into()),
525 total_voting_power: evidence.total_voting_power.into(),
526 }
527 }
528 }
529
530 impl TryFrom<pb::Misbehavior> for Misbehavior {
531 type Error = Error;
532
533 fn try_from(evidence: pb::Misbehavior) -> Result<Self, Self::Error> {
534 let kind = match evidence.r#type {
535 0 => MisbehaviorKind::Unknown,
536 1 => MisbehaviorKind::DuplicateVote,
537 2 => MisbehaviorKind::LightClientAttack,
538 _ => return Err(Error::invalid_evidence()),
539 };
540
541 Ok(Self {
542 kind,
543 validator: evidence
544 .validator
545 .ok_or_else(Error::missing_validator)?
546 .try_into()?,
547 height: evidence.height.try_into()?,
548 time: evidence
549 .time
550 .ok_or_else(Error::missing_timestamp)?
551 .try_into()?,
552 total_voting_power: evidence.total_voting_power.try_into()?,
553 })
554 }
555 }
556
557 impl Protobuf<pb::Misbehavior> for Misbehavior {}
558
559 impl From<CommitInfo> for pb::CommitInfo {
560 fn from(lci: CommitInfo) -> Self {
561 Self {
562 round: lci.round.into(),
563 votes: lci.votes.into_iter().map(Into::into).collect(),
564 }
565 }
566 }
567
568 impl TryFrom<pb::CommitInfo> for CommitInfo {
569 type Error = Error;
570
571 fn try_from(lci: pb::CommitInfo) -> Result<Self, Self::Error> {
572 Ok(Self {
573 round: lci.round.try_into()?,
574 votes: lci
575 .votes
576 .into_iter()
577 .map(TryInto::try_into)
578 .collect::<Result<_, _>>()?,
579 })
580 }
581 }
582
583 impl Protobuf<pb::CommitInfo> for CommitInfo {}
584
585 impl From<ExtendedCommitInfo> for pb::ExtendedCommitInfo {
586 fn from(lci: ExtendedCommitInfo) -> Self {
587 Self {
588 round: lci.round.into(),
589 votes: lci.votes.into_iter().map(Into::into).collect(),
590 }
591 }
592 }
593
594 impl TryFrom<pb::ExtendedCommitInfo> for ExtendedCommitInfo {
595 type Error = Error;
596
597 fn try_from(lci: pb::ExtendedCommitInfo) -> Result<Self, Self::Error> {
598 Ok(Self {
599 round: lci.round.try_into()?,
600 votes: lci
601 .votes
602 .into_iter()
603 .map(TryInto::try_into)
604 .collect::<Result<_, _>>()?,
605 })
606 }
607 }
608
609 impl Protobuf<pb::ExtendedCommitInfo> for ExtendedCommitInfo {}
610
611 impl From<Snapshot> for pb::Snapshot {
612 fn from(snapshot: Snapshot) -> Self {
613 Self {
614 height: snapshot.height.into(),
615 format: snapshot.format,
616 chunks: snapshot.chunks,
617 hash: snapshot.hash,
618 metadata: snapshot.metadata,
619 }
620 }
621 }
622
623 impl TryFrom<pb::Snapshot> for Snapshot {
624 type Error = Error;
625
626 fn try_from(snapshot: pb::Snapshot) -> Result<Self, Self::Error> {
627 Ok(Self {
628 height: snapshot.height.try_into()?,
629 format: snapshot.format,
630 chunks: snapshot.chunks,
631 hash: snapshot.hash,
632 metadata: snapshot.metadata,
633 })
634 }
635 }
636
637 impl Protobuf<pb::Snapshot> for Snapshot {}
638}
639
640mod v0_38 {
641 use super::{
642 BlockSignatureInfo, CommitInfo, ExecTxResult, ExtendedCommitInfo, ExtendedVoteInfo,
643 Misbehavior, MisbehaviorKind, Snapshot, Validator, VoteInfo,
644 };
645 use crate::{prelude::*, Error, Signature};
646 use tendermint_proto::v0_38::abci as pb;
647 use tendermint_proto::v0_38::types::BlockIdFlag as RawBlockIdFlag;
648 use tendermint_proto::Protobuf;
649
650 use bytes::Bytes;
651
652 impl From<Validator> for pb::Validator {
653 fn from(v: Validator) -> Self {
654 Self {
655 address: Bytes::copy_from_slice(&v.address[..]),
656 power: v.power.into(),
657 }
658 }
659 }
660
661 impl TryFrom<pb::Validator> for Validator {
662 type Error = Error;
663
664 fn try_from(vu: pb::Validator) -> Result<Self, Self::Error> {
665 let address = if vu.address.len() == 20 {
666 let mut bytes = [0u8; 20];
667 bytes.copy_from_slice(&vu.address);
668 bytes
669 } else {
670 return Err(Error::invalid_account_id_length());
671 };
672
673 Ok(Self {
674 address,
675 power: vu.power.try_into()?,
676 })
677 }
678 }
679
680 impl Protobuf<pb::Validator> for Validator {}
681
682 impl From<BlockSignatureInfo> for RawBlockIdFlag {
683 fn from(value: BlockSignatureInfo) -> Self {
684 match value {
688 BlockSignatureInfo::Flag(flag) => flag.into(),
689 BlockSignatureInfo::LegacySigned => RawBlockIdFlag::Unknown,
690 }
691 }
692 }
693
694 impl From<VoteInfo> for pb::VoteInfo {
695 fn from(vi: VoteInfo) -> Self {
696 let block_id_flag: RawBlockIdFlag = vi.sig_info.into();
697 Self {
698 validator: Some(vi.validator.into()),
699 block_id_flag: block_id_flag as i32,
700 }
701 }
702 }
703
704 impl TryFrom<pb::VoteInfo> for VoteInfo {
705 type Error = Error;
706
707 fn try_from(vi: pb::VoteInfo) -> Result<Self, Self::Error> {
708 let block_id_flag: RawBlockIdFlag = vi
709 .block_id_flag
710 .try_into()
711 .map_err(|_| Error::block_id_flag())?;
712 Ok(Self {
713 validator: vi
714 .validator
715 .ok_or_else(Error::missing_validator)?
716 .try_into()?,
717 sig_info: BlockSignatureInfo::Flag(block_id_flag.try_into()?),
718 })
719 }
720 }
721
722 impl Protobuf<pb::VoteInfo> for VoteInfo {}
723
724 impl From<ExtendedVoteInfo> for pb::ExtendedVoteInfo {
725 fn from(vi: ExtendedVoteInfo) -> Self {
726 let block_id_flag: RawBlockIdFlag = vi.sig_info.into();
727 Self {
728 validator: Some(vi.validator.into()),
729 vote_extension: vi.vote_extension,
730 extension_signature: vi.extension_signature.map(Into::into).unwrap_or_default(),
731 block_id_flag: block_id_flag as i32,
732 }
733 }
734 }
735
736 impl TryFrom<pb::ExtendedVoteInfo> for ExtendedVoteInfo {
737 type Error = Error;
738
739 fn try_from(vi: pb::ExtendedVoteInfo) -> Result<Self, Self::Error> {
740 let block_id_flag: RawBlockIdFlag = vi
741 .block_id_flag
742 .try_into()
743 .map_err(|_| Error::block_id_flag())?;
744 Ok(Self {
745 validator: vi
746 .validator
747 .ok_or_else(Error::missing_validator)?
748 .try_into()?,
749 sig_info: BlockSignatureInfo::Flag(block_id_flag.try_into()?),
750 vote_extension: vi.vote_extension,
751 extension_signature: Signature::new(vi.extension_signature)?,
752 })
753 }
754 }
755
756 impl Protobuf<pb::ExtendedVoteInfo> for ExtendedVoteInfo {}
757
758 impl From<Misbehavior> for pb::Misbehavior {
759 fn from(evidence: Misbehavior) -> Self {
760 Self {
761 r#type: evidence.kind as i32,
762 validator: Some(evidence.validator.into()),
763 height: evidence.height.into(),
764 time: Some(evidence.time.into()),
765 total_voting_power: evidence.total_voting_power.into(),
766 }
767 }
768 }
769
770 impl TryFrom<pb::Misbehavior> for Misbehavior {
771 type Error = Error;
772
773 fn try_from(evidence: pb::Misbehavior) -> Result<Self, Self::Error> {
774 let kind = match evidence.r#type {
775 0 => MisbehaviorKind::Unknown,
776 1 => MisbehaviorKind::DuplicateVote,
777 2 => MisbehaviorKind::LightClientAttack,
778 _ => return Err(Error::invalid_evidence()),
779 };
780
781 Ok(Self {
782 kind,
783 validator: evidence
784 .validator
785 .ok_or_else(Error::missing_validator)?
786 .try_into()?,
787 height: evidence.height.try_into()?,
788 time: evidence
789 .time
790 .ok_or_else(Error::missing_timestamp)?
791 .try_into()?,
792 total_voting_power: evidence.total_voting_power.try_into()?,
793 })
794 }
795 }
796
797 impl Protobuf<pb::Misbehavior> for Misbehavior {}
798
799 impl From<CommitInfo> for pb::CommitInfo {
800 fn from(lci: CommitInfo) -> Self {
801 Self {
802 round: lci.round.into(),
803 votes: lci.votes.into_iter().map(Into::into).collect(),
804 }
805 }
806 }
807
808 impl TryFrom<pb::CommitInfo> for CommitInfo {
809 type Error = Error;
810
811 fn try_from(lci: pb::CommitInfo) -> Result<Self, Self::Error> {
812 Ok(Self {
813 round: lci.round.try_into()?,
814 votes: lci
815 .votes
816 .into_iter()
817 .map(TryInto::try_into)
818 .collect::<Result<_, _>>()?,
819 })
820 }
821 }
822
823 impl Protobuf<pb::CommitInfo> for CommitInfo {}
824
825 impl From<ExtendedCommitInfo> for pb::ExtendedCommitInfo {
826 fn from(lci: ExtendedCommitInfo) -> Self {
827 Self {
828 round: lci.round.into(),
829 votes: lci.votes.into_iter().map(Into::into).collect(),
830 }
831 }
832 }
833
834 impl TryFrom<pb::ExtendedCommitInfo> for ExtendedCommitInfo {
835 type Error = Error;
836
837 fn try_from(lci: pb::ExtendedCommitInfo) -> Result<Self, Self::Error> {
838 Ok(Self {
839 round: lci.round.try_into()?,
840 votes: lci
841 .votes
842 .into_iter()
843 .map(TryInto::try_into)
844 .collect::<Result<_, _>>()?,
845 })
846 }
847 }
848
849 impl Protobuf<pb::ExtendedCommitInfo> for ExtendedCommitInfo {}
850
851 impl From<Snapshot> for pb::Snapshot {
852 fn from(snapshot: Snapshot) -> Self {
853 Self {
854 height: snapshot.height.into(),
855 format: snapshot.format,
856 chunks: snapshot.chunks,
857 hash: snapshot.hash,
858 metadata: snapshot.metadata,
859 }
860 }
861 }
862
863 impl TryFrom<pb::Snapshot> for Snapshot {
864 type Error = Error;
865
866 fn try_from(snapshot: pb::Snapshot) -> Result<Self, Self::Error> {
867 Ok(Self {
868 height: snapshot.height.try_into()?,
869 format: snapshot.format,
870 chunks: snapshot.chunks,
871 hash: snapshot.hash,
872 metadata: snapshot.metadata,
873 })
874 }
875 }
876
877 impl Protobuf<pb::Snapshot> for Snapshot {}
878
879 impl From<ExecTxResult> for pb::ExecTxResult {
880 fn from(deliver_tx: ExecTxResult) -> Self {
881 Self {
882 code: deliver_tx.code.into(),
883 data: deliver_tx.data,
884 log: deliver_tx.log,
885 info: deliver_tx.info,
886 gas_wanted: deliver_tx.gas_wanted,
887 gas_used: deliver_tx.gas_used,
888 events: deliver_tx.events.into_iter().map(Into::into).collect(),
889 codespace: deliver_tx.codespace,
890 }
891 }
892 }
893
894 impl TryFrom<pb::ExecTxResult> for ExecTxResult {
895 type Error = Error;
896
897 fn try_from(deliver_tx: pb::ExecTxResult) -> Result<Self, Self::Error> {
898 Ok(Self {
899 code: deliver_tx.code.into(),
900 data: deliver_tx.data,
901 log: deliver_tx.log,
902 info: deliver_tx.info,
903 gas_wanted: deliver_tx.gas_wanted,
904 gas_used: deliver_tx.gas_used,
905 events: deliver_tx
906 .events
907 .into_iter()
908 .map(TryInto::try_into)
909 .collect::<Result<_, _>>()?,
910 codespace: deliver_tx.codespace,
911 })
912 }
913 }
914
915 impl Protobuf<pb::ExecTxResult> for ExecTxResult {}
916}