Releases: Moonsong-Labs/storage-hub
StorageHub v0.2.7
Summary
StorageHub v0.2.7 is a non‑breaking release that patches an incompatibility between the StorageHub MSP Backend and the DataHaven runtime, so multiaddresses can be correctly SCALE-decoded.
Components
- Client code: v0.2.7
- Pallets code: v0.2.7
- Runtime code: v0.2.7 (spec_name/spec_version: unchanged from v0.2.0)
- SH Backend Docker image: v0.2.7 (image:
ghcr.io/<org>/storage-hub-msp-backend:v0.2.7) - SH SDK (npm): v0.3.3 (
@storagehub-sdk/core,@storagehub-sdk/msp-client) - types-bundle/api-augment (npm):
@storagehub/types-bundlev0.2.8,@storagehub/api-augmentv0.2.13
Changes since last tag
Base: a923d5c
- Highlights:
- Runtime update and backend rebuild: the
MaxMultiAddressSizeof the StorageHub Solochain EVM runtime was changed from 100 to 200 to match DataHaven's configured type. This is because the backend uses this type to SCALE-decode the multiaddresses of the MSP it's connected to, and it was failing as it was trying to decode with a different size.
- Runtime update and backend rebuild: the
- Full diff: a923d5c...9dcf64a
- PRs included:
- #622 fix: 🩹 change
MaxMultiAddressSizeto match DataHaven's
- #622 fix: 🩹 change
Migrations
N/A
⚠️ Breaking Changes ⚠️
- None. All PRs included in v0.2.7 are labelled
not-breakingand do not introduce breaking changes to public APIs, runtime storage layouts, or configuration surfaces.
Runtime
- Constants changed:
- The constant
MaxMultiAddressSizefrom theConfigofpallet-storage-providerswas changed in the solochain EVM runtime fromConstU32<100>toConstU32<200>to match DataHaven's config.
- The constant
Backend
- Compilation changes:
- The new version of the backend was compiled with the aforementioned new runtime constant, which makes the new backend functionally identical to the previous version but with the ability to correctly encode and decode DataHaven's multiaddresses.
Versions
- Polkadot SDK: polkadot-stable2412-6
- Rust: 1.90 (from
rust-toolchain.toml)
Compatibility
- SH Backend v0.2.7 → compatible with pallets/runtime v0.2.7 and client v0.2.7 (all built from this release).
- SDK v0.3.3 → compatible with backend v0.2.7, client v0.2.7, and pallets/runtime v0.2.7.
Upgrade Guide
None. Upgrading from the previous release should be seamless. All PRs included in this release are labelled not-breaking and do not introduce breaking changes to public APIs, runtime storage layouts, or configuration surfaces.
StorageHub v0.2.6
Summary
StorageHub v0.2.6 is a non‑breaking maintenance release focused on indexer correctness, bucket and deletion flows, runtime event semantics, and backend observability via the now correctly implemented /stats endpoint. It also includes improvements to BSP stop‑storing incentives, fixes around fisherman batching and file‑record step handling, and an update to the Rust 1.90 toolchain.
Components
- Client code: v0.2.6
- Pallets code: v0.2.6
- Runtime code: v0.2.6 (spec_name/spec_version: unchanged from v0.2.0)
- SH Backend Docker image: v0.2.6 (image:
ghcr.io/<org>/storage-hub-msp-backend:v0.2.6) - SH SDK (npm): v0.3.3 (
@storagehub-sdk/core,@storagehub-sdk/msp-client) - types-bundle/api-augment (npm):
@storagehub/types-bundlev0.2.7,@storagehub/api-augmentv0.2.10
Changes since last tag
Base: 24f4489
- Highlights:
- Backend observability: correctly implemented
/statsendpoint in the backend reads on‑chain storage from the configured provider and returns actual provider/runtime values, backed by reusable helpers for runtime API calls and storage queries (#567). - Move bucket flow robustness: indexer handling of
MoveBucketAcceptednow consistently updates MSP–file associations so that all files in a bucket are re‑associated to the new MSP, and avoids creating associations for files that have already been deleted from the bucket (#601). - BSP stop‑storing incentives: the BSP stop‑storing flow now updates the payment stream when the BSP requests to stop storing (not only when confirming), and prevents requests while there is an
IncompleteStorageRequest, reducing state bloat and better incentivising timely confirmations (#602). - Indexer correctness: fixes around
is_in_bucket, handling of insolvent‑user stop‑storing events, andIncompleteStorageRequest/ deletion interactions make the indexer’s view of files, buckets, and storage requests more reliable and easier to reason about (#603, #610). - Fisherman batching: fisherman deletion now deduplicates file keys before batching extrinsics and only updates the latest file record’s storage‑request step, preventing failed deletion batches and preserving accurate per‑request history (#610).
- Runtime events and forests:
MutationsAppliedandMutationsAppliedForProvidernow emit mutations with their values for both add and trie‑remove cases, allowing providers to correctly rebuild forests on reorgs and other rollbacks (#613). - BSP stop‑storing documentation and safety: documentation of the BSP stop‑storing flow has been expanded, and runtime logic tightened around
IncompleteStorageRequestinteractions (#602). - Tooling and infra: Rust toolchain bumped to 1.90 with associated warning fixes, e2e tests temporarily pinned MetaMask to 12.23.1 to work around a dappwright bug, and then moved back to using dappwright’s recommended MetaMask version once the upstream issue was fixed (#608, #609, #612).
- Backend observability: correctly implemented
- Full diff: 24f4489...a923d5c
- PRs included:
- #567 feat(backend): /stats endpoint
- #601 feat: 🎨 move bucket flow improvements
- #602 feat: 🎨 BSP stop storing improvements
- #603 fix: 🐛 general indexer improvements
- #608 build: ⬆️ Upgrade to Rust 1.90 and fix warnings
- #609 fix(e2e): use MetaMask 12.23.1 for dappwright compatibility
- #610 fix: 🐛 file record deduplication on deletion
- #612 revert: ⏪ revert back to using metamask recommended version from dappwright
- #613 fix: 🐛 correctly emit mutations in events
Migrations
RocksDB (File Storage)
- Changes:
- No new schema changes in this release.
- Action required:
- None for fresh deployments or chains already using the v0.2.x RocksDB schema.
RocksDB (Forest Storage)
- Changes:
- No new schema changes.
- Action required:
- None.
RocksDB (State store)
- Changes:
- No changes that require an explicit migration.
- Action required:
- None.
Indexer DB (Postgres)
- Migrations:
- No new SQL migrations are introduced in this release; existing migrations from previous v0.2.x releases continue to apply as before.
- How to apply:
- The indexer service runs migrations automatically on startup. Alternatively run
diesel migration runin the indexer DB crate.
- The indexer service runs migrations automatically on startup. Alternatively run
Pending extrinsics DB (Postgres)
- Migrations:
- No new migrations; the schema introduced in v0.2.0 remains unchanged.
- How to apply:
- The Blockchain Service runs migrations automatically on startup. Alternatively run
diesel migration runwhere applicable.
- The Blockchain Service runs migrations automatically on startup. Alternatively run
⚠️ Breaking Changes ⚠️
- None. All PRs included in v0.2.6 are labelled
not-breakingand do not introduce breaking changes to public APIs, runtime storage layouts, or configuration surfaces.
Runtime
- Upgrades (spec_version):
- Runtime code remains on the same spec_version as v0.2.0; this release focuses on behavioural fixes and incentives rather than runtime storage migrations.
- Migrations:
- No runtime storage migrations detected for this release.
- Behaviour changes:
- BSP stop‑storing flow: the BSP stop‑storing extrinsics now adjust the payment stream at request time, ensuring BSPs that have requested to stop storing are no longer over‑paid and are better incentivised to complete the flow by confirming (#602).
- Safety around
IncompleteStorageRequest: BSPs are prevented from requesting to stop storing a file while there is an openIncompleteStorageRequest, ensuring that the fisherman‑driven clean‑up path remains the authoritative mechanism for incomplete storage flows (#602). - Event semantics for mutations:
MutationsAppliedandMutationsAppliedForProvidernow emit trie‑remove mutations with their associated values, so providers can replay and revert mutations with full information, particularly during reorg handling (#613).
- Constants changed:
- No operator‑visible constant changes requiring configuration updates.
- Scripts to run:
- None specific to this release beyond existing deployment and indexer/bootstrap scripts.
Client
- Behaviour changes:
- Move bucket flow: when a bucket is moved to a new MSP, the indexer now:
- Deletes all MSP–file associations for the previous MSP and files in the bucket (if there was a previous MSP).
- Creates new MSP–file associations between the new MSP and all files currently in the bucket, ensuring the index reflects the effective storage topology (#601).
- Stop‑storing and insolvency handling: indexer handling of
MspStopStoringBucketInsolventUserandSpStopStoringInsolventUsernow:- Correctly sets
is_in_bucket = falsefor all affected files. - Cleans up bucket records when there are no remaining associations, reducing stale rows and improving consistency (#603).
- Correctly sets
- Incomplete storage and deletion interactions: fixes ensure that:
IncompleteStorageRequestevents no longer overwrite the signed delete intention for a file key if aFileDeletionRequestedevent was already seen.- Clean‑up of removed buckets/BSPs from
IncompleteStorageRequestMetadatais correctly applied when the fisherman deletes file keys (#603).
- Fisherman deletion batching: the fisherman now:
- Deduplicates file keys when building deletion batches, preventing extrinsics from failing due to duplicated keys.
- Updates the storage‑request
Steponly for the latest file record of a file key, preserving an accurate history of earlier storage requests (#610).
- General indexer robustness: additional clarifications in indexer code comments and more verbose error messages make it easier to debug indexing issues in production (#603).
- Move bucket flow: when a bucket is moved to a new MSP, the indexer now:
- Initialisation changes:
- No new CLI flags or configuration fields are introduced for client services in this release.
- Operators should ensure that indexer and fisherman binaries are upgraded together to benefit from the corrected deletion and bucket‑movement semantics.
Backend
- Behaviour changes:
- Correctly implemented
/statsendpoint:- Backend now exposes a
/statsendpoint that queries the configured provider and reads chain storage directly to return real on‑chain statistics, rather than derived or stubbed values (#567). - The change introduces general‑purpose helpers for runtime API calls and storage reads, replacing an earlier custom RPC method for the payment stream price per giga unit.
- Backend now exposes a
- Runtime‑aware backend:
- Backend now depends explicitly on the runtime crate for type definitions and storage key encoding, rather than using dynamic decoding via subxt, aligning types more tightly with the deployed runtime (#567).
- A previous experimental subxt‑based approach is retained in Git history but not shipped in this release.
- Correctly implemented
- Initialisation changes:
- No new backend configuration fields are required;
/statsuses the existing provider and runtime configuration. - Ensure backend deployments are rebuilt against the updated runtime dependency set so the
/statsendpoint has access to the correct types.
- No new backend configuration fields are required;
SDK
- Behaviour changes:
- No changes to SDK API surface or configuration.
- Initialisation changes:
- No changes to SDK configuration or initialisation.
Versions
- Polkadot SDK: polkadot-stable2412-6
- Rust: 1.90 (from
rust-toolchain.toml)
Compatibility
- SH Backend v0.2.6 → compatible with pallets/runtime v0.2.6 and client v0.2.6 (all built from this release).
- SDK v0.3.3 → compatible with backend v0.2.6, client v0.2.6, and pallets/runtime v0.2.6.
Upgrade Guide
None. Upgrading from the previous release should be seamless. All PRs...
StorageHub v0.2.5
Summary
StorageHub v0.2.4 includes a hotfix for how the indexer handles the MspAcceptedStorageRequest. Previously it would query the bucket of the accepted storage request by its database ID, not its onchain bucket ID (what it now does).
Components
- Client code: v0.2.4
- Pallets code: v0.2.4
- Runtime code: v0.2.4 (spec_name/spec_version: parachain 1, solochain-evm 1)
- SH Backend Docker image: v0.2.4 (image: ghcr.io/<org>/storage-hub-msp-backend:v0.2.3)
- SH SDK (npm): v0.3.4 (
@storagehub-sdk/core,@storagehub-sdk/msp-client) - types-bundle/api-augment (npm):
@storagehub/types-bundlev0.2.8,@storagehub/api-augmentv0.2.11
Changes since last tag
Base: 0a076dc57f1cf6a6ecb55f12b8b452581ed14489
- Highlights:
- Fix critical issue with indexer: The bucket ID was being queried by its PostgresDB internal database ID, not the on-chain bucket ID. This has now been changed to being queried by the on-chain bucket ID, and the utility function to query by database ID has been removed to prevent this kind of issue again. There were no other uses of this utility function.
- Add verbose failure logs to indexer: Now indexer failures log the block number and event they were indexing when the error happens.
- Full diff: 0a076dc...24f4489
- PRs included:
Client/Indexer
- Behaviour changes:
- Fix critical issue with indexer: The bucket ID was being queried by its PostgresDB internal database ID, not the on-chain bucket ID. This has now been changed to being queried by the on-chain bucket ID, and the utility function to query by database ID has been removed to prevent this kind of issue again. There were no other uses of this utility function.
- Add verbose failure logs to indexer: Now indexer failures log the block number and event they were indexing when the error happens.
Versions
- Polkadot SDK: polkadot-stable2412-6
- Rust: 1.87 (from rust-toolchain.toml)
Compatibility
- SH Backend v0.2.4 → compatible with pallets/runtime v0.2.4 and client v0.2.4 (all built from this release).
- SDK v0.3.4 → compatible with backend v0.2.4, client v0.2.4, and pallets/runtime v0.2.4.
Upgrade Guide
Just bumping the patch version.
StorageHub v0.2.4
Summary
StorageHub v0.2.4 includes a hotfix for how the indexer handles the is_in_bucket field of files, which is the field used by both the fisherman and the indexer service to check if a file is being stored in a bucket currently. Previously, new storage requests defaulted to false for this field, but since storage requests can be created for files that are already stored in a bucket, what we do now is check if the file is in a bucket and set is_in_bucket appropiately.
Components
- Client code: v0.2.4
- Pallets code: v0.2.4
- Runtime code: v0.2.4 (spec_name/spec_version: parachain 1, solochain-evm 1)
- SH Backend Docker image: v0.2.4 (image: ghcr.io/<org>/storage-hub-msp-backend:v0.2.3)
- SH SDK (npm): v0.3.4 (
@storagehub-sdk/core,@storagehub-sdk/msp-client) - types-bundle/api-augment (npm):
@storagehub/types-bundlev0.2.8,@storagehub/api-augmentv0.2.11
Changes since last tag
Base: 527f303055e6ac136db4d6ca373ecc8fd6feeec6
- Highlights:
- Fix critical issue with indexer: the indexer will now appropiately populate the
is_in_bucketfield for new file records created, avoiding inconsistencies and possible issues during deletion.
- Fix critical issue with indexer: the indexer will now appropiately populate the
- Full diff: 527f303...0a076dc
- PRs included:
- fix: 🚑 make it so
is_in_bucketis consistent across same file key records (#598)
- fix: 🚑 make it so
⚠️ Breaking Changes ⚠️
- #598: There's a new migration to run that makes existing
is_in_bucketfields consistent across file records for identical file keys.
Client/Indexer
- Behaviour changes:
- Keep
is_in_bucketfield consistent across a file key: The indexer now correctly sets the initialis_in_bucketstatus for a new file record when creating it. Updates to that field are done across a file key and not for one specific file record.
- Keep
Versions
- Polkadot SDK: polkadot-stable2412-6
- Rust: 1.87 (from rust-toolchain.toml)
Compatibility
- SH Backend v0.2.4 → compatible with pallets/runtime v0.2.4 and client v0.2.4 (all built from this release).
- SDK v0.3.4 → compatible with backend v0.2.4, client v0.2.4, and pallets/runtime v0.2.4.
Upgrade Guide
- #598 – running the new indexer DB migration:
There's a new migration for the indexer DB that must be executed for all existing DBs.
-
Who is affected
- Indexer node runners since they'll have to run the new migration
-
Changes required
-
Indexer DB: If you are running an indexer, you must run the new migration over your existing indexer DB.
-
Suggested code changes: None.
-
StorageHub v0.2.3
Summary
StorageHub v0.2.3 includes a hotfix for how the indexer handles the deletion of files, preventing it if the file to delete currently has an open storage request on-chain. It also includes extra safeguards in the whole deletion process to avoid inconsistent or erroneous states, such as a BSP confirming to store a file that a fisherman has already deleted.
Components
- Client code: v0.2.3
- Pallets code: v0.2.3
- Runtime code: v0.2.3 (spec_name/spec_version: parachain 1, solochain-evm 1)
- SH Backend Docker image: v0.2.3 (image: ghcr.io/<org>/storage-hub-msp-backend:v0.2.3)
- SH SDK (npm): v0.3.4 (
@storagehub-sdk/core,@storagehub-sdk/msp-client) - types-bundle/api-augment (npm):
@storagehub/types-bundlev0.2.8,@storagehub/api-augmentv0.2.11
Changes since last tag
Base: 5e53d4c3e6b6d9524968c9149f9542a99ca0e72d
- Highlights:
- Fix critical issue with indexer: the indexer will no longer delete files from its DB that currently have an open storage request on-chain. This avoid an issue where the indexer would get stuck if a BSP confirm or MSP accept came for a on-chain storage request for a file key that a fisherman has already finished up deleting.
- Extra safeguards in the runtime: The runtime now also protects against this sort of inconsistencies, by requiring specific conditions in order to issue a new storage request or request the deletion of a file.
- Full diff: 5e53d4c...527f303
- PRs included:
- fix: 🚑 indexer handling of file deletion (#596)
⚠️ Breaking Changes ⚠️
- #596: The indexer DB has two new possible Steps that a file can be in: revoked and rejected. The backend (which interacts with the indexer DB) was updated to handle the two new steps in its FileStatus model, and the SDK as well since it receives a FileStatus from the backend.
Client/Indexer
- Behaviour changes:
- Graceful recovery for missing file records: The indexer no longer crashes if it doesn't find a file record during
BspConfirmedStoringorMspAcceptedStorageRequestevents. Instead, it recreates the file record from the event metadata. This is a recovery mechanism for edge cases where a file was deleted from the DB but a storage request was still present on-chain. - Protect files with active storage requests from deletion: The indexer will no longer delete file records that have an active storage request (
step = Requestedand no deletion status). This prevents race conditions where deletion events arrive before confirmation events, avoiding situations where the indexer would get stuck. - New file storage request steps: Added two new
FileStorageRequestStepvalues:Revoked(step 3) andRejected(step 4). Files are now marked with these steps when handlingStorageRequestRevokedandMspRejectedStorageRequestevents respectively, before attempting orphan cleanup.
- Graceful recovery for missing file records: The indexer no longer crashes if it doesn't find a file record during
Runtime
- Block new storage requests for files being cleaned up: A new storage request cannot be issued if there's an existing
IncompleteStorageRequestin storage for that file key. Users must wait until the fisherman finishes cleaning up the previous storage request before issuing a new one. - Block file deletion when storage request is active: Users cannot request a file deletion if there's either an open storage request for that file key or an
IncompleteStorageRequestexists for it. For the former, users should callrevoke_storage_requestinstead, for the latter they should wait until the fisherman finishes cleaning up the previous storage request. - Handle open storage requests during deletion: If a storage request is open for a file key that the fisherman is deleting, the runtime now issues an
IncompleteStorageRequestfor it and cleans it up properly.
Backend
- New
FileStatusvalues: Updated theFileStatusenum in theFileInfomodel to include two new statuses:Revoked(when user explicitly revoked a storage request) andRejected(when MSP rejected a storage request).
SDK
- Updated
FileStatustype: TheFileStatustype in @storagehub-sdk/msp-client now includes "revoked" and "rejected" as possible values, in addition to "inProgress", "ready", "expired", and "deletionInProgress".
Versions
- Polkadot SDK: polkadot-stable2412-6
- Rust: 1.87 (from rust-toolchain.toml)
Compatibility
- SH Backend v0.2.3 → compatible with pallets/runtime v0.2.3 and client v0.2.3 (all built from this release).
- SDK v0.3.4 → compatible with backend v0.2.3, client v0.2.3, and pallets/runtime v0.2.3.
Upgrade Guide
- #596 – handling the two new
FileStatusthat a file can be in:
The indexer DB has two new possible Steps that a file can be in: revoked and rejected. The backend (which interacts with the indexer DB) was updated to handle the two new steps in its FileStatus model, and the SDK as well since it receives a FileStatus from the backend.
-
Who is affected
- Backend API consumers calling
/buckets/{bucket_id}/info/{file_key}since they now have two extraFileStatusto handle. - SDK users calling
MspClient.files.getFileInfo(bucketId, fileKey)orMspClient.buckets.getFiles(bucketId, options?), since the files returned by these methods have these two new statuses to handle.
- Backend API consumers calling
-
Changes required
-
Backend API: If you have any logic that depends on the
FileStatusreturned when calling/buckets/{bucket_id}/info/{file_key}, handle the two new statuses. -
SDK - MspClient: Any logic that uses the
getFileInfoandgetFilesendpoints should handle the two new statuses. -
Suggested code changes: See PR description for instructions and code snippets.
-
StorageHub v0.2.2
Summary
StorageHub v0.2.2 includes a hotfix for how the indexer handles the fact that there can be multiple entries in the Indexer DB for the same file_key, which happens when there are multiple storage requests for that file_key over time. For instance, when a user wants to increase redundancy.
Components
- Client code: v0.2.0
- Pallets code: v0.2.0
- Runtime code: v0.2.0 (spec_name/spec_version: parachain 1, solochain-evm 1)
- SH Backend Docker image: v0.2.1 (image: ghcr.io/<org>/storage-hub-msp-backend:v0.2.1)
- SH SDK (npm): v0.3.3 (
@storagehub-sdk/core,@storagehub-sdk/msp-client) - types-bundle/api-augment (npm):
@storagehub/types-bundlev0.2.7,@storagehub/api-augmentv0.2.10
Changes since last tag
Base: 25e8dbbc679b46fc7c955ee5a2707dfcaab1ca2b
- Highlights:
- Fix indexer handling multiple file records: The indexer now properly handles the fact that there can be multiple file records in the DB for the same
file_key, which happens when there are multiple storage requests for thatfile_keyover time. For instance, when a user wants to increase redundancy. - Additional success/failure logs in tasks and RPCs: Now all tasks and RPCs log both on failure and successful execution.
- Fix indexer handling multiple file records: The indexer now properly handles the fact that there can be multiple file records in the DB for the same
- Full diff: 25e8dbb...5e53d4c
- PRs included:
⚠️ Breaking Changes ⚠️
No breaking changes.
Client
- Behaviour changes:
- Fix indexer handling multiple file records: The indexer now properly handles the fact that there can be multiple file records in the DB for the same
file_key, which happens when there are multiple storage requests for thatfile_keyover time. For instance, when a user wants to increase redundancy. - Additional success/failure logs in tasks and RPCs: Now all tasks and RPCs log both on failure and successful execution.
- Fix indexer handling multiple file records: The indexer now properly handles the fact that there can be multiple file records in the DB for the same
Versions
- Polkadot SDK: polkadot-stable2412-6
- Rust: 1.87 (from rust-toolchain.toml)
Compatibility
- SH Backend v0.2.0 → compatible with pallets/runtime v0.2.0 and client v0.2.0 (all built from this release).
- SDK v0.3.3 → compatible with backend v0.2.0, client v0.2.0, and pallets/runtime v0.2.0.
Upgrade Guide
From v0.2.1, just a version bump is required, nothing more.
StorageHub v0.2.1
Summary
StorageHub v0.2.0 focuses on scalability and resilience of MSP/BSP operations, better observability and indexing of storage requests, and SDK and backend improvements around authentication, file upload, and client UX. This includes support for multiple MSP/BSP instances (leader role), more robust handling of storage request lifecycles, a new Blockchain Service Postgres store for pending extrinsics, and SDK performance improvements for large files.
Components
- Client code: v0.2.0
- Pallets code: v0.2.0
- Runtime code: v0.2.0 (spec_name/spec_version: parachain 1, solochain-evm 1)
- SH Backend Docker image: v0.2.1 (image: ghcr.io/<org>/storage-hub-msp-backend:v0.2.1)
- SH SDK (npm): v0.3.3 (
@storagehub-sdk/core,@storagehub-sdk/msp-client) - types-bundle/api-augment (npm):
@storagehub/types-bundlev0.2.7,@storagehub/api-augmentv0.2.10
Changes since last tag
Base: d9a283293a2612a1a567ab5b6848e84e4ea0a858
- Highlights:
- Fix account nonce query at startup:
account_noncefrom the Blockchain Service now doesn't panic if querying a block that no longer exists, just warns. - Feature gate parachain in shc-common: Feature gate parachain-related crates in
shc-commonreducing significantly build times for solochain nodes.
- Fix account nonce query at startup:
- Full diff: d9a2832...25e8dbb
- PRs included:
⚠️ Breaking Changes ⚠️
- #581: Changed the
ParachainClienttype toStorageHubClient, which now conditionally includes parachain host functions or regular substrate host functions, depending on theparachainfeature flag.
Client
- Behaviour changes:
- Fix account nonce query at startup:
account_noncefrom the Blockchain Service now doesn't panic if querying a block that no longer exists, just warns. Instead of panicking, it returns aResult, whose errors are properly logged and handled. - Avoid pending db cleanup in Standalone: when running in standalone mode (no multiple instances of MSP/BSP) cleanup of the DB is ignored (as there is no DB).
- Fix account nonce query at startup:
Versions
- Polkadot SDK: polkadot-stable2412-6
- Rust: 1.87 (from rust-toolchain.toml)
Compatibility
- SH Backend v0.2.0 → compatible with pallets/runtime v0.2.0 and client v0.2.0 (all built from this release).
- SDK v0.3.3 → compatible with backend v0.2.0, client v0.2.0, and pallets/runtime v0.2.0.
Upgrade Guide
-
#581 – changing
ParachainClientforStorageHubClient:-
The
ParachainClienttype alias in the StorageHub client has been replaced byStorageHubClient, and Cumulus parachain host functions (cumulus-client-serviceand related crates) are now behind an optionalparachainCargo feature inshc-commoninstead of being required unconditionally. -
Who is affected
- Substrate projects using the StorageHub client crates (for example
shc-common,shc-blockchain-service,shc-indexer-service,shc-fisherman-service,shc-rpc, or the top-level StorageHub client builder) that:- Refer directly to the
ParachainClienttype alias, or - Rely on Cumulus (
cumulus-client-service,cumulus-primitives-*) being pulled in transitively without enabling any feature flags.
- Refer directly to the
- Substrate projects using the StorageHub client crates (for example
-
Suggested code changes
See PR description for instructions and code snippets.
-
StorageHub v0.2.0
Summary
StorageHub v0.2.0 focuses on scalability and resilience of MSP/BSP operations, better observability and indexing of storage requests, and SDK and backend improvements around authentication, file upload, and client UX. This includes support for multiple MSP/BSP instances (leader role), more robust handling of storage request lifecycles, a new Blockchain Service Postgres store for pending extrinsics, and SDK performance improvements for large files.
Components
- Client code: v0.2.0
- Pallets code: v0.2.0
- Runtime code: v0.2.0 (spec_name/spec_version: parachain 1, solochain-evm 1)
- SH Backend Docker image: v0.2.0 (image: ghcr.io/<org>/storage-hub-msp-backend:v0.2.0)
- SH SDK (npm): v0.3.3 (
@storagehub-sdk/core,@storagehub-sdk/msp-client) - types-bundle/api-augment (npm):
@storagehub/types-bundlev0.2.7,@storagehub/api-augmentv0.2.10
Changes since last tag
Base: release/v0.1 (b7e6082c0bf88579c3979a54542628ba1cc1e214)
- Highlights:
- Indexing & observability: indexer now stores transaction hash and block hash for each new storage request, improving traceability from the chain to the database (#580).
- Indexer API:
getFilesresponses now include anuploaded_attimestamp, making it easier to reason about file lifecycles (#576). - Multiple MSP/BSP instances (leader role): initial implementation of support for running multiple MSP/BSP instances, including leader election logic for storage request handling (#577). Follower logic is not yet implemented.
- MSP file handling: when the MSP Backend sends a file to the MSP Node, it now streams chunks from disk instead of loading whole files into memory, significantly reducing peak memory usage on large uploads (#572).
- MSP robustness: rejected storage requests now trigger file clean‑up where needed, MSP uses a retry strategy for storage request responses, and the MSP upload code has been refactored to avoid holding the file storage write lock, risking deadlocks (#547, #558, #582).
- Fisherman: fisherman node can batch file deletions, improving deletion throughput (#531).
- Blockchain Service DB: SH Client's Blockchain Service now persists pending extrinsics in a dedicated Postgres DB, improving resilience across restarts and better tracking of in‑flight transactions (#563). Has to be enabled through the
pending_db_urlconfiguration option, either via the CLI or configuration file. - Transactions “implicit” construction:
implicitdata in transactions is now built dynamically via a runtime API, allowing a client to work with a runtime build different from the one it was compiled against (#557). - SDK: improved ergonomics (for example optional
call_scale) and faster fingerprinting for large files, alongside general SDK clean‑ups and version bumps (#551, #554, #569, #574). - Backend auth: backend now supports optional authentication, refactored auth expiry handling, and SIWE‑related fixes (URL/domain config and retry of verification), plus various clean‑ups (#544, #550, #552, #579).
- Backend correctness: validate uploads against the bucket owner (not the file owner), avoid concurrent uploads for the same file key, and fill in missing
backend_config.tomlfields; improve logging and remove unnecessary peer‑id lookups in upload paths (#517, #568, #570, #573, #555, #586). - Tooling & examples: new demo app, improved local scripts (including adding fisherman node), and benchmarks for file deletion extrinsics to guide performance tuning (#516, #556, #560).
- Full diff:
https://github.com/Moonsong-Labs/storage-hub/compare/b7e6082c0bf88579c3979a54542628ba1cc1e214...d9a283293a2612a1a567ab5b6848e84e4ea0a858 - PRs included:
- #588 docs: 📝 Add missing parameters to config files
- #587 fix: 🐛 update column order of migration in indexer DB to match schema and code
- #586 fix(backend): 🐛 avoid concurrent uploads for the same file key
- #582 fix: 🚑 avoid deadlocks during the MSP upload process
- #580 feat: ✨ add tx hash for each new storage request in the indexer
- #579 fix: SIWE config URL and domain
- #576 feat: Add
uploaded_atfield to getFiles response - #577 feat: 🚧 Add multiple MSP/BSP instances support - Leader role implementation only
- #575 feat(test): Add flag to initialise MSP with arbitrary size files
- #572 feat(msp): stream chunks instead of full load in memory in save_file_to_disk
- #574 feat: ✨ Make
call_scaleoptional - #563 feat(client): ✨ Persist pending extrinsics in new Blockchain Service Postgres DB
- #573 refactor(backend): do not get peer id in upload file
- #570 fix(backend): 🐛 validate file upload against bucket owner instead of file owner
- #560 benchmark: file deletion extrinsics
- #547 feat(msp): rejected storage request triggers file clean up if needed
- #531 feat(fisherman): 🌎 batch file deletions
- #569 chore: 🔖 bump SDK packages version
- #568 fix: 📝 add missing fields to the
backend_config.tomlfile - #566 chore: 🔖 bump backend version after major changes
- #562 fix: 🐛 remove either leading or trailing comma, not both
- #557 feat: ✨ Build
implicitin transactions dynamically using a runtime API - #558 feat: 🔊 make the MSP use a retry strategy for its storage request responses
- #516 Demo app
- #556 feat: ✨ Add fisherman node to script
- #555 chore: 🔊 update logs for MSP distributing
- #553 fix: 🐛 BSP volunteering issues
- #552 Retry verify on SIWE
- #544 feat(backend): optional auth
- #550 Refactor/auth expiry
Migrations
RocksDB (File Storage)
- Changes:
- No new schema changes.
- Action required:
- None for fresh deployments or chains already migrated to the v0.1.x RocksDB schema.
RocksDB (Forest Storage)
- Changes:
- No new schema changes.
- Action required:
- None.
RocksDB (State store)
- Changes:
- None that require migration.
- Action required:
- None.
Indexer DB (Postgres)
- Migrations:
- Includes
2025-11-27-182418_add_tx_hash_and_block_hash_to_file; its column order was updated in PR #587 before any release shipped, so this release only contains the corrected version.
- Includes
- How to apply: The indexer service runs migrations automatically on startup. Alternatively run
diesel migration run.
Pending extrinsics DB (Postgres)
- Migrations:
- Freshly introduced. No migrations required as it didn't exist before this release.
- How to apply: The Blockchain Service runs migrations automatically on startup. Alternatively run
diesel migration run.
⚠️ Breaking Changes ⚠️
- PR #517: backend configuration and HTTP API changes (new auth/expiry/callback/retry config fields; authenticated upload/download; alloy
Addressfor addresses; file list response now rooted at a singletreefield;/distributeendpoint removed; bucket table extended with value-proposition and size/count columns). - PR #557: transaction
implicitdata is now built dynamically via a runtime API; clients that manually constructedimplicitpayloads must align with the new API. - PR #531: fisherman now batches file deletions; any tooling assuming one-by-one deletion semantics should be reviewed.
- PR #547: MSP performs clean-up of on-disk file data when storage requests are rejected, altering behaviour for incomplete or failed storage flows.
- PR #563: new Postgres database for pending extrinsics in the Blockchain Service, controlled via
pending_db_url, changes how in-flight extrinsics are persisted across restarts. - PR #554:
@storagehub-sdk/coreand@storagehub-sdk/msp-clientv0.3.3 introduce SDK API/typing adjustments that may require client code changes. - PR #572: MSP file handling now streams chunks from disk instead of loading full files into memory, which can change performance characteristics and any extensions hooking into the old path.
- PR #577: groundwork for multiple MSP/BSP instances with a leader role; multi-instance deployments must follow the new leader configuration model.
- PR #576:
getFilesresponse and related indexer models now include anuploaded_attimestamp; clients parsing file metadata must handle the new field. - PR #579: SIWE configuration URL and domain have been corrected; deployments must update their SIWE settings to match.
- PR #580: indexer now records a
tx_hash(and associatedblock_hash) per new storage request; any direct consumers of the indexer DB must account for these columns. - PR #586: backend config TOML gains a new
file_transfersection withmax_upload_sessionsandmax_download_sessions, which operators must add to their config. - PR #587: column order in migration
2025-11-27-182418_add_tx_hash_and_block_hash_to_filewas updated to match schema and code; no extra operator action is required beyond running migrations for this release.
Runtime
- Upgrades (spec_version): parachain and solochain-evm remain at spec_version 1.
- Migrations: No runtime storage...
StorageHub v0.1.5
StorageHub v0.1.5
Summary
StorageHub patch that fixes an issue with the backend when uploading freshly-requested files.
Components
- Client code: v0.1.0
- Pallets code: v0.1.0
- Runtime code: v0.1.0 (spec_name/spec_version: parachain 1, solochain-evm 1)
- SH Backend Docker image: v0.1.1 (image: ghcr.io/Moonsong-Labs/storage-hub-msp-backend:v0.1.5)
- SH SDK (npm): v0.3.2
- types-bundle: v0.2.7
- api-augment: v0.2.9
Changes since last tag
Base commit: 18a562a
- Highlights:
- Full diff: 18a562a...b7e6082
Runtime
- Upgrades (spec_version): parachain and solochain-evm remain at spec_version 1.
- Migrations: No runtime storage migrations detected.
- Constants changed: None requiring operator action.
- Scripts to run: None.
Client
- Behaviour changes: None
Backend
- Behaviour changes:
- Previously, when uploading a new file, the backend checked if the user had permissions to do so by getting the file information from the indexer's DB to check if the user is the owner of said file. This had an issue where recently issued storage requests that weren't finalised yet are not present in the indexer DB, which meant the query failed and the backend returned an error and did not proceed with the upload.
- With the new logic, the backend checks if the user has permissions to upload a file by checking if it's the owner of the bucket where the file is being uploaded to. This still has the same issue when the bucket was created recently and the extrinsic doing so was not finalised yet, but this is a good-enough solution until we implement way of directly checking this on-chain.
Versions
- Polkadot SDK: polkadot-stable2412-6
- Rust: 1.87 (from rust-toolchain.toml)
Compatibility
- SH Backend v0.1.1 → compatible with pallets/runtime v0.1.0 and client v0.1.0.
- SDK v0.3.2 → compatible with backend v0.1.1, client v0.1.0, and pallets/runtime v0.1.0.
StorageHub v0.1.4
StorageHub v0.1.4
Summary
Minor release of StorageHub focusing on backend fixes and minor client changes.
Components
- Client code: v0.1.0
- Pallets code: v0.1.0
- Runtime code: v0.1.0 (spec_name/spec_version: parachain 1, solochain-evm 1)
- SH Backend Docker image: v0.1.5 (image: ghcr.io/Moonsong-Labs/storage-hub-msp-backend:v0.1.5)
- SH SDK (npm): v0.3.2
- types-bundle: v0.2.7
- api-augment: v0.2.9
Changes since last tag
Base commit: e3bf4fc
- Highlights:
- refactor(backend): auth expiry (#550)
- feat(backend): optional auth (#544)
- feat(sdk): retry verify on SIWE (#552)
- fix(backend): cleanups part 1 (#517)
- feat(scripts): add fisherman node to solochain evm bootstrap script (#556)
- feat(sdk): demo app (#516)
- feat(client): Build implicit in transactions dynamically using a runtime API (#557)
- fix(backend): remove either leading or trailing comma in backend logs, not both (#562)
- chore(backend): bump backend version after major changes (#566)
- fix(backend): add missing fields to the
backend_config.tomlfile (#568)
- Full diff: e3bf4fc...18a562a
Migrations
Indexer DB (Postgres)
- Migrations added:
- 2025-10-09-161554_add_bucket_value_prop_size_count
- How to apply: The indexer service runs migrations automatically on startup. Alternatively run
diesel migration run.
Runtime
- Upgrades (spec_version): parachain and solochain-evm remain at spec_version 1.
- Migrations: No runtime storage migrations detected.
- Constants changed: None requiring operator action.
- Scripts to run: None.
Client
- Behaviour changes:
- Extrinsic building in the Blockchain Service now gets the signed extra implicit data from the extensions themselves through a runtime API instead of being hardcoded. Implement the runtime API as explained in feat(client): Build implicit in transactions dynamically using a runtime API (#557)
Backend
- Behaviour changes:
- Refactored auth expiration to have better debug logging.
- Made authorization optional and made the
/downloadendpoint not require auth. - Added pagination query parameters to
/filesand/bucketsendpoints.- The pagination parameters are optional and are:
limit(the number of items to reply with) andpage(which 'page' the endpoint should return).
- The pagination parameters are optional and are:
- Made it so the FileList response (obtained from the
/buckets/{bucket_id}/filesendpoint) now has a single tree field at the root and folder items do not have a children field. - Removed the
/distributeendpoint as the backend is not in charge of this anymore. - Fixes a bug with the logs which should now have proper JSON formatting.
- Config changes:
- Added a
msparray of configurations to the TOML config file, which has:- The node's callback URL.
- The number of times to retry an upload to the node.
- The delay between retries.
- Added the following configuration parameters to the auth service:
- The session duration for generated JWTs.
- The duration for stored nonces.
- The SIWE domain to use for the generated auth messages.
- Added a
Versions
- Polkadot SDK: polkadot-stable2412-6
- Rust: 1.87 (from rust-toolchain.toml)
Compatibility
- SH Backend v0.1.1 → compatible with pallets/runtime v0.1.0 and client v0.1.0.
- SDK v0.3.2 → compatible with backend v0.1.1, client v0.1.0, and pallets/runtime v0.1.0.
Upgrade Guide
- Ensure indexer service is restarted to apply migrations automatically.