tendermint/proposal/
sign_proposal.rs

1use bytes::BufMut;
2use tendermint_proto::Error as ProtobufError;
3
4use super::Proposal;
5use crate::{chain::Id as ChainId, prelude::*, privval::RemoteSignerError};
6
7/// SignProposalRequest is a request to sign a proposal
8#[derive(Clone, PartialEq, Eq, Debug)]
9pub struct SignProposalRequest {
10    /// Proposal
11    pub proposal: Proposal,
12    /// Chain ID
13    pub chain_id: ChainId,
14}
15
16impl SignProposalRequest {
17    /// Create signable bytes from Proposal.
18    pub fn to_signable_bytes<B>(&self, sign_bytes: &mut B) -> Result<bool, ProtobufError>
19    where
20        B: BufMut,
21    {
22        self.proposal
23            .to_signable_bytes(self.chain_id.clone(), sign_bytes)
24    }
25
26    /// Create signable vector from Proposal.
27    pub fn into_signable_vec(self) -> Vec<u8> {
28        self.proposal.into_signable_vec(self.chain_id)
29    }
30}
31
32/// SignedProposalResponse is response containing a signed proposal or an error
33#[derive(Clone, PartialEq, Eq, Debug)]
34pub struct SignedProposalResponse {
35    /// Proposal
36    pub proposal: Option<Proposal>,
37    /// Response error
38    pub error: Option<RemoteSignerError>,
39}
40
41// =============================================================================
42// Protobuf conversions
43// =============================================================================
44
45tendermint_pb_modules! {
46    use pb::privval::{
47        SignProposalRequest as RawSignProposalRequest,
48        SignedProposalResponse as RawSignedProposalResponse,
49    };
50    use crate::{Error, Proposal, chain::Id as ChainId, prelude::*};
51    use super::{SignProposalRequest, SignedProposalResponse};
52
53    impl Protobuf<RawSignProposalRequest> for SignProposalRequest {}
54    impl Protobuf<RawSignedProposalResponse> for SignedProposalResponse {}
55
56    impl TryFrom<RawSignProposalRequest> for SignProposalRequest {
57        type Error = Error;
58
59        fn try_from(value: RawSignProposalRequest) -> Result<Self, Self::Error> {
60            if value.proposal.is_none() {
61                return Err(Error::no_proposal_found());
62            }
63            Ok(SignProposalRequest {
64                proposal: Proposal::try_from(value.proposal.unwrap())?,
65                chain_id: ChainId::try_from(value.chain_id).unwrap(),
66            })
67        }
68    }
69
70    impl From<SignProposalRequest> for RawSignProposalRequest {
71        fn from(value: SignProposalRequest) -> Self {
72            RawSignProposalRequest {
73                proposal: Some(value.proposal.into()),
74                chain_id: value.chain_id.to_string(),
75            }
76        }
77    }
78
79    impl TryFrom<RawSignedProposalResponse> for SignedProposalResponse {
80        type Error = Error;
81
82        fn try_from(value: RawSignedProposalResponse) -> Result<Self, Self::Error> {
83            Ok(SignedProposalResponse {
84                proposal: value.proposal.map(TryInto::try_into).transpose()?,
85                error: value.error.map(TryInto::try_into).transpose()?,
86            })
87        }
88    }
89
90    impl From<SignedProposalResponse> for RawSignedProposalResponse {
91        fn from(value: SignedProposalResponse) -> Self {
92            RawSignedProposalResponse {
93                proposal: value.proposal.map(Into::into),
94                error: value.error.map(Into::into),
95            }
96        }
97    }
98}