Skip to content

Commit

Permalink
Inline propose_block and simplify `process_pending_block_without_pr…
Browse files Browse the repository at this point in the history
…epare`. (#2938)

* Inline propose_block.

* Simplify process_pending_block_without_prepare.

* Move re-proposing the locked block to a separate if block.

* Return errors directly from round_for_new_proposal.

* Extract more logic from process_pending_block_without_prepare.

* Update the state from info inside the chain_info methods.

* Extract request_leader_timeout_if_needed.

* Extract finalize_locked_block.

* Avoid cloning the block.

* Return round timeout directly from round_for_new_proposal.
  • Loading branch information
afck authored Nov 21, 2024
1 parent 3a66ab0 commit 5044836
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 208 deletions.
29 changes: 14 additions & 15 deletions linera-chain/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -684,21 +684,6 @@ impl ChainManagerInfo {
self.pending_blobs = manager.pending_blobs.clone();
}

/// Gets the highest validated block.
pub fn highest_validated_block(&self) -> Option<&Block> {
if let Some(certificate) = &self.requested_locked {
return Some(&certificate.executed_block().block);
}

if let Some(proposal) = &self.requested_proposed {
if proposal.content.round.is_fast() {
return Some(&proposal.content.block);
}
}

None
}

/// Returns whether the `identity` is allowed to propose a block in `round`.
/// This is dependant on the type of round and whether `identity` is a validator or (super)owner.
pub fn can_propose(&self, identity: &Owner, round: Round) -> bool {
Expand All @@ -708,4 +693,18 @@ impl ChainManagerInfo {
Round::SingleLeader(_) | Round::Validator(_) => self.leader.as_ref() == Some(identity),
}
}

/// Returns whether a proposal with this content was already handled.
pub fn already_handled_proposal(&self, round: Round, block: &Block) -> bool {
self.requested_proposed.as_ref().is_some_and(|proposal| {
proposal.content.round == round && proposal.content.block == *block
})
}

/// Returns whether there is a locked block in the current round.
pub fn has_locked_block_in_current_round(&self) -> bool {
self.requested_locked
.as_ref()
.is_some_and(|certificate| certificate.round == self.current_round)
}
}
15 changes: 15 additions & 0 deletions linera-core/src/client/chain_client_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ use std::{
use linera_base::{
crypto::{CryptoHash, KeyPair, PublicKey},
data_types::{Blob, BlockHeight, Timestamp},
ensure,
identifiers::{BlobId, Owner},
ownership::ChainOwnership,
};
use linera_chain::data_types::Block;
use linera_execution::committee::ValidatorName;
use tokio::sync::Mutex;

use super::ChainClientError;
use crate::data_types::ChainInfo;

/// The state of our interaction with a particular chain: how far we have synchronized it and
Expand Down Expand Up @@ -168,4 +170,17 @@ impl ChainClientState {
pub(super) fn client_mutex(&self) -> Arc<Mutex<()>> {
self.client_mutex.clone()
}

/// Returns an error if the chain info does not match the block hash and height.
pub(super) fn check_info_is_up_to_date(
&self,
info: &ChainInfo,
) -> Result<(), ChainClientError> {
ensure!(
self.block_hash() == info.block_hash
&& self.next_block_height() == info.next_block_height,
ChainClientError::BlockProposalError("The chain is not synchronized.")
);
Ok(())
}
}
Loading

0 comments on commit 5044836

Please sign in to comment.