Skip to content

Conversation

@HermanObst
Copy link
Contributor

@HermanObst HermanObst commented Oct 31, 2025

Problem:

File deletion from file storage are only being triggered by MutationsApplied event. This is correct for the happy paths as this event is emitted always that an msp accepted the storage request (thus it root was updated in the runtime) and now is not required anymore, either because the user wants to delete it, or the user revoke the SR.

But this leaves us with the edge case where the msp try to accept the SR (thus, it stores the file), but the transaction fails and his root is not updated on-chain. In this case, he will never see MutationsApplied event.

Solution:

Make msp react to events that inform that the SR was incomplete (StorageRequestRejected) but MSP could have sent a tx accepting it that ends up failing.

⚠️ Breaking Changes ⚠️

  • StorageRequestRejected event contains two new fields: msp_id and bucket_id. leaving the new struct as follows:
        StorageRequestRejected {
            file_key: MerkleHash<T>,
            msp_id: ProviderIdFor<T>,
            bucket_id: BucketIdFor<T>,
            reason: RejectedStorageRequestReason,
        },

@HermanObst HermanObst changed the title Storage request rejected triggers file clean up if needed feat(msp): rejected storage request triggers file clean up if needed Oct 31, 2025
@HermanObst HermanObst added B5-clientnoteworthy Changes should be mentioned client-related release notes B7-runtimenoteworthy Changes should be noted in any runtime-upgrade release notes breaking Needs to be mentioned in breaking changes labels Nov 3, 2025
@HermanObst HermanObst added the D2-noauditneeded🙈 PR doesn't need to be audited label Nov 3, 2025
@HermanObst HermanObst marked this pull request as ready for review November 3, 2025 19:23
Comment on lines +248 to +254
if !matches!(
reason,
pallet_file_system::types::RejectedStorageRequestReason::RequestExpired
| pallet_file_system::types::RejectedStorageRequestReason::InternalError
) {
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the storage request failed for any of these reasons, wouldn't we want to delete the file from storage anyways?

ReachedMaximumCapacity
ReceivedInvalidProof
FileKeyAlreadyStored

Comment on lines +166 to +177
let bucket_forest_key = event.bucket_id.as_ref().to_vec();
let read_fs = self
.storage_hub_handler
.forest_storage_handler
.get(&bucket_forest_key.into())
.await
.ok_or_else(|| {
anyhow!(
"CRITICAL❗️❗️ Failed to get forest storage for bucket [{:?}].",
event.bucket_id
)
})?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Buckets can be removed from MSPs in unfinalized blocks. I don't think this needs to be a critical error.

Comment on lines +184 to +190
warn!(
target: LOG_TARGET,
"StorageRequestExpired and finalised for file key {:?} in bucket {:?}, but file key is still in Forest.",
event.file_key,
event.bucket_id
);
return Err(anyhow!("File key is still in Forest"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we consider this case a warning and also return an error?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

B5-clientnoteworthy Changes should be mentioned client-related release notes B7-runtimenoteworthy Changes should be noted in any runtime-upgrade release notes breaking Needs to be mentioned in breaking changes D2-noauditneeded🙈 PR doesn't need to be audited

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants