diff --git a/.changelog/unreleased/features/1134-sign-request-conversion.md b/.changelog/unreleased/features/1134-sign-request-conversion.md new file mode 100644 index 000000000..31d799c44 --- /dev/null +++ b/.changelog/unreleased/features/1134-sign-request-conversion.md @@ -0,0 +1,2 @@ +- `[tendermint]` Added conversions from signing requests to consensus states + ([#1134](https://github.com/informalsystems/tendermint-rs/issues/1134)) \ No newline at end of file diff --git a/tendermint/src/consensus/state.rs b/tendermint/src/consensus/state.rs index 658f99ba1..699e598d0 100644 --- a/tendermint/src/consensus/state.rs +++ b/tendermint/src/consensus/state.rs @@ -5,7 +5,7 @@ pub use core::{cmp::Ordering, fmt}; use serde::{Deserialize, Serialize}; pub use crate::block; -use crate::prelude::*; +use crate::{prelude::*, proposal::SignProposalRequest, vote::SignVoteRequest}; /// Placeholder string to show when block ID is absent. Syntax from: /// @@ -66,12 +66,88 @@ impl PartialOrd for State { } } +impl From for State { + fn from(req: SignProposalRequest) -> Self { + Self { + height: req.proposal.height, + round: req.proposal.round, + step: 0, + block_id: req.proposal.block_id, + } + } +} + +impl From for State { + fn from(req: SignVoteRequest) -> Self { + Self { + height: req.vote.height, + round: req.vote.round, + step: if req.vote.is_precommit() { 2 } else { 1 }, + block_id: req.vote.block_id, + } + } +} + #[cfg(test)] mod tests { - use core::str::FromStr; + use core::{convert::TryFrom, str::FromStr}; use super::State; - use crate::{block, Hash}; + use crate::{ + account::Id, + block, + proposal::{self, SignProposalRequest}, + vote::{self, SignVoteRequest, ValidatorIndex}, + Hash, Proposal, Vote, + }; + + #[test] + fn sign_request_test() { + let proposal = SignProposalRequest { + proposal: Proposal { + height: block::Height::from(9001_u32), + round: block::Round::default(), + block_id: None, + msg_type: proposal::Type::Proposal, + pol_round: None, + timestamp: None, + signature: None, + }, + chain_id: "chain_id".parse().unwrap(), + }; + let vote1 = SignVoteRequest { + vote: Vote { + height: block::Height::from(9001_u32), + round: block::Round::default(), + block_id: None, + vote_type: vote::Type::Prevote, + timestamp: None, + validator_address: Id::new(Default::default()), + validator_index: ValidatorIndex::try_from(1).unwrap(), + signature: None, + }, + chain_id: "chain_id".parse().unwrap(), + }; + let vote2 = SignVoteRequest { + vote: Vote { + height: block::Height::from(9001_u32), + round: block::Round::default(), + block_id: None, + vote_type: vote::Type::Precommit, + timestamp: None, + validator_address: Id::new(Default::default()), + validator_index: ValidatorIndex::try_from(1).unwrap(), + signature: None, + }, + chain_id: "chain_id".parse().unwrap(), + }; + let state1 = State::from(proposal); + let state2 = State::from(vote1); + let state3 = State::from(vote2); + + assert!(state1 < state2); + assert!(state2 < state3); + } #[test] fn state_ord_test() {