tendermint/block/
commit.rs

1//! Commits to a Tendermint blockchain
2
3use serde::{Deserialize, Serialize};
4use tendermint_proto::v0_37::types::Commit as RawCommit;
5
6use crate::{
7    block::{commit_sig::CommitSig, Height, Id, Round},
8    prelude::*,
9};
10
11/// Commit contains the justification (ie. a set of signatures) that a block was committed by a set
12/// of validators.
13/// TODO: Update links below!
14/// <https://github.com/tendermint/tendermint/blob/51dc810d041eaac78320adc6d53ad8b160b06601/types/block.go#L486-L502>
15/// <https://github.com/tendermint/spec/blob/d46cd7f573a2c6a2399fcab2cde981330aa63f37/spec/core/data_structures.md#lastcommit>
16#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
17#[serde(try_from = "RawCommit", into = "RawCommit")] // Used by testgen Generator trait
18pub struct Commit {
19    /// Block height
20    pub height: Height,
21
22    /// Round
23    pub round: Round,
24
25    /// Block ID
26    pub block_id: Id,
27
28    /// Signatures
29    pub signatures: Vec<CommitSig>,
30}
31
32tendermint_pb_modules! {
33    use super::Commit;
34    use crate::{
35        block::commit_sig::CommitSig,
36        error::Error,
37        prelude::*,
38    };
39    use pb::types::Commit as RawCommit;
40
41    impl TryFrom<RawCommit> for Commit {
42        type Error = Error;
43
44        fn try_from(value: RawCommit) -> Result<Self, Self::Error> {
45            let signatures: Result<Vec<CommitSig>, Error> = value
46                .signatures
47                .into_iter()
48                .map(TryFrom::try_from)
49                .collect();
50            Ok(Self {
51                height: value.height.try_into()?,
52                round: value.round.try_into()?,
53                block_id: value
54                    .block_id
55                    .ok_or_else(|| Error::invalid_block("missing block id".to_string()))?
56                    .try_into()?, // gogoproto.nullable = false
57                signatures: signatures?,
58            })
59        }
60    }
61
62    impl From<Commit> for RawCommit {
63        fn from(value: Commit) -> Self {
64            RawCommit {
65                height: value.height.into(),
66                round: value.round.into(),
67                block_id: Some(value.block_id.into()),
68                signatures: value.signatures.into_iter().map(Into::into).collect(),
69            }
70        }
71    }
72}
73
74impl Default for Commit {
75    fn default() -> Self {
76        Commit {
77            // The default Height is 1, but the default commit is an empty commit with height = 0.
78            height: Height::from(0_u32),
79            round: Default::default(),
80            block_id: Default::default(),
81            signatures: vec![],
82        }
83    }
84}