Skip to content

Commit dfd3fa0

Browse files
committed
Fix updater.
1 parent 017aad8 commit dfd3fa0

File tree

4 files changed

+44
-76
lines changed

4 files changed

+44
-76
lines changed

linera-core/src/chain_worker/state.rs

Lines changed: 18 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -762,61 +762,35 @@ where
762762
{
763763
certificate.check(committee)?;
764764
} else {
765-
// Inline committees_for logic with specific error handling.
766765
let net_description = self
767766
.storage
768767
.read_network_description()
769768
.await?
770769
.ok_or_else(|| WorkerError::MissingNetworkDescription)?;
771-
let admin_chain_id = net_description.admin_chain_id;
772-
773-
let committee = if epoch == Epoch::ZERO {
770+
let committee_hash = if epoch == Epoch::ZERO {
774771
// Genesis epoch is stored in NetworkDescription.
775-
let blob_id = BlobId::new(
776-
net_description.genesis_committee_blob_hash,
777-
BlobType::Committee,
778-
);
779-
let committee_blob = self
780-
.storage
781-
.read_blob(blob_id)
782-
.await?
783-
.ok_or_else(|| WorkerError::BlobsNotFound(vec![blob_id]))?;
784-
bcs::from_bytes::<Committee>(committee_blob.bytes())
785-
.map_err(|e| WorkerError::from(linera_views::ViewError::from(e)))?
772+
net_description.genesis_committee_blob_hash
786773
} else {
787774
// Read the epoch creation event.
788-
let epoch_creation_events = self
789-
.storage
790-
.read_events_from_index(
791-
&admin_chain_id,
792-
&StreamId::system(EPOCH_STREAM_NAME),
793-
epoch.0,
794-
)
795-
.await?;
796-
797-
let event = epoch_creation_events
798-
.into_iter()
799-
.find(|index_and_event| index_and_event.index == epoch.0)
800-
.ok_or_else(|| {
801-
WorkerError::EventsNotFound(vec![EventId {
802-
chain_id: admin_chain_id,
803-
stream_id: StreamId::system(EPOCH_STREAM_NAME),
804-
index: epoch.0,
805-
}])
806-
})?;
807-
808-
let committee_hash: CryptoHash = bcs::from_bytes(&event.event)
809-
.map_err(|e| WorkerError::from(linera_views::ViewError::from(e)))?;
810-
let blob_id = BlobId::new(committee_hash, BlobType::Committee);
811-
let committee_blob = self
775+
let event_id = EventId {
776+
chain_id: net_description.admin_chain_id,
777+
stream_id: StreamId::system(EPOCH_STREAM_NAME),
778+
index: epoch.0,
779+
};
780+
let event = self
812781
.storage
813-
.read_blob(blob_id)
782+
.read_event(event_id.clone())
814783
.await?
815-
.ok_or_else(|| WorkerError::BlobsNotFound(vec![blob_id]))?;
816-
bcs::from_bytes::<Committee>(committee_blob.bytes())
817-
.map_err(|e| WorkerError::from(linera_views::ViewError::from(e)))?
784+
.ok_or_else(|| WorkerError::EventsNotFound(vec![event_id]))?;
785+
bcs::from_bytes(&event)?
818786
};
819-
// This line is duplicated, but this avoids cloning and a lifetimes error.
787+
let blob_id = BlobId::new(committee_hash, BlobType::Committee);
788+
let committee_blob = self
789+
.storage
790+
.read_blob(blob_id)
791+
.await?
792+
.ok_or_else(|| WorkerError::BlobsNotFound(vec![blob_id]))?;
793+
let committee = bcs::from_bytes(committee_blob.bytes())?;
820794
certificate.check(&committee)?;
821795
}
822796

linera-core/src/updater.rs

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,7 @@ where
248248
loop {
249249
match result {
250250
Err(NodeError::EventsNotFound(event_ids))
251-
if self.admin_id != certificate.block().header.chain_id
252-
&& !sent_admin_chain
251+
if !sent_admin_chain
253252
&& certificate.inner().chain_id() != self.admin_id
254253
&& event_ids.iter().all(|event_id| {
255254
event_id.stream_id == StreamId::system(EPOCH_STREAM_NAME)
@@ -260,18 +259,6 @@ where
260259
self.update_admin_chain().await?;
261260
sent_admin_chain = true;
262261
}
263-
Err(NodeError::BlobsNotFound(blob_ids))
264-
if blob_ids
265-
.iter()
266-
.all(|id| id.blob_type == BlobType::Committee) =>
267-
{
268-
if sent_admin_chain || self.admin_id == certificate.block().header.chain_id {
269-
return Err(NodeError::BlobsNotFound(blob_ids).into());
270-
}
271-
// The validator doesn't have the committee that signed the certificate.
272-
self.update_admin_chain().await?;
273-
sent_admin_chain = true;
274-
}
275262
Err(NodeError::BlobsNotFound(blob_ids)) if !sent_blobs => {
276263
// The validator is missing the blobs required by the certificate.
277264
self.remote_node
@@ -306,7 +293,7 @@ where
306293
.await;
307294

308295
let chain_id = certificate.inner().chain_id();
309-
Ok(match &result {
296+
match &result {
310297
Err(original_err @ NodeError::BlobsNotFound(blob_ids)) => {
311298
self.remote_node
312299
.check_blobs_not_found(&certificate, blob_ids)?;
@@ -319,9 +306,6 @@ where
319306
.await?
320307
.ok_or_else(|| original_err.clone())?;
321308
self.remote_node.send_pending_blobs(chain_id, blobs).await?;
322-
self.remote_node
323-
.handle_validated_certificate(certificate)
324-
.await
325309
}
326310
Err(error) => {
327311
self.sync_if_needed(
@@ -331,12 +315,13 @@ where
331315
error,
332316
)
333317
.await?;
334-
self.remote_node
335-
.handle_validated_certificate(certificate)
336-
.await
337318
}
338-
_ => result,
339-
}?)
319+
_ => return Ok(result?),
320+
}
321+
Ok(self
322+
.remote_node
323+
.handle_validated_certificate(certificate)
324+
.await?)
340325
}
341326

342327
/// Requests a vote for a timeout certificate for the given round from the remote node.
@@ -616,11 +601,7 @@ where
616601
target_block_height: BlockHeight,
617602
delivery: CrossChainMessageDelivery,
618603
) -> Result<(), chain_client::Error> {
619-
let info = if let Some(height) = target_block_height
620-
.try_sub_one()
621-
.ok()
622-
.filter(|_| chain_id != self.admin_id)
623-
{
604+
let info = if let Ok(height) = target_block_height.try_sub_one() {
624605
// Figure out which certificates this validator is missing. In many cases, it's just the
625606
// last one, so we optimistically send that one right away.
626607
let hash = self
@@ -644,9 +625,17 @@ where
644625
.read_certificate(hash)
645626
.await?
646627
.ok_or_else(|| chain_client::Error::MissingConfirmedBlock(hash))?;
647-
let info = self
648-
.send_confirmed_certificate(certificate, delivery)
649-
.await?;
628+
let info = match self.send_confirmed_certificate(certificate, delivery).await {
629+
Ok(info) => info,
630+
Err(error) => {
631+
tracing::debug!(
632+
address = self.remote_node.address(), %error,
633+
"validator failed to handle confirmed certificate; sending whole chain",
634+
);
635+
let query = ChainInfoQuery::new(chain_id);
636+
self.remote_node.handle_chain_info_query(query).await?
637+
}
638+
};
650639
// Obtain the missing blocks and the manager state from the local node.
651640
let heights = (info.next_block_height.0..target_block_height.0).map(BlockHeight);
652641
let validator_missing_hashes = self

linera-core/src/worker.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ pub enum WorkerError {
172172
#[error(transparent)]
173173
ChainError(#[from] Box<ChainError>),
174174

175+
#[error(transparent)]
176+
BcsError(#[from] bcs::Error),
177+
175178
// Chain access control
176179
#[error("Block was not signed by an authorized owner")]
177180
InvalidOwner,
@@ -279,7 +282,8 @@ impl WorkerError {
279282
| WorkerError::UnexpectedBlob
280283
| WorkerError::TooManyPublishedBlobs(_)
281284
| WorkerError::ViewError(ViewError::NotFound(_)) => false,
282-
WorkerError::InvalidCrossChainRequest
285+
WorkerError::BcsError(_)
286+
| WorkerError::InvalidCrossChainRequest
283287
| WorkerError::ViewError(_)
284288
| WorkerError::ConfirmedLogEntryNotFound { .. }
285289
| WorkerError::PreprocessedBlocksEntryNotFound { .. }

linera-service/src/cli/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2200,6 +2200,7 @@ fn main() -> anyhow::Result<process::ExitCode> {
22002200
builder
22012201
};
22022202

2203+
runtime.thread_stack_size(4 << 20);
22032204
if let Some(blocking_threads) = options.tokio_blocking_threads {
22042205
runtime.max_blocking_threads(blocking_threads);
22052206
}

0 commit comments

Comments
 (0)