diff --git a/crates/hotshot/task-impls/src/transactions.rs b/crates/hotshot/task-impls/src/transactions.rs index bd05abb1eb..525903ddc4 100644 --- a/crates/hotshot/task-impls/src/transactions.rs +++ b/crates/hotshot/task-impls/src/transactions.rs @@ -21,7 +21,7 @@ use hotshot_types::{ event::{Event, EventType}, message::UpgradeLock, traits::{ - block_contents::{BuilderFee, EncodeBytes}, + block_contents::{BlockHeader, BuilderFee, EncodeBytes}, node_implementation::{ConsensusTime, NodeType, Versions}, signature_key::{BuilderSignatureKey, SignatureKey}, BlockPayload, @@ -116,16 +116,9 @@ impl TransactionTaskState { event_stream: &Sender>>, block_view: TYPES::View, block_epoch: Option, + vid: Option, ) -> Option { - let _version = match self.upgrade_lock.version(block_view).await { - Ok(v) => v, - Err(e) => { - tracing::error!("Failed to calculate version: {e:?}"); - return None; - }, - }; - - self.handle_view_change_legacy(event_stream, block_view, block_epoch) + self.handle_view_change_legacy(event_stream, block_view, block_epoch, vid) .await } @@ -136,6 +129,7 @@ impl TransactionTaskState { event_stream: &Sender>>, block_view: TYPES::View, block_epoch: Option, + vid: Option, ) -> Option { let version = match self.upgrade_lock.version(block_view).await { Ok(v) => v, @@ -219,7 +213,7 @@ impl TransactionTaskState { { None } else { - self.wait_for_block(block_view).await + self.wait_for_block(block_view, vid).await } }; @@ -366,7 +360,50 @@ impl TransactionTaskState { .leader(view) .await?; if leader == self.public_key { - self.handle_view_change(&event_stream, view, *epoch).await; + self.handle_view_change(&event_stream, view, *epoch, None) + .await; + return Ok(()); + } + }, + HotShotEvent::QuorumProposalValidated(proposal, _leaf) => { + let view_number = proposal.data.view_number(); + let next_view = view_number + 1; + + let version = match self.upgrade_lock.version(next_view).await { + Ok(v) => v, + Err(e) => { + tracing::error!("Failed to calculate version: {e:?}"); + return Ok(()); + }, + }; + + if version < V::DrbAndHeaderUpgrade::VERSION { + return Ok(()); + } + + let vid = proposal.data.block_header().payload_commitment(); + let block_height = proposal.data.block_header().block_number(); + if is_epoch_transition(block_height, self.epoch_height) { + return Ok(()); + } + if is_last_block(block_height, self.epoch_height) { + return Ok(()); + } + if next_view <= self.cur_view { + return Ok(()); + } + // move to next view for this task only + self.cur_view = next_view; + + let leader = self + .membership_coordinator + .membership_for_epoch(self.cur_epoch) + .await? + .leader(next_view) + .await?; + if leader == self.public_key { + self.handle_view_change(&event_stream, next_view, self.cur_epoch, Some(vid)) + .await; return Ok(()); } }, @@ -444,19 +481,27 @@ impl TransactionTaskState { } #[instrument(skip_all, fields(id = self.id, cur_view = *self.cur_view, block_view = *block_view), name = "wait_for_block", level = "error")] - async fn wait_for_block(&self, block_view: TYPES::View) -> Option> { + async fn wait_for_block( + &self, + block_view: TYPES::View, + vid: Option, + ) -> Option> { let task_start_time = Instant::now(); // Find commitment to the block we want to build upon - let (parent_view, parent_comm) = match self - .last_vid_commitment_retry(block_view, task_start_time) - .await - { - Ok((v, c)) => (v, c), - Err(e) => { - tracing::warn!("Failed to find last vid commitment in time: {e}"); - return None; - }, + let (parent_view, parent_comm) = if let Some(vid) = vid { + (block_view - 1, vid) + } else { + match self + .last_vid_commitment_retry(block_view, task_start_time) + .await + { + Ok((v, c)) => (v, c), + Err(e) => { + tracing::warn!("Failed to find last vid commitment in time: {e}"); + return None; + }, + } }; let parent_comm_sig = match <::SignatureKey as SignatureKey>::sign(