pallets: close the deletion holes on-chain - #355
Conversation
e96e305 to
092b0fe
Compare
092b0fe to
e96e305
Compare
e96e305 to
2ed0c90
Compare
2ed0c90 to
e533a0f
Compare
Two holes let deletion reach frozen (append-only-forever) buckets, contradicting the design's 'Frozen = deletions impossible': - checkpoint accepted any commitment with start_seq >= frozen_start_seq, so an admin could prune a frozen bucket's history simply by checkpointing an advanced start_seq. The design pins start_seq for frozen buckets exactly (only leaf_count may grow); the check is now equality. - cleanup_bucket_internal (drive deletion path) had no frozen check at all, so tearing down the whole drive deleted every leaf of a frozen bucket at once. It now refuses with BucketFrozen before any state mutation, which drive-registry surfaces as BucketCleanupFailed.
…cket delete_s3_bucket removed only the S3 registry rows: the underlying Layer 0 bucket, its agreements, and the owner's locked payments all survived, so the S3 purge path reclaimed nothing — the owner kept paying until expiry and the provider was never released. It now mirrors drive deletion: cleanup_bucket_internal ends every agreement with a prorated refund, pays providers for time served, and removes the bucket, before any S3 state is touched. Cleanup errors (frozen bucket, pending challenge) propagate unchanged. S3BucketDeleted gains the refunded amount, and the delete benchmark now sets up a real Layer 0 bucket + agreement so the measured path includes the teardown.
verify_signature previously required the signer to be a registered provider, erroring with ProviderNotFound otherwise — which made the Deleted challenge defense unverifiable: its signer is the bucket admin, a plain account with no registry entry. Unregistered signers now fall back to key-based verification: on AccountId32 runtimes the account's SCALE encoding is its key bytes, and MultiSignature::verify handles every scheme against it. Registered providers keep verifying against their registered key, unchanged.
e533a0f to
fdb249c
Compare
|
/cmd bench --pallet pallet_storage_provider pallet_drive_registry pallet_s3_registry |
|
Command "bench --pallet pallet_storage_provider pallet_drive_registry pallet_s3_registry" has started 🚀 See logs here |
…t_storage_provider pallet_drive_registry pallet_s3_registry'
|
Command "bench --pallet pallet_storage_provider pallet_drive_registry pallet_s3_registry" has finished ✅ See logs here DetailsSubweight results:
Command output:args: Namespace(command='bench', continue_on_fail=False, quiet=False, clean=False, runtime=['web3-storage-paseo', 'storage-parachain-runtime'], pallet=['pallet_storage_provider', 'pallet_drive_registry', 'pallet_s3_registry'], steps=50, repeat=20, profile='production') |
# Conflicts: # crates/pallets/storage-provider/src/impls/signatures.rs # crates/storage-subxt/src/storage_paseo_runtime.rs # runtimes/web3-storage-local/src/weights/pallet_drive_registry.rs # runtimes/web3-storage-local/src/weights/pallet_s3_registry.rs # runtimes/web3-storage-local/src/weights/pallet_storage_provider.rs # runtimes/web3-storage-paseo/src/weights/pallet_drive_registry.rs # runtimes/web3-storage-paseo/src/weights/pallet_s3_registry.rs # runtimes/web3-storage-paseo/src/weights/pallet_storage_provider.rs
|
/cmd bench --pallet pallet_storage_provider pallet_drive_registry pallet_s3_registry |
|
Command "bench --pallet pallet_storage_provider pallet_drive_registry pallet_s3_registry" has started 🚀 See logs here |
…t_storage_provider pallet_drive_registry pallet_s3_registry'
|
Command "bench --pallet pallet_storage_provider pallet_drive_registry pallet_s3_registry" has finished ✅ See logs here DetailsSubweight results:
Command output:args: Namespace(command='bench', continue_on_fail=False, quiet=False, clean=False, runtime=['web3-storage-paseo', 'storage-parachain-runtime'], pallet=['pallet_storage_provider', 'pallet_drive_registry', 'pallet_s3_registry'], steps=50, repeat=20, profile='production') |
Part 3/5 of the deletion-reclaims-capacity stack. Chain-side changes only; compiles and tests standalone.
Frozen means undeletable —
checkpointaccepted anystart_seq >= frozen_start_seq, so an admin could prune a frozen bucket's history by checkpointing an advanced start; the check is now strict equality (onlyleaf_countmay grow).cleanup_bucket_internal(the drive-deletion path) had no frozen check at all and would delete every leaf of a frozen bucket at once; it now refuses withBucketFrozenbefore any mutation, surfaced by drive-registry asBucketCleanupFailed.delete_s3_buckettears down the Layer 0 bucket — previously it removed only the S3 registry rows, so agreements and the owner's locked payments leaked until expiry. It now routes throughcleanup_bucket_internallike drive deletion (prorated refund to the owner, time-served pay to the provider) before touching S3 state;S3BucketDeletedgains therefundedamount (subxt bindings regenerated) and the delete benchmark now measures the real teardown path.Plain-account signature verification —
verify_signaturerequired the signer to be a registered provider, which made theDeletedchallenge defense unverifiable (its signer is the bucket admin, a plain account). Unregistered signers now fall back to key-based verification via the extractedplain_account_verifieshelper, tested with a real sr25519 pair.