diff --git a/crates/sequencing/papyrus_consensus/src/manager_test.rs b/crates/sequencing/papyrus_consensus/src/manager_test.rs index 99f8a01087..a96dfd23b1 100644 --- a/crates/sequencing/papyrus_consensus/src/manager_test.rs +++ b/crates/sequencing/papyrus_consensus/src/manager_test.rs @@ -49,6 +49,7 @@ mock! { &mut self, height: BlockNumber, round: Round, + proposer: ValidatorId, timeout: Duration, content: mpsc::Receiver ) -> oneshot::Receiver; @@ -71,8 +72,12 @@ mock! { precommits: Vec, ) -> Result<(), ConsensusError>; - async fn set_height_and_round(&mut self, height: BlockNumber, round: Round); - + async fn set_height_and_round( + &mut self, + height: BlockNumber, + round: Round, + proposer: ValidatorId + ); } } @@ -99,7 +104,7 @@ async fn manager_multiple_heights_unordered() { // Run the manager for height 1. context .expect_validate_proposal() - .return_once(move |_, _, _, _| { + .return_once(move |_, _, _, _, _| { let (block_sender, block_receiver) = oneshot::channel(); block_sender.send(BlockHash(Felt::ONE)).unwrap(); block_receiver @@ -107,7 +112,7 @@ async fn manager_multiple_heights_unordered() { .times(1); context.expect_validators().returning(move |_| vec![*PROPOSER_ID, *VALIDATOR_ID]); context.expect_proposer().returning(move |_, _| *PROPOSER_ID); - context.expect_set_height_and_round().returning(move |_, _| ()); + context.expect_set_height_and_round().returning(move |_, _, _| ()); context.expect_broadcast().returning(move |_| Ok(())); let mut manager = MultiHeightManager::new(*VALIDATOR_ID, TIMEOUTS.clone()); @@ -119,7 +124,7 @@ async fn manager_multiple_heights_unordered() { // Run the manager for height 2. context .expect_validate_proposal() - .return_once(move |_, _, _, _| { + .return_once(move |_, _, _, _, _| { let (block_sender, block_receiver) = oneshot::channel(); block_sender.send(BlockHash(Felt::TWO)).unwrap(); block_receiver @@ -136,14 +141,14 @@ async fn run_consensus_sync() { let mut context = MockTestContext::new(); let (decision_tx, decision_rx) = oneshot::channel(); - context.expect_validate_proposal().return_once(move |_, _, _, _| { + context.expect_validate_proposal().return_once(move |_, _, _, _, _| { let (block_sender, block_receiver) = oneshot::channel(); block_sender.send(BlockHash(Felt::TWO)).unwrap(); block_receiver }); context.expect_validators().returning(move |_| vec![*PROPOSER_ID, *VALIDATOR_ID]); context.expect_proposer().returning(move |_, _| *PROPOSER_ID); - context.expect_set_height_and_round().returning(move |_, _| ()); + context.expect_set_height_and_round().returning(move |_, _, _| ()); context.expect_broadcast().returning(move |_| Ok(())); context.expect_decision_reached().return_once(move |block, votes| { assert_eq!(block, BlockHash(Felt::TWO)); @@ -196,14 +201,14 @@ async fn run_consensus_sync_cancellation_safety() { let (proposal_handled_tx, proposal_handled_rx) = oneshot::channel(); let (decision_tx, decision_rx) = oneshot::channel(); - context.expect_validate_proposal().return_once(move |_, _, _, _| { + context.expect_validate_proposal().return_once(move |_, _, _, _, _| { let (block_sender, block_receiver) = oneshot::channel(); block_sender.send(BlockHash(Felt::ONE)).unwrap(); block_receiver }); context.expect_validators().returning(move |_| vec![*PROPOSER_ID, *VALIDATOR_ID]); context.expect_proposer().returning(move |_, _| *PROPOSER_ID); - context.expect_set_height_and_round().returning(move |_, _| ()); + context.expect_set_height_and_round().returning(move |_, _, _| ()); context.expect_broadcast().with(eq(prevote(Some(Felt::ONE), 1, 0, *VALIDATOR_ID))).return_once( move |_| { proposal_handled_tx.send(()).unwrap(); @@ -267,8 +272,8 @@ async fn test_timeouts() { send(&mut sender, precommit(None, 1, 0, *VALIDATOR_ID_3)).await; let mut context = MockTestContext::new(); - context.expect_set_height_and_round().returning(move |_, _| ()); - context.expect_validate_proposal().returning(move |_, _, _, _| { + context.expect_set_height_and_round().returning(move |_, _, _| ()); + context.expect_validate_proposal().returning(move |_, _, _, _, _| { let (block_sender, block_receiver) = oneshot::channel(); block_sender.send(BlockHash(Felt::ONE)).unwrap(); block_receiver diff --git a/crates/sequencing/papyrus_consensus/src/single_height_consensus.rs b/crates/sequencing/papyrus_consensus/src/single_height_consensus.rs index 856d08ca9f..07b32e908c 100644 --- a/crates/sequencing/papyrus_consensus/src/single_height_consensus.rs +++ b/crates/sequencing/papyrus_consensus/src/single_height_consensus.rs @@ -193,11 +193,15 @@ impl SingleHeightConsensus { context: &mut ContextT, ) -> Result { info!("Starting consensus with validators {:?}", self.validators); - context.set_height_and_round(self.height, self.state_machine.round()).await; + context + .set_height_and_round(self.height, self.state_machine.round(), ValidatorId::default()) + .await; let leader_fn = |round: Round| -> ValidatorId { context.proposer(self.height, round) }; let events = self.state_machine.start(&leader_fn); let ret = self.handle_state_machine_events(context, events).await; - context.set_height_and_round(self.height, self.state_machine.round()).await; + context + .set_height_and_round(self.height, self.state_machine.round(), ValidatorId::default()) + .await; ret } @@ -240,11 +244,14 @@ impl SingleHeightConsensus { .validate_proposal( self.height, init.round, + init.proposer, self.timeouts.proposal_timeout, p2p_messages_receiver, ) .await; - context.set_height_and_round(self.height, self.state_machine.round()).await; + context + .set_height_and_round(self.height, self.state_machine.round(), ValidatorId::default()) + .await; Ok(ShcReturn::Tasks(vec![ShcTask::ValidateProposal(init, block_receiver, fin_receiver)])) } @@ -272,7 +279,13 @@ impl SingleHeightConsensus { } ConsensusMessage::Vote(vote) => { let ret = self.handle_vote(context, vote).await; - context.set_height_and_round(self.height, self.state_machine.round()).await; + context + .set_height_and_round( + self.height, + self.state_machine.round(), + ValidatorId::default(), + ) + .await; ret } } @@ -359,7 +372,9 @@ impl SingleHeightConsensus { } _ => unimplemented!("Unexpected event: {:?}", event), }; - context.set_height_and_round(self.height, self.state_machine.round()).await; + context + .set_height_and_round(self.height, self.state_machine.round(), ValidatorId::default()) + .await; ret } diff --git a/crates/sequencing/papyrus_consensus/src/single_height_consensus_test.rs b/crates/sequencing/papyrus_consensus/src/single_height_consensus_test.rs index 3f0bd44856..e391174bec 100644 --- a/crates/sequencing/papyrus_consensus/src/single_height_consensus_test.rs +++ b/crates/sequencing/papyrus_consensus/src/single_height_consensus_test.rs @@ -94,7 +94,7 @@ async fn proposer() { block_sender.send(BLOCK.id).unwrap(); block_receiver }); - context.expect_set_height_and_round().returning(move |_, _| ()); + context.expect_set_height_and_round().returning(move |_, _, _| ()); context .expect_broadcast() .times(1) @@ -174,12 +174,12 @@ async fn validator(repeat_proposal: bool) { ); context.expect_proposer().returning(move |_, _| *PROPOSER_ID); - context.expect_validate_proposal().times(1).returning(move |_, _, _, _| { + context.expect_validate_proposal().times(1).returning(move |_, _, _, _, _| { let (block_sender, block_receiver) = oneshot::channel(); block_sender.send(BLOCK.id).unwrap(); block_receiver }); - context.expect_set_height_and_round().returning(move |_, _| ()); + context.expect_set_height_and_round().returning(move |_, _, _| ()); context .expect_broadcast() .times(1) @@ -253,12 +253,12 @@ async fn vote_twice(same_vote: bool) { ); context.expect_proposer().times(1).returning(move |_, _| *PROPOSER_ID); - context.expect_validate_proposal().times(1).returning(move |_, _, _, _| { + context.expect_validate_proposal().times(1).returning(move |_, _, _, _, _| { let (block_sender, block_receiver) = oneshot::channel(); block_sender.send(BLOCK.id).unwrap(); block_receiver }); - context.expect_set_height_and_round().returning(move |_, _| ()); + context.expect_set_height_and_round().returning(move |_, _, _| ()); context .expect_broadcast() .times(1) // Shows the repeat vote is ignored. @@ -327,7 +327,7 @@ async fn rebroadcast_votes() { block_sender.send(BLOCK.id).unwrap(); block_receiver }); - context.expect_set_height_and_round().returning(move |_, _| ()); + context.expect_set_height_and_round().returning(move |_, _, _| ()); context .expect_broadcast() .times(1) @@ -389,7 +389,7 @@ async fn repropose() { block_sender.send(BLOCK.id).unwrap(); block_receiver }); - context.expect_set_height_and_round().returning(move |_, _| ()); + context.expect_set_height_and_round().returning(move |_, _, _| ()); context .expect_broadcast() .times(1) diff --git a/crates/sequencing/papyrus_consensus/src/test_utils.rs b/crates/sequencing/papyrus_consensus/src/test_utils.rs index 6c91eae045..8f9a78abdd 100644 --- a/crates/sequencing/papyrus_consensus/src/test_utils.rs +++ b/crates/sequencing/papyrus_consensus/src/test_utils.rs @@ -34,6 +34,7 @@ mock! { &mut self, height: BlockNumber, round: Round, + proposer: ValidatorId, timeout: Duration, content: mpsc::Receiver ) -> oneshot::Receiver; @@ -56,7 +57,12 @@ mock! { precommits: Vec, ) -> Result<(), ConsensusError>; - async fn set_height_and_round(&mut self, height: BlockNumber, round: Round); + async fn set_height_and_round( + &mut self, + height: BlockNumber, + round: Round, + proposer: ValidatorId + ); } } diff --git a/crates/sequencing/papyrus_consensus/src/types.rs b/crates/sequencing/papyrus_consensus/src/types.rs index 2082b23c2c..363bda7e24 100644 --- a/crates/sequencing/papyrus_consensus/src/types.rs +++ b/crates/sequencing/papyrus_consensus/src/types.rs @@ -70,6 +70,7 @@ pub trait ConsensusContext { &mut self, height: BlockNumber, round: Round, + proposer: ValidatorId, timeout: Duration, content: mpsc::Receiver, ) -> oneshot::Receiver; @@ -106,7 +107,12 @@ pub trait ConsensusContext { /// Update the context with the current height and round. /// Must be called at the beginning of each height. - async fn set_height_and_round(&mut self, height: BlockNumber, round: Round); + async fn set_height_and_round( + &mut self, + height: BlockNumber, + round: Round, + proposer: ValidatorId, + ); } #[derive(PartialEq)] diff --git a/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context.rs b/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context.rs index 2fc426d8ec..851c37391c 100644 --- a/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context.rs +++ b/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context.rs @@ -28,7 +28,6 @@ use papyrus_storage::body::BodyStorageReader; use papyrus_storage::header::HeaderStorageReader; use papyrus_storage::{StorageError, StorageReader}; use starknet_api::block::BlockNumber; -use starknet_api::core::ContractAddress; use starknet_api::transaction::Transaction; use tracing::{debug, debug_span, info, warn, Instrument}; @@ -57,7 +56,7 @@ impl PapyrusConsensusContext { Self { storage_reader, network_broadcast_client, - validators: (0..num_validators).map(ContractAddress::from).collect(), + validators: (0..num_validators).map(ValidatorId::from).collect(), sync_broadcast_sender, valid_proposals: Arc::new(Mutex::new(BTreeMap::new())), } @@ -141,6 +140,7 @@ impl ConsensusContext for PapyrusConsensusContext { &mut self, height: BlockNumber, _round: Round, + _proposer: ValidatorId, _timeout: Duration, mut content: mpsc::Receiver, ) -> oneshot::Receiver { @@ -261,7 +261,12 @@ impl ConsensusContext for PapyrusConsensusContext { Ok(()) } - async fn set_height_and_round(&mut self, _height: BlockNumber, _round: Round) { + async fn set_height_and_round( + &mut self, + _height: BlockNumber, + _round: Round, + _proposer: ValidatorId, + ) { // No-op } } diff --git a/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context_test.rs b/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context_test.rs index fdcd4c3ad0..21b7f3c2fd 100644 --- a/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context_test.rs +++ b/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context_test.rs @@ -2,7 +2,7 @@ use std::time::Duration; use futures::channel::{mpsc, oneshot}; use futures::StreamExt; -use papyrus_consensus::types::ConsensusContext; +use papyrus_consensus::types::{ConsensusContext, ValidatorId}; use papyrus_network::network_manager::test_utils::{ mock_register_broadcast_topic, BroadcastNetworkMock, @@ -13,7 +13,6 @@ use papyrus_storage::header::HeaderStorageWriter; use papyrus_storage::test_utils::get_test_storage; use papyrus_test_utils::get_test_block; use starknet_api::block::{Block, BlockHash}; -use starknet_api::core::ContractAddress; use crate::papyrus_consensus_context::PapyrusConsensusContext; @@ -29,7 +28,7 @@ async fn build_proposal() { let proposal_init = ProposalInit { height: block_number, round: 0, - proposer: ContractAddress::default(), + proposer: ValidatorId::default(), valid_round: None, }; // TODO(Asmaa): Test proposal content. @@ -51,7 +50,13 @@ async fn validate_proposal_success() { validate_sender.close_channel(); let fin = papyrus_context - .validate_proposal(block_number, 0, Duration::MAX, validate_receiver) + .validate_proposal( + block_number, + 0, + ValidatorId::default(), + Duration::MAX, + validate_receiver, + ) .await .await .unwrap(); @@ -72,7 +77,13 @@ async fn validate_proposal_fail() { validate_sender.close_channel(); let fin = papyrus_context - .validate_proposal(block_number, 0, Duration::MAX, validate_receiver) + .validate_proposal( + block_number, + 0, + ValidatorId::default(), + Duration::MAX, + validate_receiver, + ) .await .await; assert_eq!(fin, Err(oneshot::Canceled)); diff --git a/crates/sequencing/papyrus_consensus_orchestrator/src/sequencer_consensus_context.rs b/crates/sequencing/papyrus_consensus_orchestrator/src/sequencer_consensus_context.rs index 36a0095e1c..9c377fbe02 100644 --- a/crates/sequencing/papyrus_consensus_orchestrator/src/sequencer_consensus_context.rs +++ b/crates/sequencing/papyrus_consensus_orchestrator/src/sequencer_consensus_context.rs @@ -131,7 +131,12 @@ impl ConsensusContext for SequencerConsensusContext { timeout: Duration, ) -> oneshot::Receiver { // Handles interrupting an active proposal from a previous height/round - self.set_height_and_round(proposal_init.height, proposal_init.round).await; + self.set_height_and_round( + proposal_init.height, + proposal_init.round, + proposal_init.proposer, + ) + .await; debug!( "Building proposal for height: {} with timeout: {:?}", proposal_init.height, timeout @@ -163,7 +168,7 @@ impl ConsensusContext for SequencerConsensusContext { now.timestamp().try_into().expect("Failed to convert timestamp"), ), use_kzg_da: true, - ..Default::default() + sequencer_address: proposal_init.proposer, }, }; // TODO: Should we be returning an error? @@ -202,6 +207,7 @@ impl ConsensusContext for SequencerConsensusContext { &mut self, height: BlockNumber, round: Round, + proposer: ValidatorId, timeout: Duration, content: mpsc::Receiver, ) -> oneshot::Receiver { @@ -214,7 +220,10 @@ impl ConsensusContext for SequencerConsensusContext { fin_receiver } std::cmp::Ordering::Equal => { - self.validate_current_round_proposal(height, timeout, content, fin_sender).await; + self.validate_current_round_proposal( + height, proposer, timeout, content, fin_sender, + ) + .await; fin_receiver } } @@ -271,8 +280,17 @@ impl ConsensusContext for SequencerConsensusContext { Ok(()) } - async fn set_height_and_round(&mut self, height: BlockNumber, round: Round) { - if self.current_height.is_none_or(|h| height > h) { + async fn set_height_and_round( + &mut self, + height: BlockNumber, + round: Round, + proposer: ValidatorId, + ) { + let condition = match self.current_height { + Some(h) => h < height, + None => true, + }; + if condition { self.current_height = Some(height); assert_eq!(round, 0); self.current_round = round; @@ -313,7 +331,7 @@ impl ConsensusContext for SequencerConsensusContext { let Some(((height, timeout, content), fin_sender)) = to_process else { return; }; - self.validate_current_round_proposal(height, timeout, content, fin_sender).await; + self.validate_current_round_proposal(height, proposer, timeout, content, fin_sender).await; } } @@ -321,6 +339,7 @@ impl SequencerConsensusContext { async fn validate_current_round_proposal( &mut self, height: BlockNumber, + proposer: ValidatorId, timeout: Duration, content: mpsc::Receiver>, fin_sender: oneshot::Sender, @@ -350,7 +369,7 @@ impl SequencerConsensusContext { now.timestamp().try_into().expect("Failed to convert timestamp"), ), use_kzg_da: true, - ..Default::default() + sequencer_address: proposer, }, }; batcher.validate_block(input).await.expect("Failed to initiate proposal validation"); diff --git a/crates/sequencing/papyrus_consensus_orchestrator/src/sequencer_consensus_context_test.rs b/crates/sequencing/papyrus_consensus_orchestrator/src/sequencer_consensus_context_test.rs index 58c8978022..f070e1fc9d 100644 --- a/crates/sequencing/papyrus_consensus_orchestrator/src/sequencer_consensus_context_test.rs +++ b/crates/sequencing/papyrus_consensus_orchestrator/src/sequencer_consensus_context_test.rs @@ -5,7 +5,7 @@ use std::vec; use futures::channel::mpsc; use futures::{FutureExt, SinkExt}; use lazy_static::lazy_static; -use papyrus_consensus::types::ConsensusContext; +use papyrus_consensus::types::{ConsensusContext, ValidatorId}; use papyrus_network::network_manager::test_utils::{ mock_register_broadcast_topic, TestSubscriberChannels, @@ -13,7 +13,7 @@ use papyrus_network::network_manager::test_utils::{ use papyrus_network::network_manager::BroadcastTopicChannels; use papyrus_protobuf::consensus::ProposalInit; use starknet_api::block::{BlockHash, BlockNumber}; -use starknet_api::core::{ContractAddress, StateDiffCommitment}; +use starknet_api::core::StateDiffCommitment; use starknet_api::executable_transaction::{AccountTransaction, Transaction}; use starknet_api::hash::PoseidonHash; use starknet_api::test_utils::invoke::{executable_invoke_tx, InvokeTxArgs}; @@ -87,7 +87,7 @@ async fn build_proposal() { let init = ProposalInit { height: BlockNumber(0), round: 0, - proposer: ContractAddress::default(), + proposer: ValidatorId::default(), valid_round: None, }; // TODO(Asmaa): Test proposal content. @@ -138,11 +138,12 @@ async fn validate_proposal_success() { let mut context = SequencerConsensusContext::new(Arc::new(batcher), broadcast_topic_client, NUM_VALIDATORS); // Initialize the context for a specific height, starting with round 0. - context.set_height_and_round(BlockNumber(0), 0).await; + context.set_height_and_round(BlockNumber(0), 0, ValidatorId::default()).await; let (mut content_sender, content_receiver) = mpsc::channel(CHANNEL_SIZE); content_sender.send(TX_BATCH.clone()).await.unwrap(); - let fin_receiver = - context.validate_proposal(BlockNumber(0), 0, TIMEOUT, content_receiver).await; + let fin_receiver = context + .validate_proposal(BlockNumber(0), 0, ValidatorId::default(), TIMEOUT, content_receiver) + .await; content_sender.close_channel(); assert_eq!(fin_receiver.await.unwrap().0, STATE_DIFF_COMMITMENT.0.0); } @@ -179,14 +180,15 @@ async fn repropose() { let mut context = SequencerConsensusContext::new(Arc::new(batcher), broadcast_topic_client, NUM_VALIDATORS); // Initialize the context for a specific height, starting with round 0. - context.set_height_and_round(BlockNumber(0), 0).await; + context.set_height_and_round(BlockNumber(0), 0, ValidatorId::default()).await; // Receive a valid proposal. let (mut content_sender, content_receiver) = mpsc::channel(CHANNEL_SIZE); let txs = vec![generate_invoke_tx(Felt::TWO)]; content_sender.send(txs.clone()).await.unwrap(); - let fin_receiver = - context.validate_proposal(BlockNumber(0), 0, TIMEOUT, content_receiver).await; + let fin_receiver = context + .validate_proposal(BlockNumber(0), 0, ValidatorId::default(), TIMEOUT, content_receiver) + .await; content_sender.close_channel(); assert_eq!(fin_receiver.await.unwrap().0, STATE_DIFF_COMMITMENT.0.0); @@ -242,30 +244,33 @@ async fn proposals_from_different_rounds() { let mut context = SequencerConsensusContext::new(Arc::new(batcher), broadcast_topic_client, NUM_VALIDATORS); // Initialize the context for a specific height, starting with round 0. - context.set_height_and_round(BlockNumber(0), 0).await; - context.set_height_and_round(BlockNumber(0), 1).await; + context.set_height_and_round(BlockNumber(0), 0, ValidatorId::default()).await; + context.set_height_and_round(BlockNumber(0), 1, ValidatorId::default()).await; // The proposal from the past round is ignored. let (mut content_sender, content_receiver) = mpsc::channel(CHANNEL_SIZE); content_sender.send(TX_BATCH.clone()).await.unwrap(); - let fin_receiver_past_round = - context.validate_proposal(BlockNumber(0), 0, TIMEOUT, content_receiver).await; + let fin_receiver_past_round = context + .validate_proposal(BlockNumber(0), 0, ValidatorId::default(), TIMEOUT, content_receiver) + .await; content_sender.close_channel(); assert!(fin_receiver_past_round.await.is_err()); // The proposal from the current round should be validated. let (mut content_sender, content_receiver) = mpsc::channel(CHANNEL_SIZE); content_sender.send(TX_BATCH.clone()).await.unwrap(); - let fin_receiver_curr_round = - context.validate_proposal(BlockNumber(0), 1, TIMEOUT, content_receiver).await; + let fin_receiver_curr_round = context + .validate_proposal(BlockNumber(0), 1, ValidatorId::default(), TIMEOUT, content_receiver) + .await; content_sender.close_channel(); assert_eq!(fin_receiver_curr_round.await.unwrap().0, STATE_DIFF_COMMITMENT.0.0); // The proposal from the future round should not be processed. let (mut content_sender, content_receiver) = mpsc::channel(CHANNEL_SIZE); content_sender.send(TX_BATCH.clone()).await.unwrap(); - let fin_receiver_future_round = - context.validate_proposal(BlockNumber(0), 2, TIMEOUT, content_receiver).await; + let fin_receiver_future_round = context + .validate_proposal(BlockNumber(0), 2, ValidatorId::default(), TIMEOUT, content_receiver) + .await; content_sender.close_channel(); assert!(fin_receiver_future_round.now_or_never().is_none()); } @@ -318,21 +323,23 @@ async fn interrupt_active_proposal() { let mut context = SequencerConsensusContext::new(Arc::new(batcher), broadcast_topic_client, NUM_VALIDATORS); // Initialize the context for a specific height, starting with round 0. - context.set_height_and_round(BlockNumber(0), 0).await; + context.set_height_and_round(BlockNumber(0), 0, ValidatorId::default()).await; // Keep the sender open, as closing it or sending Fin would cause the validate to complete // without needing interrupt. let (mut _content_sender_0, content_receiver) = mpsc::channel(CHANNEL_SIZE); - let fin_receiver_0 = - context.validate_proposal(BlockNumber(0), 0, TIMEOUT, content_receiver).await; + let fin_receiver_0 = context + .validate_proposal(BlockNumber(0), 0, ValidatorId::default(), TIMEOUT, content_receiver) + .await; let (mut content_sender_1, content_receiver) = mpsc::channel(CHANNEL_SIZE); content_sender_1.send(TX_BATCH.clone()).await.unwrap(); - let fin_receiver_1 = - context.validate_proposal(BlockNumber(0), 1, TIMEOUT, content_receiver).await; + let fin_receiver_1 = context + .validate_proposal(BlockNumber(0), 1, ValidatorId::default(), TIMEOUT, content_receiver) + .await; content_sender_1.close_channel(); // Move the context to the next round. - context.set_height_and_round(BlockNumber(0), 1).await; + context.set_height_and_round(BlockNumber(0), 1, ValidatorId::default()).await; // Interrupt active proposal. assert!(fin_receiver_0.await.is_err());