diff --git a/linera-core/src/client/chain_state.rs b/linera-core/src/client/chain_state.rs index 373d17c3043..7fa8863a2f2 100644 --- a/linera-core/src/client/chain_state.rs +++ b/linera-core/src/client/chain_state.rs @@ -44,9 +44,9 @@ pub struct ChainState { /// 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 preparing the next block, to ensure that no - /// other client can begin preparing a block. - preparing_block: Arc>, + /// A mutex that is held whilst we are performing operations that should not be + /// attempted by multiple clients at the same time. + client_mutex: Arc>, } impl ChainState { @@ -72,7 +72,7 @@ impl ChainState { pending_block: None, pending_blobs, received_certificate_trackers: HashMap::new(), - preparing_block: Arc::default(), + client_mutex: Arc::default(), }; if let Some(block) = pending_block { state.set_pending_block(block); @@ -161,7 +161,7 @@ impl ChainState { self.pending_blobs.clear(); } - pub fn preparing_block(&self) -> Arc> { - self.preparing_block.clone() + pub fn client_mutex(&self) -> Arc> { + self.client_mutex.clone() } } diff --git a/linera-core/src/client/mod.rs b/linera-core/src/client/mod.rs index 51d2db3a117..f35823e61fa 100644 --- a/linera-core/src/client/mod.rs +++ b/linera-core/src/client/mod.rs @@ -871,6 +871,9 @@ where #[cfg(with_metrics)] let _latency = metrics::PREPARE_CHAIN_LATENCY.measure_latency(); + let mutex = self.state().client_mutex(); + let _guard = mutex.lock_owned().await; + // Verify that our local storage contains enough history compared to the // expected block height. Otherwise, download the missing history from the // network. @@ -1845,8 +1848,8 @@ where #[cfg(with_metrics)] let _latency = metrics::EXECUTE_BLOCK_LATENCY.measure_latency(); - let block_mutex = self.state().preparing_block(); - let _block_guard = block_mutex.lock_owned().await; + let mutex = self.state().client_mutex(); + let _guard = mutex.lock_owned().await; match self.process_pending_block_without_prepare().await? { ClientOutcome::Committed(Some(certificate)) => { return Ok(ExecuteBlockOutcome::Conflict(certificate)) @@ -3001,10 +3004,13 @@ where /// This is similar to `find_received_certificates` but for only one validator. /// We also don't try to synchronize the admin chain. #[tracing::instrument(level = "trace")] - pub async fn find_received_certificates_from_validator( + async fn find_received_certificates_from_validator( &self, remote_node: RemoteNode, ) -> Result<(), ChainClientError> { + let mutex = self.state().client_mutex(); + let _guard = mutex.lock_owned().await; + let chain_id = self.chain_id; // Proceed to downloading received certificates. let (name, tracker, certificates) = self