From d2380e5104b17b872246872ee318ee18b4f2df43 Mon Sep 17 00:00:00 2001 From: Matan Markind Date: Thu, 20 Jun 2024 12:41:45 +0300 Subject: [PATCH] feat(consensus): add Vote message to proto --- crates/papyrus_protobuf/src/consensus.rs | 15 +++++ .../src/converters/consensus.rs | 63 ++++++++++++++++++- .../src/proto/p2p/proto/consensus.proto | 23 ++++++- .../sequencing/papyrus_consensus/src/lib.rs | 5 +- 4 files changed, 101 insertions(+), 5 deletions(-) diff --git a/crates/papyrus_protobuf/src/consensus.rs b/crates/papyrus_protobuf/src/consensus.rs index 2e9ec7fb5f..4e6704cbe0 100644 --- a/crates/papyrus_protobuf/src/consensus.rs +++ b/crates/papyrus_protobuf/src/consensus.rs @@ -10,7 +10,22 @@ pub struct Proposal { pub block_hash: BlockHash, } +#[derive(Debug, Clone, Eq, PartialEq)] +pub enum VoteType { + Prevote, + Precommit, +} + +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct Vote { + pub vote_type: VoteType, + pub height: u64, + pub block_hash: BlockHash, + pub voter: ContractAddress, +} + #[derive(Debug, Clone, Eq, PartialEq)] pub enum ConsensusMessage { Proposal(Proposal), + Vote(Vote), } diff --git a/crates/papyrus_protobuf/src/converters/consensus.rs b/crates/papyrus_protobuf/src/converters/consensus.rs index 0b7a88fdca..9f773be4c4 100644 --- a/crates/papyrus_protobuf/src/converters/consensus.rs +++ b/crates/papyrus_protobuf/src/converters/consensus.rs @@ -5,7 +5,7 @@ use starknet_api::block::BlockHash; use starknet_api::hash::StarkHash; use starknet_api::transaction::Transaction; -use crate::consensus::{ConsensusMessage, Proposal}; +use crate::consensus::{ConsensusMessage, Proposal, Vote, VoteType}; use crate::converters::ProtobufConversionError; use crate::{auto_impl_into_and_try_from_vec_u8, protobuf}; @@ -47,6 +47,63 @@ impl From for protobuf::Proposal { } } +impl TryFrom for VoteType { + type Error = ProtobufConversionError; + + fn try_from(value: protobuf::vote::VoteType) -> Result { + match value { + protobuf::vote::VoteType::Prevote => Ok(VoteType::Prevote), + protobuf::vote::VoteType::Precommit => Ok(VoteType::Precommit), + } + } +} + +impl From for protobuf::vote::VoteType { + fn from(value: VoteType) -> Self { + match value { + VoteType::Prevote => protobuf::vote::VoteType::Prevote, + VoteType::Precommit => protobuf::vote::VoteType::Precommit, + } + } +} + +impl TryFrom for Vote { + type Error = ProtobufConversionError; + + fn try_from(value: protobuf::Vote) -> Result { + let vote_type = protobuf::vote::VoteType::try_from(value.vote_type)?.try_into()?; + + let height = value.height; + let block_hash: StarkHash = value + .block_hash + .ok_or(ProtobufConversionError::MissingField { field_description: "block_hash" })? + .try_into()?; + let block_hash = BlockHash(block_hash); + let sender = value + .voter + .ok_or(ProtobufConversionError::MissingField { field_description: "sender" })? + .try_into()?; + + Ok(Vote { vote_type, height, block_hash, voter: sender }) + } +} + +impl From for protobuf::Vote { + fn from(value: Vote) -> Self { + let vote_type = match value.vote_type { + VoteType::Prevote => protobuf::vote::VoteType::Prevote, + VoteType::Precommit => protobuf::vote::VoteType::Precommit, + }; + + protobuf::Vote { + vote_type: vote_type as i32, + height: value.height, + block_hash: Some(value.block_hash.0.into()), + voter: Some(value.voter.into()), + } + } +} + impl TryFrom for ConsensusMessage { type Error = ProtobufConversionError; @@ -59,6 +116,7 @@ impl TryFrom for ConsensusMessage { match message { Message::Proposal(proposal) => Ok(ConsensusMessage::Proposal(proposal.try_into()?)), + Message::Vote(vote) => Ok(ConsensusMessage::Vote(vote.try_into()?)), } } } @@ -69,6 +127,9 @@ impl From for protobuf::ConsensusMessage { ConsensusMessage::Proposal(proposal) => protobuf::ConsensusMessage { message: Some(protobuf::consensus_message::Message::Proposal(proposal.into())), }, + ConsensusMessage::Vote(vote) => protobuf::ConsensusMessage { + message: Some(protobuf::consensus_message::Message::Vote(vote.into())), + }, } } } diff --git a/crates/papyrus_protobuf/src/proto/p2p/proto/consensus.proto b/crates/papyrus_protobuf/src/proto/p2p/proto/consensus.proto index 8f910096dc..d219a1fd0e 100644 --- a/crates/papyrus_protobuf/src/proto/p2p/proto/consensus.proto +++ b/crates/papyrus_protobuf/src/proto/p2p/proto/consensus.proto @@ -3,14 +3,31 @@ import "p2p/proto/transaction.proto"; import "p2p/proto/common.proto"; message Proposal { - uint64 height = 1; - Felt252 proposer = 2; + uint64 height = 1; + Felt252 proposer = 2; repeated Transaction transactions = 3; - Hash block_hash = 4; + Hash block_hash = 4; +} + +message Vote { + enum VoteType { + Prevote = 0; + Precommit = 1; + }; + + // We use a type field to distinguish between prevotes and precommits instead of different + // messages, to make sure the data, and therefore the signatures, are unambiguous between + // Prevote and Precommit. + VoteType vote_type = 2; + uint64 height = 3; + // This is optional since a vote can be NIL. + optional Hash block_hash = 4; + Address voter = 5; } message ConsensusMessage { oneof message { Proposal proposal = 1; + Vote vote = 2; } } \ No newline at end of file diff --git a/crates/sequencing/papyrus_consensus/src/lib.rs b/crates/sequencing/papyrus_consensus/src/lib.rs index f93a05ddb7..4f68be0db7 100644 --- a/crates/sequencing/papyrus_consensus/src/lib.rs +++ b/crates/sequencing/papyrus_consensus/src/lib.rs @@ -50,7 +50,10 @@ where .await .expect("Failed to receive a message from network") .0 - .expect("Network receiver closed unexpectedly"); + .expect("Network receiver closed unexpectedly") + else { + todo!("Handle votes"); + }; let (proposal_init, content_receiver, fin_receiver) = ProposalWrapper(proposal).into(); shc.handle_proposal(proposal_init, content_receiver, fin_receiver)