tendermint/block/
signed_header.rs

1//! SignedHeader contains commit and block header.
2//! It is what the rpc endpoint /commit returns and hence can be used by a
3//! light client.
4
5use serde::{Deserialize, Serialize};
6use tendermint_proto::v0_37::types::SignedHeader as RawSignedHeader;
7
8use crate::{block, Error};
9
10/// Signed block headers
11#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
12#[serde(try_from = "RawSignedHeader", into = "RawSignedHeader")] // used by RPC /commit endpoint
13#[non_exhaustive]
14pub struct SignedHeader {
15    /// Block header
16    pub header: block::Header,
17    /// Commit containing signatures for the header
18    pub commit: block::Commit,
19}
20
21tendermint_pb_modules! {
22    use super::SignedHeader;
23    use crate::Error;
24    use pb::types::SignedHeader as RawSignedHeader;
25
26    impl TryFrom<RawSignedHeader> for SignedHeader {
27        type Error = Error;
28
29        fn try_from(value: RawSignedHeader) -> Result<Self, Self::Error> {
30            let header = value
31                .header
32                .ok_or_else(Error::invalid_signed_header)?
33                .try_into()?;
34            let commit = value
35                .commit
36                .ok_or_else(Error::invalid_signed_header)?
37                .try_into()?;
38            Self::new(header, commit) // Additional checks
39        }
40    }
41
42    impl From<SignedHeader> for RawSignedHeader {
43        fn from(value: SignedHeader) -> Self {
44            RawSignedHeader {
45                header: Some(value.header.into()),
46                commit: Some(value.commit.into()),
47            }
48        }
49    }
50
51    impl Protobuf<RawSignedHeader> for SignedHeader {}
52}
53
54impl SignedHeader {
55    /// Constructor.
56    pub fn new(header: block::Header, commit: block::Commit) -> Result<Self, Error> {
57        if header.height != commit.height {
58            return Err(Error::invalid_signed_header());
59        }
60        Ok(Self { header, commit })
61    }
62
63    /// Get header
64    pub fn header(&self) -> &block::Header {
65        &self.header
66    }
67
68    /// Get commit
69    pub fn commit(&self) -> &block::Commit {
70        &self.commit
71    }
72}