Skip to content

Commit

Permalink
Return an error if a pending blob is not needed by any pending block. (
Browse files Browse the repository at this point in the history
…#3244)

## Motivation

We currently don't detect if the blob in `HandlePendingBlob` was needed
at all.
(See [this
discussion](#3204 (comment)))

## Proposal

Return an error if no pending block needed it.

## Test Plan

CI should catch regressions.

## Release Plan

- Nothing to do / These changes follow the usual release cycle.

## Links

- Discussion:
#3204 (comment)
- [reviewer
checklist](https://github.com/linera-io/linera-protocol/blob/main/CONTRIBUTING.md#reviewer-checklist)
  • Loading branch information
afck authored Feb 5, 2025
1 parent 280abcb commit b8083c1
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 9 deletions.
14 changes: 8 additions & 6 deletions linera-chain/src/pending_blobs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,16 @@ where
Ok(self.pending_blobs.get(blob_id).await?.flatten())
}

pub async fn maybe_insert(&mut self, blob: &Blob) -> Result<(), ViewError> {
/// Inserts the blob. Returns whether the blob was required by the pending block.
pub async fn maybe_insert(&mut self, blob: &Blob) -> Result<bool, ViewError> {
let blob_id = blob.id();
if let Some(maybe_blob) = self.pending_blobs.get_mut(&blob_id).await? {
if maybe_blob.is_none() {
*maybe_blob = Some(blob.clone());
}
let Some(maybe_blob) = self.pending_blobs.get_mut(&blob_id).await? else {
return Ok(false);
};
if maybe_blob.is_none() {
*maybe_blob = Some(blob.clone());
}
Ok(())
Ok(true)
}

pub async fn update(
Expand Down
6 changes: 4 additions & 2 deletions linera-core/src/chain_worker/state/attempted_changes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,8 @@ where
&mut self,
blob: Blob,
) -> Result<ChainInfoResponse, WorkerError> {
self.state
let mut was_expected = self
.state
.chain
.pending_validated_blobs
.maybe_insert(&blob)
Expand All @@ -650,8 +651,9 @@ where
WorkerError::TooManyPublishedBlobs(policy.maximum_published_blobs)
);
}
pending_blobs.maybe_insert(&blob).await?;
was_expected = was_expected || pending_blobs.maybe_insert(&blob).await?;
}
ensure!(was_expected, WorkerError::UnexpectedBlob);
self.save().await?;
Ok(ChainInfoResponse::new(
&self.state.chain,
Expand Down
6 changes: 5 additions & 1 deletion linera-core/src/unit_tests/client_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1387,9 +1387,13 @@ where
};
{
let node3 = builder.node(3);
let content1 = blob1.into_content();
assert_matches!(node3.handle_pending_blob(chain_id2, content1.clone()).await,
Err(NodeError::WorkerError { error })
if error.contains("Blob was not required by any pending block")
);
let result = node3.handle_validated_certificate(validated.clone()).await;
assert_matches!(result, Err(NodeError::BlobsNotFound(_)));
let content1 = blob1.into_content();
node3.handle_pending_blob(chain_id2, content1).await?;
let response = node3
.handle_validated_certificate(validated.clone())
Expand Down
2 changes: 2 additions & 0 deletions linera-core/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ pub enum WorkerError {
JoinError,
#[error("Blob exceeds size limit")]
BlobTooLarge,
#[error("Blob was not required by any pending block")]
UnexpectedBlob,
#[error("Bytecode exceeds size limit")]
BytecodeTooLarge,
#[error("Number of published blobs per block must not exceed {0}")]
Expand Down

0 comments on commit b8083c1

Please sign in to comment.