diff --git a/linera-chain/src/manager.rs b/linera-chain/src/manager.rs index 4017b491941..435510d743a 100644 --- a/linera-chain/src/manager.rs +++ b/linera-chain/src/manager.rs @@ -115,10 +115,12 @@ pub struct ChainManager { /// Latest validated proposal that we have voted to confirm (or would have, if we are not a /// validator). pub locked: Option, + /// These are blobs belonging to the locked block. + pub locked_blobs: BTreeMap, /// Latest leader timeout certificate we have received. pub timeout: Option, /// Latest vote we have cast, to validate or confirm. - pub pending: Option, + pub pending_vote: Option, /// Latest timeout vote we cast. pub timeout_vote: Option, /// Fallback vote we cast. @@ -134,8 +136,6 @@ pub struct ChainManager { pub current_round: Round, /// The owners that take over in fallback mode. pub fallback_owners: BTreeMap, - /// These are blobs belonging to proposed or validated blocks that have not been confirmed yet. - pub pending_blobs: BTreeMap, } doc_scalar!( @@ -197,20 +197,20 @@ impl ChainManager { fallback_distribution, proposed: None, locked: None, + locked_blobs: BTreeMap::new(), timeout: None, - pending: None, + pending_vote: None, timeout_vote: None, fallback_vote: None, round_timeout, current_round, fallback_owners, - pending_blobs: BTreeMap::new(), }) } /// Returns the most recent vote we cast. pub fn pending(&self) -> Option<&Vote> { - self.pending.as_ref() + self.pending_vote.as_ref() } /// Verifies the safety of a proposed block with respect to voting rules. @@ -340,7 +340,7 @@ impl ChainManager { ) -> Result { let new_block = &certificate.executed_block().block; let new_round = certificate.round; - if let Some(Vote { value, round, .. }) = &self.pending { + if let Some(Vote { value, round, .. }) = &self.pending_vote { match value.inner() { CertificateValue::ConfirmedBlock { executed_block } => { if &executed_block.block == new_block && *round == new_round { @@ -381,14 +381,17 @@ impl ChainManager { key_pair: Option<&KeyPair>, local_time: Timestamp, ) { + let validated_block_certificate = proposal.validated_block_certificate.clone(); + let proposal_content = proposal.content.clone(); + let proposal_blobs = proposal.blobs.clone(); // Record the proposed block, so it can be supplied to clients that request it. - self.proposed = Some(proposal.clone()); + self.update_proposed(proposal); self.update_current_round(local_time); - let ProposalContent { block, round, .. } = proposal.content; + let ProposalContent { block, round, .. } = proposal_content; let executed_block = outcome.with(block); // If the validated block certificate is more recent, update our locked block. - if let Some(lite_cert) = proposal.validated_block_certificate { + if let Some(lite_cert) = validated_block_certificate { if self .locked .as_ref() @@ -396,15 +399,11 @@ impl ChainManager { { let value = HashedCertificateValue::new_validated(executed_block.clone()); if let Some(certificate) = lite_cert.with_value(value) { - self.locked = Some(certificate.into()); + self.update_locked(certificate.into(), proposal_blobs); } } } - for blob in proposal.blobs { - self.pending_blobs.insert(blob.id(), blob); - } - if let Some(key_pair) = key_pair { // If this is a fast block, vote to confirm. Otherwise vote to validate. let value = if round.is_fast() { @@ -412,7 +411,7 @@ impl ChainManager { } else { HashedCertificateValue::new_validated(executed_block) }; - self.pending = Some(Vote::new(value, round, key_pair)); + self.pending_vote = Some(Vote::new(value, round, key_pair)); } } @@ -420,6 +419,7 @@ impl ChainManager { pub fn create_final_vote( &mut self, validated: ValidatedBlockCertificate, + validated_blobs: Vec, key_pair: Option<&KeyPair>, local_time: Timestamp, ) { @@ -430,7 +430,7 @@ impl ChainManager { return; } let confirmed = ConfirmedBlockCertificate::from_validated(validated.clone()); - self.locked = Some(validated); + self.update_locked(validated, validated_blobs); self.update_current_round(local_time); if let Some(key_pair) = key_pair { // Vote to confirm. @@ -438,7 +438,7 @@ impl ChainManager { // back into `Certificate` type so that the vote is cast over hash of the old type. let vote = Vote::new(confirmed.into_inner().into(), round, key_pair); // Ok to overwrite validation votes with confirmation votes at equal or higher round. - self.pending = Some(vote); + self.pending_vote = Some(vote); } } @@ -549,6 +549,31 @@ impl ChainManager { fn is_super(&self, owner: &Owner) -> bool { self.ownership.super_owners.contains_key(owner) } + + fn update_locked(&mut self, new_locked: ValidatedBlockCertificate, validated_blobs: Vec) { + self.locked = Some(new_locked); + self.locked_blobs = validated_blobs + .into_iter() + .map(|blob| (blob.id(), blob)) + .collect(); + } + + fn update_proposed(&mut self, new_proposed: BlockProposal) { + self.proposed = Some(new_proposed); + } + + pub fn proposed_blobs(&self) -> BTreeMap { + self.proposed + .as_ref() + .map(|proposed| { + proposed + .blobs + .iter() + .map(|blob| (blob.id(), blob.clone())) + .collect() + }) + .unwrap_or_default() + } } /// Chain manager information that is included in `ChainInfo` sent to clients. @@ -562,10 +587,12 @@ pub struct ChainManagerInfo { /// Latest validated proposal that we have voted to confirm (or would have, if we are not a /// validator). pub requested_locked: Option>, + /// These are blobs belonging to the locked block. + pub locked_blobs: Vec, /// Latest timeout certificate we have seen. pub timeout: Option>, /// Latest vote we cast (either to validate or to confirm a block). - pub pending: Option, + pub pending_vote: Option, /// Latest timeout vote we cast. pub timeout_vote: Option, /// Fallback vote we cast. @@ -579,8 +606,6 @@ pub struct ChainManagerInfo { pub leader: Option, /// The timestamp when the current round times out. pub round_timeout: Option, - /// These are blobs belonging to proposed or validated blocks that have not been confirmed yet. - pub pending_blobs: BTreeMap, } impl From<&ChainManager> for ChainManagerInfo { @@ -590,15 +615,15 @@ impl From<&ChainManager> for ChainManagerInfo { ownership: manager.ownership.clone(), requested_proposed: None, requested_locked: None, + locked_blobs: Vec::new(), timeout: manager.timeout.clone().map(Box::new), - pending: manager.pending.as_ref().map(|vote| vote.lite()), + pending_vote: manager.pending_vote.as_ref().map(|vote| vote.lite()), timeout_vote: manager.timeout_vote.as_ref().map(Vote::lite), fallback_vote: manager.fallback_vote.as_ref().map(Vote::lite), requested_pending_value: None, current_round, leader: manager.round_leader(current_round).cloned(), round_timeout: manager.round_timeout, - pending_blobs: BTreeMap::new(), } } } @@ -609,10 +634,10 @@ impl ChainManagerInfo { self.requested_proposed = manager.proposed.clone().map(Box::new); self.requested_locked = manager.locked.clone().map(Box::new); self.requested_pending_value = manager - .pending + .pending_vote .as_ref() .map(|vote| Box::new(vote.value.clone())); - self.pending_blobs = manager.pending_blobs.clone(); + self.locked_blobs = manager.locked_blobs.values().cloned().collect(); } /// Gets the highest validated block. diff --git a/linera-core/src/chain_worker/state/attempted_changes.rs b/linera-core/src/chain_worker/state/attempted_changes.rs index 45415b0ece2..b302b1e1a6d 100644 --- a/linera-core/src/chain_worker/state/attempted_changes.rs +++ b/linera-core/src/chain_worker/state/attempted_changes.rs @@ -206,12 +206,15 @@ where .difference(&blobs.iter().map(|blob| blob.id()).collect()) .cloned() .collect(); - self.state - .check_no_missing_blobs(&remaining_required_blob_ids) + let mut validated_blobs = self + .state + .get_proposed_blobs_and_check_storage(&remaining_required_blob_ids) .await?; + validated_blobs.extend_from_slice(blobs); let old_round = self.state.chain.manager.get().current_round; self.state.chain.manager.get_mut().create_final_vote( certificate, + validated_blobs, self.state.config.key_pair(), self.state.storage.clock().current_time(), ); @@ -299,7 +302,7 @@ where .collect(); let mut blobs_in_block = self .state - .get_blobs_and_checks_storage(&remaining_required_blob_ids) + .get_locked_blobs_and_check_storage(&remaining_required_blob_ids) .await?; blobs_in_block.extend_from_slice(blobs); diff --git a/linera-core/src/chain_worker/state/mod.rs b/linera-core/src/chain_worker/state/mod.rs index 27817856848..2b2d516104f 100644 --- a/linera-core/src/chain_worker/state/mod.rs +++ b/linera-core/src/chain_worker/state/mod.rs @@ -306,28 +306,37 @@ where } /// Returns an error if the block requires a blob we don't have. - /// Looks for the blob in: chain manager's pending blobs and storage. - async fn check_no_missing_blobs( + /// Looks for the blob in: chain manager's proposed blobs and storage. + async fn get_proposed_blobs_and_check_storage( &self, - required_blob_ids: &HashSet, - ) -> Result<(), WorkerError> { - let pending_blobs = &self.chain.manager.get().pending_blobs; - let missing_blob_ids = required_blob_ids - .iter() - .filter(|blob_id| !pending_blobs.contains_key(blob_id)) - .cloned() - .collect::>(); - - let missing_blob_ids = self - .storage - .missing_blobs(missing_blob_ids.as_slice()) - .await?; + blob_ids: &HashSet, + ) -> Result, WorkerError> { + let pending_blobs = self.chain.manager.get().proposed_blobs(); + self.get_blobs_and_check_storage(blob_ids, &pending_blobs) + .await + } - if missing_blob_ids.is_empty() { - return Ok(()); + async fn get_blobs_and_check_storage( + &self, + blob_ids: &HashSet, + pending_blobs: &BTreeMap, + ) -> Result, WorkerError> { + let mut found_blobs = Vec::new(); + let mut missing_blob_ids = Vec::new(); + for blob_id in blob_ids { + if let Some(blob) = pending_blobs.get(blob_id) { + found_blobs.push(blob.clone()); + } else { + missing_blob_ids.push(*blob_id); + } } + let not_found_blob_ids = self.storage.missing_blobs(&missing_blob_ids).await?; - Err(WorkerError::BlobsNotFound(missing_blob_ids)) + if not_found_blob_ids.is_empty() { + Ok(found_blobs) + } else { + Err(WorkerError::BlobsNotFound(not_found_blob_ids)) + } } /// Returns an error if unrelated blobs were provided. @@ -348,30 +357,15 @@ where Ok(()) } - /// Returns the blobs requested by their `blob_ids` that are in the chain manager's pending blobs - /// and checks that they are otherwise in storage. - async fn get_blobs_and_checks_storage( + /// Returns the blobs requested by their `blob_ids` that are in the chain manager's locked blobs + /// and check that they are otherwise in storage. + async fn get_locked_blobs_and_check_storage( &self, blob_ids: &HashSet, ) -> Result, WorkerError> { - let pending_blobs = &self.chain.manager.get().pending_blobs; - - let mut found_blobs = Vec::new(); - let mut missing_blob_ids = Vec::new(); - for blob_id in blob_ids { - if let Some(blob) = pending_blobs.get(blob_id) { - found_blobs.push(blob.clone()); - } else { - missing_blob_ids.push(*blob_id); - } - } - let not_found_blob_ids = self.storage.missing_blobs(&missing_blob_ids).await?; - - if not_found_blob_ids.is_empty() { - Ok(found_blobs) - } else { - Err(WorkerError::BlobsNotFound(not_found_blob_ids)) - } + let pending_blobs = &self.chain.manager.get().locked_blobs; + self.get_blobs_and_check_storage(blob_ids, pending_blobs) + .await } /// Adds any newly created chains to the set of `tracked_chains`, if the parent chain is diff --git a/linera-core/src/client/chain_client_state.rs b/linera-core/src/client/chain_client_state.rs index a8116a0c520..def6641bb90 100644 --- a/linera-core/src/client/chain_client_state.rs +++ b/linera-core/src/client/chain_client_state.rs @@ -33,15 +33,15 @@ pub struct ChainClientState { /// /// This is always at the same height as `next_block_height`. pending_block: Option, + /// This contains blobs belonging to our `pending_block` that may not even have + /// been processed by (i.e. been proposed to) our own local chain manager yet. + pending_blobs: BTreeMap, /// Known key pairs from present and past identities. known_key_pairs: BTreeMap, /// For each validator, up to which index we have synchronized their /// [`ChainStateView::received_log`]. received_certificate_trackers: HashMap, - /// This contains blobs belonging to our `pending_block` that may not even have - /// been processed by (i.e. been proposed to) our own local chain manager yet. - pending_blobs: BTreeMap, /// A mutex that is held whilst we are performing operations that should not be /// attempted by multiple clients at the same time. diff --git a/linera-core/src/client/mod.rs b/linera-core/src/client/mod.rs index e7f14255f5e..05c31a6a368 100644 --- a/linera-core/src/client/mod.rs +++ b/linera-core/src/client/mod.rs @@ -1753,7 +1753,7 @@ where &original_err { if let Some(new_blobs) = remote_node - .find_missing_blobs(blob_ids.clone(), chain_id) + .find_missing_blobs(blob_ids.clone(), &info.manager.locked_blobs) .await? { blobs = new_blobs; @@ -1898,13 +1898,14 @@ where } } - /// Tries to read blobs from either the pending blobs or the local node's cache, or - /// storage + /// Tries to read blobs from either the locked blobs or the + /// chain client's pending blobs. #[instrument(level = "trace")] async fn read_local_blobs( &self, blob_ids: impl IntoIterator + std::fmt::Debug, ) -> Result, LocalNodeError> { + let mut missing_blob_ids = Vec::new(); let mut blobs = Vec::new(); for blob_id in blob_ids { let maybe_blob = self.pending_blobs().get(&blob_id).cloned(); @@ -1918,7 +1919,7 @@ where chain_state_view .manager .get() - .pending_blobs + .locked_blobs .get(&blob_id) .cloned() }; @@ -1928,11 +1929,16 @@ where continue; } - return Err(LocalNodeError::CannotReadLocalBlob { + missing_blob_ids.push(blob_id); + } + + if !missing_blob_ids.is_empty() { + return Err(LocalNodeError::CannotReadLocalBlobs { chain_id: self.chain_id, - blob_id, + blob_ids: missing_blob_ids, }); } + Ok(blobs) } @@ -2008,7 +2014,12 @@ where // Create the final block proposal. let key_pair = self.key_pair().await?; let proposal = if let Some(cert) = manager.requested_locked { - Box::new(BlockProposal::new_retry(round, *cert, &key_pair, blobs)) + Box::new(BlockProposal::new_retry( + round, + *cert, + &key_pair, + manager.locked_blobs, + )) } else { Box::new(BlockProposal::new_initial( round, diff --git a/linera-core/src/local_node.rs b/linera-core/src/local_node.rs index b2441e499bc..3d5f4e7ea07 100644 --- a/linera-core/src/local_node.rs +++ b/linera-core/src/local_node.rs @@ -61,8 +61,11 @@ pub enum LocalNodeError { #[error("Local node operation failed: {0}")] WorkerError(#[from] WorkerError), - #[error("Failed to read blob {blob_id:?} of chain {chain_id:?}")] - CannotReadLocalBlob { chain_id: ChainId, blob_id: BlobId }, + #[error("Failed to read blobs {blob_ids:?} of chain {chain_id:?}")] + CannotReadLocalBlobs { + chain_id: ChainId, + blob_ids: Vec, + }, #[error("The local node doesn't have an active chain {0:?}")] InactiveChain(ChainId), @@ -204,13 +207,51 @@ where } // Find the missing blobs locally and retry. - let required = match certificate.value() { - CertificateValue::ConfirmedBlock { executed_block, .. } - | CertificateValue::ValidatedBlock { executed_block, .. } => { - executed_block.required_blob_ids() + match certificate.value() { + CertificateValue::ConfirmedBlock { executed_block, .. } => { + self.check_missing_blob_ids(executed_block, missing_blob_ids)?; + let storage = self.storage_client(); + Ok(Some( + storage + .read_blobs(missing_blob_ids) + .await? + .into_iter() + .flatten() + .collect(), + )) + } + CertificateValue::ValidatedBlock { executed_block, .. } => { + let unique_missing_blob_ids = + self.check_missing_blob_ids(executed_block, missing_blob_ids)?; + Ok(Some( + self.chain_state_view(chain_id) + .await? + .manager + .get() + .locked_blobs + .iter() + .filter(|(blob_id, _)| unique_missing_blob_ids.contains(blob_id)) + .map(|(_, blob)| blob.clone()) + .collect(), + )) } - CertificateValue::Timeout { .. } => HashSet::new(), - }; + CertificateValue::Timeout { .. } => { + warn!( + "validator requested blobs {:?} but they're not required", + missing_blob_ids + ); + Err(NodeError::InvalidChainInfoResponse) + } + } + } + + #[allow(clippy::result_large_err)] + fn check_missing_blob_ids( + &self, + executed_block: &ExecutedBlock, + missing_blob_ids: &Vec, + ) -> Result, NodeError> { + let required = executed_block.required_blob_ids(); for blob_id in missing_blob_ids { if !required.contains(blob_id) { warn!( @@ -220,38 +261,14 @@ where return Err(NodeError::InvalidChainInfoResponse); } } - let mut unique_missing_blob_ids = missing_blob_ids.iter().cloned().collect::>(); + + let unique_missing_blob_ids = missing_blob_ids.iter().cloned().collect::>(); if missing_blob_ids.len() > unique_missing_blob_ids.len() { warn!("blobs requested by validator contain duplicates"); return Err(NodeError::InvalidChainInfoResponse); } - let mut chain_manager_pending_blobs = self - .chain_state_view(chain_id) - .await? - .manager - .get() - .pending_blobs - .clone(); - let mut found_blobs = Vec::new(); - for blob_id in missing_blob_ids { - if let Some(blob) = chain_manager_pending_blobs.remove(blob_id) { - found_blobs.push(blob); - unique_missing_blob_ids.remove(blob_id); - } - } - - let storage = self.storage_client(); - let Some(read_blobs) = storage - .read_blobs(&unique_missing_blob_ids.into_iter().collect::>()) - .await? - .into_iter() - .collect::>>() - else { - return Ok(None); - }; - found_blobs.extend(read_blobs); - Ok(Some(found_blobs)) + Ok(unique_missing_blob_ids) } /// Returns a read-only view of the [`ChainStateView`] of a chain referenced by its diff --git a/linera-core/src/remote_node.rs b/linera-core/src/remote_node.rs index f42c74770c5..73248f7dc95 100644 --- a/linera-core/src/remote_node.rs +++ b/linera-core/src/remote_node.rs @@ -1,7 +1,10 @@ // Copyright (c) Zefchain Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -use std::{collections::HashMap, fmt}; +use std::{ + collections::{HashMap, HashSet}, + fmt, +}; use futures::{stream::FuturesUnordered, StreamExt}; use linera_base::{ @@ -197,31 +200,21 @@ impl RemoteNode { pub(crate) async fn find_missing_blobs( &self, blob_ids: Vec, - chain_id: ChainId, + locked_blobs: &[Blob], ) -> Result>, NodeError> { - let query = ChainInfoQuery::new(chain_id).with_manager_values(); - let info = match self.handle_chain_info_query(query).await { - Ok(info) => Some(info), - Err(err) => { - warn!("Got error from validator {}: {}", self.name, err); - return Ok(None); - } - }; - - let mut missing_blobs = blob_ids; - let mut found_blobs = if let Some(info) = info { - let new_found_blobs = missing_blobs - .iter() - .filter_map(|blob_id| info.manager.pending_blobs.get(blob_id)) - .map(|blob| (blob.id(), blob.clone())) - .collect::>(); - missing_blobs.retain(|blob_id| !new_found_blobs.contains_key(blob_id)); - new_found_blobs.into_values().collect() - } else { - Vec::new() - }; + let mut missing_blob_ids = blob_ids.into_iter().collect::>(); + let new_found_blobs = locked_blobs + .iter() + .filter(|blob| missing_blob_ids.contains(&blob.id())) + .map(|blob| (blob.id(), blob.clone())) + .collect::>(); + missing_blob_ids.retain(|blob_id| !new_found_blobs.contains_key(blob_id)); + let mut found_blobs: Vec = new_found_blobs.into_values().collect(); - if let Some(blobs) = self.try_download_blobs(&missing_blobs).await { + if let Some(blobs) = self + .try_download_blobs(&missing_blob_ids.into_iter().collect::>()) + .await + { found_blobs.extend(blobs); Ok(Some(found_blobs)) } else { diff --git a/linera-core/src/unit_tests/wasm_worker_tests.rs b/linera-core/src/unit_tests/wasm_worker_tests.rs index 6187e92e073..4b1435d6cc0 100644 --- a/linera-core/src/unit_tests/wasm_worker_tests.rs +++ b/linera-core/src/unit_tests/wasm_worker_tests.rs @@ -164,7 +164,7 @@ where assert_eq!(BlockHeight::from(1), info.next_block_height); assert_eq!(Timestamp::from(1), info.timestamp); assert_eq!(Some(publish_certificate.hash()), info.block_hash); - assert!(info.manager.pending.is_none()); + assert!(info.manager.pending_vote.is_none()); let mut creator_system_state = SystemExecutionState { committees: [(Epoch::ZERO, committee.clone())].into_iter().collect(), @@ -247,7 +247,7 @@ where assert_eq!(BlockHeight::from(1), info.next_block_height); assert_eq!(Timestamp::from(2), info.timestamp); assert_eq!(Some(create_certificate.hash()), info.block_hash); - assert!(info.manager.pending.is_none()); + assert!(info.manager.pending_vote.is_none()); // Execute an application operation let increment = 5_u64; @@ -300,6 +300,6 @@ where assert_eq!(BlockHeight::from(2), info.next_block_height); assert_eq!(Some(run_certificate.hash()), info.block_hash); assert_eq!(Timestamp::from(3), info.timestamp); - assert!(info.manager.pending.is_none()); + assert!(info.manager.pending_vote.is_none()); Ok(()) } diff --git a/linera-core/src/unit_tests/worker_tests.rs b/linera-core/src/unit_tests/worker_tests.rs index 891d2ac8ecf..245489cd41d 100644 --- a/linera-core/src/unit_tests/worker_tests.rs +++ b/linera-core/src/unit_tests/worker_tests.rs @@ -1115,7 +1115,7 @@ where assert!(chain.is_active()); let pending_value = chain.manager.get().pending().unwrap().lite(); assert_eq!( - chain_info_response.info.manager.pending.unwrap(), + chain_info_response.info.manager.pending_vote.unwrap(), pending_value ); Ok(()) @@ -1846,7 +1846,7 @@ where assert_eq!(Amount::ZERO, info.chain_balance); assert_eq!(BlockHeight::from(1), info.next_block_height); assert_eq!(Some(certificate.hash()), info.block_hash); - assert!(info.manager.pending.is_none()); + assert!(info.manager.pending_vote.is_none()); assert_eq!( worker .query_application(ChainId::root(1), Query::System(SystemQuery)) @@ -1972,7 +1972,7 @@ where assert_eq!(Amount::ZERO, info.chain_balance); assert_eq!(BlockHeight::from(1), info.next_block_height); assert_eq!(Some(certificate.hash()), info.block_hash); - assert!(info.manager.pending.is_none()); + assert!(info.manager.pending_vote.is_none()); Ok(()) } @@ -3211,12 +3211,12 @@ where let value1 = HashedCertificateValue::new_validated(executed_block1.clone()); // If we send the validated block certificate to the worker, it votes to confirm. - let vote = response.info.manager.pending.clone().unwrap(); + let vote = response.info.manager.pending_vote.clone().unwrap(); let certificate1 = vote.with_value(value1.clone()).unwrap().into_certificate(); let (response, _) = worker .handle_certificate(certificate1.clone(), vec![], None) .await?; - let vote = response.info.manager.pending.as_ref().unwrap(); + let vote = response.info.manager.pending_vote.as_ref().unwrap(); let value = HashedCertificateValue::new_confirmed(executed_block1.clone()); assert_eq!(vote.value, value.lite()); @@ -3277,7 +3277,7 @@ where response.info.manager.requested_locked, Some(Box::new(certificate2.into())) ); - let vote = response.info.manager.pending.as_ref().unwrap(); + let vote = response.info.manager.pending_vote.as_ref().unwrap(); assert_eq!(vote.value, lite_value2); assert_eq!(vote.round, Round::SingleLeader(5)); @@ -3459,7 +3459,7 @@ where let (executed_block1, _) = worker.stage_block_execution(block1.clone()).await?; let value1 = HashedCertificateValue::new_confirmed(executed_block1); let (response, _) = worker.handle_block_proposal(proposal1).await?; - let vote = response.info.manager.pending.as_ref().unwrap(); + let vote = response.info.manager.pending_vote.as_ref().unwrap(); assert_eq!(vote.value.value_hash, value1.hash()); // Set the clock to the end of the round. @@ -3511,7 +3511,7 @@ where response.info.manager.requested_locked, Some(Box::new(certificate2.into())) ); - let vote = response.info.manager.pending.as_ref().unwrap(); + let vote = response.info.manager.pending_vote.as_ref().unwrap(); assert_eq!(vote.value, lite_value2); assert_eq!(vote.round, Round::MultiLeader(1)); Ok(()) diff --git a/linera-core/src/updater.rs b/linera-core/src/updater.rs index f7991254764..0d2ecbbb569 100644 --- a/linera-core/src/updater.rs +++ b/linera-core/src/updater.rs @@ -426,14 +426,14 @@ where let vote = match action { CommunicateAction::SubmitBlock { proposal, blob_ids } => { let info = self.send_block_proposal(proposal, blob_ids).await?; - info.manager.pending + info.manager.pending_vote } CommunicateAction::FinalizeBlock { certificate, delivery, } => { let info = self.send_certificate(certificate, delivery).await?; - info.manager.pending + info.manager.pending_vote } CommunicateAction::RequestTimeout { .. } => { let query = ChainInfoQuery::new(chain_id).with_timeout(); diff --git a/linera-rpc/tests/snapshots/format__format.yaml.snap b/linera-rpc/tests/snapshots/format__format.yaml.snap index 16af48be5b7..2a51727a324 100644 --- a/linera-rpc/tests/snapshots/format__format.yaml.snap +++ b/linera-rpc/tests/snapshots/format__format.yaml.snap @@ -267,10 +267,13 @@ ChainManagerInfo: - requested_locked: OPTION: TYPENAME: ValidatedBlockCertificate + - locked_blobs: + SEQ: + TYPENAME: BlobContent - timeout: OPTION: TYPENAME: TimeoutCertificate - - pending: + - pending_vote: OPTION: TYPENAME: LiteVote - timeout_vote: @@ -290,12 +293,6 @@ ChainManagerInfo: - round_timeout: OPTION: TYPENAME: Timestamp - - pending_blobs: - MAP: - KEY: - TYPENAME: BlobId - VALUE: - TYPENAME: BlobContent ChainOwnership: STRUCT: - super_owners: diff --git a/linera-service/src/linera/main.rs b/linera-service/src/linera/main.rs index 70228e36f4b..fac7328edb1 100644 --- a/linera-service/src/linera/main.rs +++ b/linera-service/src/linera/main.rs @@ -735,7 +735,7 @@ impl Runnable for Job { .into_iter() .filter_map(|message| { let response = deserialize_response(message)?; - let vote = response.info.manager.pending?; + let vote = response.info.manager.pending_vote?; let value = values.get(&vote.value.value_hash)?.clone(); vote.clone().with_value(value) })