From 49286b128d39851d8a60f437aa7b2d5211e9efcb Mon Sep 17 00:00:00 2001 From: Steve Degosserie <723552+stiiifff@users.noreply.github.com> Date: Tue, 24 Feb 2026 11:41:20 +0200 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=E2=9C=A8=20Bump=20client=20version?= =?UTF-8?q?=20to=20v0.25.0=20(#455)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- operator/Cargo.lock | 120 ++++++++++++++++++++++---------------------- operator/Cargo.toml | 2 +- 2 files changed, 61 insertions(+), 61 deletions(-) diff --git a/operator/Cargo.lock b/operator/Cargo.lock index 5ffba155..59a43614 100644 --- a/operator/Cargo.lock +++ b/operator/Cargo.lock @@ -1521,7 +1521,7 @@ dependencies = [ "pallet-message-queue", "parity-scale-codec", "scale-info", - "snowbridge-core 0.24.0", + "snowbridge-core 0.25.0", "sp-core", "sp-runtime", "sp-std", @@ -2607,7 +2607,7 @@ dependencies = [ [[package]] name = "datahaven-mainnet-runtime" -version = "0.24.0" +version = "0.25.0" dependencies = [ "alloy-core", "bridge-hub-common 0.13.1", @@ -2719,8 +2719,8 @@ dependencies = [ "shp-treasury-funding", "shp-tx-implicits-runtime-api", "smallvec", - "snowbridge-beacon-primitives 0.24.0", - "snowbridge-core 0.24.0", + "snowbridge-beacon-primitives 0.25.0", + "snowbridge-core 0.25.0", "snowbridge-inbound-queue-primitives", "snowbridge-merkle-tree", "snowbridge-outbound-queue-primitives", @@ -2763,7 +2763,7 @@ dependencies = [ [[package]] name = "datahaven-node" -version = "0.24.0" +version = "0.25.0" dependencies = [ "async-channel 1.9.0", "clap", @@ -2876,7 +2876,7 @@ dependencies = [ [[package]] name = "datahaven-runtime-common" -version = "0.24.0" +version = "0.25.0" dependencies = [ "alloy-core", "fp-account", @@ -2910,7 +2910,7 @@ dependencies = [ [[package]] name = "datahaven-stagenet-runtime" -version = "0.24.0" +version = "0.25.0" dependencies = [ "alloy-core", "bridge-hub-common 0.13.1", @@ -3022,8 +3022,8 @@ dependencies = [ "shp-treasury-funding", "shp-tx-implicits-runtime-api", "smallvec", - "snowbridge-beacon-primitives 0.24.0", - "snowbridge-core 0.24.0", + "snowbridge-beacon-primitives 0.25.0", + "snowbridge-core 0.25.0", "snowbridge-inbound-queue-primitives", "snowbridge-merkle-tree", "snowbridge-outbound-queue-primitives", @@ -3066,7 +3066,7 @@ dependencies = [ [[package]] name = "datahaven-testnet-runtime" -version = "0.24.0" +version = "0.25.0" dependencies = [ "alloy-core", "bridge-hub-common 0.13.1", @@ -3178,8 +3178,8 @@ dependencies = [ "shp-treasury-funding", "shp-tx-implicits-runtime-api", "smallvec", - "snowbridge-beacon-primitives 0.24.0", - "snowbridge-core 0.24.0", + "snowbridge-beacon-primitives 0.25.0", + "snowbridge-core 0.25.0", "snowbridge-inbound-queue-primitives", "snowbridge-merkle-tree", "snowbridge-outbound-queue-primitives", @@ -3371,7 +3371,7 @@ dependencies = [ [[package]] name = "dhp-bridge" -version = "0.24.0" +version = "0.25.0" dependencies = [ "frame-support", "frame-system", @@ -3379,7 +3379,7 @@ dependencies = [ "pallet-datahaven-native-transfer", "pallet-external-validators", "parity-scale-codec", - "snowbridge-core 0.24.0", + "snowbridge-core 0.25.0", "snowbridge-inbound-queue-primitives", "sp-core", "sp-std", @@ -8716,7 +8716,7 @@ dependencies = [ [[package]] name = "pallet-datahaven-native-transfer" -version = "0.24.0" +version = "0.25.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -8724,7 +8724,7 @@ dependencies = [ "pallet-balances", "parity-scale-codec", "scale-info", - "snowbridge-core 0.24.0", + "snowbridge-core 0.25.0", "snowbridge-outbound-queue-primitives", "sp-core", "sp-io", @@ -8828,7 +8828,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-balances-erc20" -version = "0.24.0" +version = "0.25.0" dependencies = [ "fp-evm", "frame-support", @@ -8851,7 +8851,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-batch" -version = "0.24.0" +version = "0.25.0" dependencies = [ "evm", "fp-evm", @@ -8890,7 +8890,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-call-permit" -version = "0.24.0" +version = "0.25.0" dependencies = [ "evm", "fp-evm", @@ -8956,7 +8956,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-datahaven-native-transfer" -version = "0.24.0" +version = "0.25.0" dependencies = [ "evm", "fp-evm", @@ -8970,7 +8970,7 @@ dependencies = [ "parity-scale-codec", "precompile-utils", "scale-info", - "snowbridge-core 0.24.0", + "snowbridge-core 0.25.0", "snowbridge-outbound-queue-primitives", "sp-core", "sp-io", @@ -9049,7 +9049,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-proxy" -version = "0.24.0" +version = "0.25.0" dependencies = [ "evm", "fp-evm", @@ -9093,7 +9093,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-registry" -version = "0.24.0" +version = "0.25.0" dependencies = [ "fp-evm", "frame-support", @@ -9144,7 +9144,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "snowbridge-core 0.24.0", + "snowbridge-core 0.25.0", "snowbridge-outbound-queue-primitives", "sp-core", "sp-io", @@ -9154,7 +9154,7 @@ dependencies = [ [[package]] name = "pallet-external-validators" -version = "0.24.0" +version = "0.25.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -9178,7 +9178,7 @@ dependencies = [ [[package]] name = "pallet-external-validators-rewards" -version = "0.24.0" +version = "0.25.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -9191,7 +9191,7 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "snowbridge-core 0.24.0", + "snowbridge-core 0.25.0", "snowbridge-outbound-queue-primitives", "sp-core", "sp-io", @@ -9417,7 +9417,7 @@ dependencies = [ [[package]] name = "pallet-outbound-commitment-store" -version = "0.24.0" +version = "0.25.0" dependencies = [ "frame-support", "frame-system", @@ -9541,7 +9541,7 @@ dependencies = [ [[package]] name = "pallet-proxy-genesis-companion" -version = "0.24.0" +version = "0.25.0" dependencies = [ "frame-support", "frame-system", @@ -9652,7 +9652,7 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" -version = "0.24.0" +version = "0.25.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -14800,7 +14800,7 @@ dependencies = [ [[package]] name = "snowbridge-beacon-primitives" -version = "0.24.0" +version = "0.25.0" dependencies = [ "byte-slice-cast", "frame-support", @@ -14845,7 +14845,7 @@ dependencies = [ [[package]] name = "snowbridge-core" -version = "0.24.0" +version = "0.25.0" dependencies = [ "bp-relayers", "ethabi-decode", @@ -14922,8 +14922,8 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "snowbridge-beacon-primitives 0.24.0", - "snowbridge-core 0.24.0", + "snowbridge-beacon-primitives 0.25.0", + "snowbridge-core 0.25.0", "snowbridge-verification-primitives", "sp-core", "sp-io", @@ -14936,7 +14936,7 @@ dependencies = [ [[package]] name = "snowbridge-merkle-tree" -version = "0.24.0" +version = "0.25.0" dependencies = [ "array-bytes", "hex", @@ -14977,7 +14977,7 @@ dependencies = [ [[package]] name = "snowbridge-outbound-queue-primitives" -version = "0.24.0" +version = "0.25.0" dependencies = [ "alloy-core", "ethabi-decode", @@ -14989,7 +14989,7 @@ dependencies = [ "parity-scale-codec", "polkadot-parachain-primitives", "scale-info", - "snowbridge-core 0.24.0", + "snowbridge-core 0.25.0", "snowbridge-verification-primitives", "sp-arithmetic", "sp-core", @@ -15003,12 +15003,12 @@ dependencies = [ [[package]] name = "snowbridge-outbound-queue-v2-runtime-api" -version = "0.24.0" +version = "0.25.0" dependencies = [ "frame-support", "parity-scale-codec", "scale-info", - "snowbridge-core 0.24.0", + "snowbridge-core 0.25.0", "snowbridge-merkle-tree", "snowbridge-outbound-queue-primitives", "sp-api", @@ -15018,7 +15018,7 @@ dependencies = [ [[package]] name = "snowbridge-pallet-ethereum-client" -version = "0.24.0" +version = "0.25.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -15031,8 +15031,8 @@ dependencies = [ "scale-info", "serde", "serde_json", - "snowbridge-beacon-primitives 0.24.0", - "snowbridge-core 0.24.0", + "snowbridge-beacon-primitives 0.25.0", + "snowbridge-core 0.25.0", "snowbridge-ethereum 0.3.0", "snowbridge-inbound-queue-primitives", "snowbridge-pallet-ethereum-client-fixtures", @@ -15048,8 +15048,8 @@ name = "snowbridge-pallet-ethereum-client-fixtures" version = "0.9.0" dependencies = [ "hex-literal 0.3.4", - "snowbridge-beacon-primitives 0.24.0", - "snowbridge-core 0.24.0", + "snowbridge-beacon-primitives 0.25.0", + "snowbridge-core 0.25.0", "snowbridge-inbound-queue-primitives", "sp-core", "sp-std", @@ -15057,7 +15057,7 @@ dependencies = [ [[package]] name = "snowbridge-pallet-inbound-queue-v2" -version = "0.24.0" +version = "0.25.0" dependencies = [ "alloy-core", "bp-relayers", @@ -15071,8 +15071,8 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "snowbridge-beacon-primitives 0.24.0", - "snowbridge-core 0.24.0", + "snowbridge-beacon-primitives 0.25.0", + "snowbridge-core 0.25.0", "snowbridge-inbound-queue-primitives", "snowbridge-pallet-ethereum-client", "snowbridge-pallet-inbound-queue-v2-fixtures", @@ -15093,8 +15093,8 @@ name = "snowbridge-pallet-inbound-queue-v2-fixtures" version = "0.10.0" dependencies = [ "hex-literal 0.3.4", - "snowbridge-beacon-primitives 0.24.0", - "snowbridge-core 0.24.0", + "snowbridge-beacon-primitives 0.25.0", + "snowbridge-core 0.25.0", "snowbridge-inbound-queue-primitives", "sp-core", "sp-std", @@ -15124,7 +15124,7 @@ dependencies = [ [[package]] name = "snowbridge-pallet-outbound-queue-v2" -version = "0.24.0" +version = "0.25.0" dependencies = [ "alloy-core", "bp-relayers", @@ -15138,8 +15138,8 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "snowbridge-beacon-primitives 0.24.0", - "snowbridge-core 0.24.0", + "snowbridge-beacon-primitives 0.25.0", + "snowbridge-core 0.25.0", "snowbridge-inbound-queue-primitives", "snowbridge-merkle-tree", "snowbridge-outbound-queue-primitives", @@ -15170,7 +15170,7 @@ dependencies = [ "parity-scale-codec", "polkadot-primitives", "scale-info", - "snowbridge-core 0.24.0", + "snowbridge-core 0.25.0", "snowbridge-outbound-queue-primitives", "snowbridge-pallet-outbound-queue", "sp-core", @@ -15183,7 +15183,7 @@ dependencies = [ [[package]] name = "snowbridge-pallet-system-v2" -version = "0.24.0" +version = "0.25.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -15195,7 +15195,7 @@ dependencies = [ "parity-scale-codec", "polkadot-primitives", "scale-info", - "snowbridge-core 0.24.0", + "snowbridge-core 0.25.0", "snowbridge-outbound-queue-primitives", "snowbridge-pallet-outbound-queue-v2", "snowbridge-pallet-system", @@ -15211,10 +15211,10 @@ dependencies = [ [[package]] name = "snowbridge-system-v2-runtime-api" -version = "0.24.0" +version = "0.25.0" dependencies = [ "parity-scale-codec", - "snowbridge-core 0.24.0", + "snowbridge-core 0.25.0", "sp-api", "sp-std", "staging-xcm", @@ -15222,7 +15222,7 @@ dependencies = [ [[package]] name = "snowbridge-test-utils" -version = "0.24.0" +version = "0.25.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -15242,12 +15242,12 @@ dependencies = [ [[package]] name = "snowbridge-verification-primitives" -version = "0.24.0" +version = "0.25.0" dependencies = [ "frame-support", "parity-scale-codec", "scale-info", - "snowbridge-beacon-primitives 0.24.0", + "snowbridge-beacon-primitives 0.25.0", "sp-core", "sp-std", ] diff --git a/operator/Cargo.toml b/operator/Cargo.toml index 92fd4f46..169d361b 100644 --- a/operator/Cargo.toml +++ b/operator/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" homepage = "https://datahaven.xyz/" license = "GPL-3" repository = "https://github.com/datahavenxyz/datahaven" -version = "0.24.0" +version = "0.25.0" [workspace] members = [ From 39aea69e36822fdd3d084ff5cca67cdfee88d537 Mon Sep 17 00:00:00 2001 From: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com> Date: Tue, 24 Feb 2026 17:31:49 +0100 Subject: [PATCH 2/4] test: integrate validator-set-submitter Docker container into E2E test (#453) ## Summary - Replace the manual `sendNewValidatorSetForEra` contract call in the `validator-set-update` E2E test with the **validator-set-submitter daemon** running as a Docker container - Add `test/e2e/framework/submitter.ts` with helpers to build the image, launch the container on the shared Docker network, and clean up after the test - Remove unused imports (`getOwnerAccount`, `decodeEventLog`, `parseEther`, `gatewayAbi`) that were only needed for manual submission The submitter automatically detects the last session of an era and submits the validator set via Snowbridge, matching production behavior more closely than the previous manual call. ## Test plan - [x] `bun test e2e/suites/validator-set-update.test.ts --timeout 900000` passes (4/4 tests, 15 assertions) - [x] Verify submitter container starts and connects to both Ethereum and DataHaven - [x] Verify `ExternalValidatorsSet` event is observed on DataHaven - [x] Verify submitter container is cleaned up after the test - [x] Verify Charlie and Dave appear in the final validator set --- test/e2e/framework/index.ts | 1 + test/e2e/framework/submitter.ts | 135 +++++++++++++++++++ test/e2e/suites/validator-set-update.test.ts | 75 +++++------ 3 files changed, 169 insertions(+), 42 deletions(-) create mode 100644 test/e2e/framework/submitter.ts diff --git a/test/e2e/framework/index.ts b/test/e2e/framework/index.ts index c76b4215..da11bf24 100644 --- a/test/e2e/framework/index.ts +++ b/test/e2e/framework/index.ts @@ -1,4 +1,5 @@ export * from "./connectors"; export * from "./manager"; +export * from "./submitter"; export * from "./suite"; export * from "./validators"; diff --git a/test/e2e/framework/submitter.ts b/test/e2e/framework/submitter.ts new file mode 100644 index 00000000..cad168eb --- /dev/null +++ b/test/e2e/framework/submitter.ts @@ -0,0 +1,135 @@ +/** + * E2E test helper for managing the validator-set-submitter Docker container. + * + * The submitter daemon automates `sendNewValidatorSetForEra` calls on the + * ServiceManager contract. This module builds the image, launches the + * container on the shared Docker network, and tears it down after the test. + */ + +import path from "node:path"; +import { $ } from "bun"; +import { ANVIL_FUNDED_ACCOUNTS, logger, waitForContainerToStart, waitForLog } from "utils"; +import { RELAYER_CONFIG_DIR } from "../../launcher/relayers"; + +const SUBMITTER_IMAGE = "datahavenxyz/validator-set-submitter:local"; +const SUBMITTER_READY_LOG = "Submitter started — watching session changes"; +const SUBMITTER_READY_TIMEOUT_SECONDS = 30; +const SUBMITTER_LOG_TAIL_LINES = 200; + +/** + * Builds the validator-set-submitter Docker image from the repo root. + */ +export async function buildSubmitterImage(): Promise { + logger.debug("Building validator-set-submitter Docker image..."); + const repoRoot = path.resolve(import.meta.dir, "../../.."); + await $`docker build -f test/tools/validator-set-submitter/Dockerfile -t ${SUBMITTER_IMAGE} .` + .cwd(repoRoot) + .quiet(); + logger.debug("Validator-set-submitter image built successfully"); +} + +export interface LaunchSubmitterOptions { + /** Docker network name (from launchedNetwork.networkName) */ + networkName: string; + /** Network ID for container naming */ + networkId: string; + /** Host-facing Ethereum RPC URL (e.g. http://127.0.0.1:32000) */ + ethereumRpcUrl: string; + /** DataHaven container name for inter-container networking */ + datahavenContainerName: string; + /** ServiceManager contract address from deployments */ + serviceManagerAddress: string; +} + +/** + * Launches the validator-set-submitter as a Docker container. + * + * Generates a YAML config, mounts it into the container, and connects + * it to the same Docker network as the DH nodes and relayers. + */ +export async function launchSubmitter(options: LaunchSubmitterOptions): Promise<{ + containerName: string; + cleanup: () => Promise; +}> { + const { networkName, networkId, ethereumRpcUrl, datahavenContainerName, serviceManagerAddress } = + options; + + const containerName = `submitter-${networkId}`; + + // Extract port from host-facing URL and rewrite for Docker inter-container access + const ethUrl = new URL(ethereumRpcUrl); + const dockerEthRpcUrl = `http://host.docker.internal:${ethUrl.port}`; + const dockerDhWsUrl = `ws://${datahavenContainerName}:9944`; + + // Generate YAML config + const configContent = [ + `ethereum_rpc_url: "${dockerEthRpcUrl}"`, + `datahaven_ws_url: "${dockerDhWsUrl}"`, + `service_manager_address: "${serviceManagerAddress}"`, + `network_id: "anvil"`, + `execution_fee: "0.1"`, + `relayer_fee: "0.2"` + ].join("\n"); + + const configFileName = `submitter-config-${networkId}.yml`; + await $`mkdir -p ${RELAYER_CONFIG_DIR}`.quiet(); + const hostConfigPath = path.resolve(path.join(RELAYER_CONFIG_DIR, configFileName)); + await Bun.write(hostConfigPath, configContent); + logger.debug(`Submitter config written to ${hostConfigPath}`); + + // Remove any existing container with the same name + await $`docker rm -f ${containerName}`.quiet().nothrow(); + + // Launch the container + const args = [ + "run", + "-d", + "--name", + containerName, + "--network", + networkName, + "--add-host", + "host.docker.internal:host-gateway", + "-v", + `${hostConfigPath}:/config/config.yml:ro`, + "-e", + `SUBMITTER_PRIVATE_KEY=${ANVIL_FUNDED_ACCOUNTS[6].privateKey}`, + SUBMITTER_IMAGE + ]; + + await $`docker ${args}`.quiet(); + await waitForContainerToStart(containerName); + try { + await waitForLog({ + containerName, + search: SUBMITTER_READY_LOG, + timeoutSeconds: SUBMITTER_READY_TIMEOUT_SECONDS + }); + } catch (error) { + const logs = + (await $`docker logs --tail ${SUBMITTER_LOG_TAIL_LINES} ${containerName}`.nothrow().text()) || + ""; + await stopSubmitter(containerName); + throw new Error( + `Submitter did not become ready. Expected log "${SUBMITTER_READY_LOG}". Last ${SUBMITTER_LOG_TAIL_LINES} log lines:\n${logs}`, + { cause: error } + ); + } + + logger.debug(`Submitter container ${containerName} started`); + + const cleanup = async () => { + await stopSubmitter(containerName); + }; + + return { containerName, cleanup }; +} + +/** + * Stops and removes the submitter container. + */ +export async function stopSubmitter(containerName: string): Promise { + logger.debug(`Stopping submitter container ${containerName}...`); + await $`docker rm -f ${containerName}`.quiet().nothrow(); + logger.debug(`Submitter container ${containerName} removed`); +} diff --git a/test/e2e/suites/validator-set-update.test.ts b/test/e2e/suites/validator-set-update.test.ts index fe18b4cb..c5a665c4 100644 --- a/test/e2e/suites/validator-set-update.test.ts +++ b/test/e2e/suites/validator-set-update.test.ts @@ -10,7 +10,6 @@ * - Observe `ExternalValidators.ExternalValidatorsSet` on DataHaven (substrate), confirming propagation. */ import { beforeAll, describe, expect, it } from "bun:test"; -import { getOwnerAccount } from "launcher/validators"; import { CROSS_CHAIN_TIMEOUTS, type Deployments, @@ -20,14 +19,15 @@ import { ZERO_ADDRESS } from "utils"; import { waitForDataHavenEvent } from "utils/events"; -import { decodeEventLog, parseEther } from "viem"; -import { dataHavenServiceManagerAbi, gatewayAbi } from "../../contract-bindings"; +import { dataHavenServiceManagerAbi } from "../../contract-bindings"; import { addValidatorToAllowlist, BaseTestSuite, + buildSubmitterImage, getValidator, isValidatorRunning, launchDatahavenValidator, + launchSubmitter, registerOperator, type TestConnectors } from "../framework"; @@ -50,11 +50,18 @@ class ValidatorSetUpdateTestSuite extends BaseTestSuite { launchDatahavenValidator("charlie", { launchedNetwork }), launchDatahavenValidator("dave", { launchedNetwork }) ]); + + // Build the submitter Docker image so it's ready for the test + await buildSubmitterImage(); } public getNetworkId(): string { return this.getConnectors().launchedNetwork.networkId; } + + public getLaunchedNetwork() { + return this.getConnectors().launchedNetwork; + } } // Create the test suite instance @@ -173,7 +180,7 @@ describe("Validator Set Update", () => { it( "should send updated validator set and verify on DataHaven", async () => { - const { publicClient, walletClient, dhApi } = connectors; + const { dhApi } = connectors; // Era rotation was paused in beforeAll. Wait for any pending transition to settle // (ForceNone prevents new eras, but an in-progress one must finish first). @@ -190,44 +197,7 @@ describe("Validator Set Update", () => { } const targetEra = BigInt(stableEraIndex + 1); - - // Send the updated validator set via Snowbridge - const hash = await walletClient.writeContract({ - address: deployments.ServiceManager as `0x${string}`, - abi: dataHavenServiceManagerAbi, - functionName: "sendNewValidatorSetForEra", - args: [targetEra, parseEther("0.1"), parseEther("0.2")], - value: parseEther("0.3"), - account: getOwnerAccount(), - chain: null - }); - const receipt = await publicClient.waitForTransactionReceipt({ hash }); - logger.info( - `sendNewValidatorSet tx status: ${receipt.status}, block: ${receipt.blockNumber}` - ); - expect(receipt.status).toBe("success"); - - // Verify OutboundMessageAccepted event was emitted - const hasOutboundAccepted = (receipt.logs ?? []).some((log: any) => { - try { - const decoded = decodeEventLog({ - abi: gatewayAbi, - data: log.data, - topics: log.topics - }); - if (decoded.eventName === "OutboundMessageAccepted") { - logger.info(`OutboundMessageAccepted event: nonce=${(decoded.args as any)?.nonce}`); - } - return decoded.eventName === "OutboundMessageAccepted"; - } catch { - return false; - } - }); - expect(hasOutboundAccepted).toBe(true); - - logger.info("Waiting for ExternalValidators.ExternalValidatorsSet event on DataHaven..."); - // Wait for the validator set to be updated on Substrate - await waitForDataHavenEvent({ + const validatorSetUpdated = waitForDataHavenEvent({ api: dhApi, pallet: "ExternalValidators", event: "ExternalValidatorsSet", @@ -235,6 +205,27 @@ describe("Validator Set Update", () => { BigInt(event.external_index) === targetEra, timeout: CROSS_CHAIN_TIMEOUTS.ETH_TO_DH_MS }); + // Prevent unhandled rejection if launchSubmitter fails before we await this promise. + void validatorSetUpdated.catch(() => undefined); + + // Launch the submitter daemon — it will detect the last-session condition + // and automatically call sendNewValidatorSetForEra on the ServiceManager. + const launchedNetwork = suite.getLaunchedNetwork(); + const { cleanup: cleanupSubmitter } = await launchSubmitter({ + networkName: launchedNetwork.networkName, + networkId: suite.getNetworkId(), + ethereumRpcUrl: connectors.elRpcUrl, + datahavenContainerName: `datahaven-alice-${suite.getNetworkId()}`, + serviceManagerAddress: deployments.ServiceManager + }); + + try { + logger.info("Waiting for ExternalValidators.ExternalValidatorsSet event on DataHaven..."); + // Wait for the validator set to be updated on Substrate + await validatorSetUpdated; + } finally { + await cleanupSubmitter(); + } // Resume era rotation const resumeTx = dhApi.tx.Sudo.sudo({ From 873a886df47f3fa01b148d8d5723c3e123e73bba Mon Sep 17 00:00:00 2001 From: Tobi Demeco <50408393+TDemeco@users.noreply.github.com> Date: Wed, 25 Feb 2026 09:13:25 -0300 Subject: [PATCH 3/4] build: :arrow_up: upgrade to StorageHub v0.4.2 (#457) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update StorageHub dependencies from v0.4.1 to v0.4.2. - Bump all `storage-hub` crate references to v0.4.2 - Wire new `--trusted-msps` CLI parameter and `with_file_transfer` API changes - Wire new `--trusted-file-transfer-batch-size-bytes` config option - Update Rust toolchain from 1.88.0 to 1.90.0 - Apply cargo fmt fixes for Rust 1.90 See [StorageHub v0.4.2 release notes](https://github.com/Moonsong-Labs/storage-hub/releases/tag/v0.4.2) for full details. ## ⚠️ Breaking Changes ⚠️ New `--trusted-msps` parameter will have to be added to the launch options of BSPs, and new `--trusted-file-transfer-batch-size-bytes` has sane default so adding it to the MSPs configuration is not required. --------- Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com> --- operator/Cargo.lock | 153 ++++++++++++++++++----------------- operator/Cargo.toml | 68 ++++++++-------- operator/node/src/cli.rs | 24 ++++++ operator/node/src/command.rs | 7 ++ operator/node/src/service.rs | 38 ++++++--- 5 files changed, 173 insertions(+), 117 deletions(-) diff --git a/operator/Cargo.lock b/operator/Cargo.lock index 59a43614..60011856 100644 --- a/operator/Cargo.lock +++ b/operator/Cargo.lock @@ -8639,8 +8639,8 @@ dependencies = [ [[package]] name = "pallet-bucket-nfts" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "frame-benchmarking", "frame-support", @@ -8696,8 +8696,8 @@ dependencies = [ [[package]] name = "pallet-cr-randomness" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "frame-support", "frame-system", @@ -8980,8 +8980,8 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-file-system" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "fp-account", "fp-evm", @@ -9220,8 +9220,8 @@ dependencies = [ [[package]] name = "pallet-file-system" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "frame-benchmarking", "frame-support", @@ -9249,8 +9249,8 @@ dependencies = [ [[package]] name = "pallet-file-system-runtime-api" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "parity-scale-codec", "scale-info", @@ -9445,8 +9445,8 @@ dependencies = [ [[package]] name = "pallet-payment-streams" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "frame-benchmarking", "frame-support", @@ -9465,8 +9465,8 @@ dependencies = [ [[package]] name = "pallet-payment-streams-runtime-api" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "parity-scale-codec", "scale-info", @@ -9493,8 +9493,8 @@ dependencies = [ [[package]] name = "pallet-proofs-dealer" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "frame-benchmarking", "frame-support", @@ -9519,8 +9519,8 @@ dependencies = [ [[package]] name = "pallet-proofs-dealer-runtime-api" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "parity-scale-codec", "scale-info", @@ -9558,8 +9558,8 @@ dependencies = [ [[package]] name = "pallet-randomness" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "frame-benchmarking", "frame-support", @@ -9696,8 +9696,8 @@ dependencies = [ [[package]] name = "pallet-storage-providers" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "frame-benchmarking", "frame-support", @@ -9718,8 +9718,8 @@ dependencies = [ [[package]] name = "pallet-storage-providers-runtime-api" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "parity-scale-codec", "scale-info", @@ -13881,8 +13881,8 @@ dependencies = [ [[package]] name = "shc-actors-derive" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "once_cell", "proc-macro2", @@ -13894,8 +13894,8 @@ dependencies = [ [[package]] name = "shc-actors-framework" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "anyhow", "bincode", @@ -13913,8 +13913,8 @@ dependencies = [ [[package]] name = "shc-blockchain-service" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "anyhow", "array-bytes", @@ -13969,8 +13969,8 @@ dependencies = [ [[package]] name = "shc-blockchain-service-db" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "chrono", "diesel", @@ -13993,8 +13993,8 @@ dependencies = [ [[package]] name = "shc-client" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "anyhow", "array-bytes", @@ -14002,6 +14002,7 @@ dependencies = [ "async-trait", "axum", "axum-extra", + "bytes", "chrono", "frame-benchmarking", "frame-benchmarking-cli", @@ -14067,12 +14068,13 @@ dependencies = [ [[package]] name = "shc-common" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "anyhow", "bigdecimal", "bincode", + "bytes", "cumulus-primitives-core", "cumulus-primitives-storage-weight-reclaim", "fp-account", @@ -14131,8 +14133,8 @@ dependencies = [ [[package]] name = "shc-file-manager" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "bincode", "hash-db", @@ -14140,6 +14142,7 @@ dependencies = [ "kvdb-memorydb", "kvdb-rocksdb", "log", + "lru 0.16.3", "parity-scale-codec", "serde_json", "shc-common", @@ -14155,8 +14158,8 @@ dependencies = [ [[package]] name = "shc-file-transfer-service" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "anyhow", "array-bytes", @@ -14164,6 +14167,7 @@ dependencies = [ "async-trait", "chrono", "futures", + "pallet-storage-providers-runtime-api", "parity-scale-codec", "prost 0.12.6", "prost-build 0.12.6", @@ -14178,14 +14182,15 @@ dependencies = [ "shc-common", "shp-file-key-verifier", "shp-file-metadata", + "sp-api", "thiserror 1.0.69", "tokio", ] [[package]] name = "shc-fisherman-service" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "async-trait", "diesel", @@ -14215,8 +14220,8 @@ dependencies = [ [[package]] name = "shc-forest-manager" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "anyhow", "async-trait", @@ -14241,8 +14246,8 @@ dependencies = [ [[package]] name = "shc-indexer-db" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "bigdecimal", "chrono", @@ -14269,8 +14274,8 @@ dependencies = [ [[package]] name = "shc-indexer-service" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "anyhow", "array-bytes", @@ -14320,8 +14325,8 @@ dependencies = [ [[package]] name = "shc-rpc" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "array-bytes", "async-trait", @@ -14366,8 +14371,8 @@ dependencies = [ [[package]] name = "shc-telemetry" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -14383,8 +14388,8 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "shp-constants" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "sp-core", "sp-runtime", @@ -14392,8 +14397,8 @@ dependencies = [ [[package]] name = "shp-data-price-updater" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "frame-support", "parity-scale-codec", @@ -14407,8 +14412,8 @@ dependencies = [ [[package]] name = "shp-file-key-verifier" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "frame-support", "parity-scale-codec", @@ -14425,8 +14430,8 @@ dependencies = [ [[package]] name = "shp-file-metadata" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "hex", "num-bigint", @@ -14441,8 +14446,8 @@ dependencies = [ [[package]] name = "shp-forest-verifier" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "frame-support", "parity-scale-codec", @@ -14458,16 +14463,16 @@ dependencies = [ [[package]] name = "shp-opaque" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "sp-runtime", ] [[package]] name = "shp-session-keys" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "async-trait", "parity-scale-codec", @@ -14481,8 +14486,8 @@ dependencies = [ [[package]] name = "shp-traits" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "frame-support", "parity-scale-codec", @@ -14495,8 +14500,8 @@ dependencies = [ [[package]] name = "shp-treasury-funding" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "log", "shp-traits", @@ -14506,8 +14511,8 @@ dependencies = [ [[package]] name = "shp-tx-implicits-runtime-api" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "parity-scale-codec", "scale-info", @@ -14519,8 +14524,8 @@ dependencies = [ [[package]] name = "shp-types" -version = "0.4.1" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.1#b5d6eb2ffa153d97e079d1fda382773b466f4702" +version = "0.4.2" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.4.2#5b52af21ca6c60db96bb7c3fe7c069075e941614" dependencies = [ "sp-core", "sp-runtime", diff --git a/operator/Cargo.toml b/operator/Cargo.toml index 169d361b..4419b4b3 100644 --- a/operator/Cargo.toml +++ b/operator/Cargo.toml @@ -272,42 +272,42 @@ fc-storage = { git = "https://github.com/polkadot-evm/frontier", branch = "stabl # StorageHub ## Runtime -pallet-bucket-nfts = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -pallet-cr-randomness = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -pallet-file-system = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -pallet-file-system-runtime-api = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -pallet-payment-streams = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -pallet-payment-streams-runtime-api = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -pallet-proofs-dealer = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -pallet-proofs-dealer-runtime-api = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -pallet-randomness = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -pallet-storage-providers = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -pallet-storage-providers-runtime-api = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shp-constants = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shp-data-price-updater = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shp-file-key-verifier = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shp-file-metadata = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shp-forest-verifier = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shp-traits = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shp-treasury-funding = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } +pallet-bucket-nfts = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +pallet-cr-randomness = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +pallet-file-system = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +pallet-file-system-runtime-api = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +pallet-payment-streams = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +pallet-payment-streams-runtime-api = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +pallet-proofs-dealer = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +pallet-proofs-dealer-runtime-api = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +pallet-randomness = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +pallet-storage-providers = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +pallet-storage-providers-runtime-api = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shp-constants = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shp-data-price-updater = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shp-file-key-verifier = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shp-file-metadata = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shp-forest-verifier = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shp-traits = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shp-treasury-funding = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } ## Client -shc-actors-derive = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shc-actors-framework = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shc-blockchain-service = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shc-client = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shc-common = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shc-file-manager = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shc-file-transfer-service = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shc-fisherman-service = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shc-forest-manager = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shc-indexer-db = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shc-indexer-service = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shc-rpc = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shp-opaque = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shp-tx-implicits-runtime-api = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } -shp-types = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } +shc-actors-derive = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shc-actors-framework = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shc-blockchain-service = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shc-client = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shc-common = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shc-file-manager = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shc-file-transfer-service = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shc-fisherman-service = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shc-forest-manager = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shc-indexer-db = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shc-indexer-service = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shc-rpc = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shp-opaque = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shp-tx-implicits-runtime-api = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } +shp-types = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } ## Precompiles -pallet-evm-precompile-file-system = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.1", default-features = false } +pallet-evm-precompile-file-system = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.4.2", default-features = false } # Static linking diff --git a/operator/node/src/cli.rs b/operator/node/src/cli.rs index af0ac8af..d661df4e 100644 --- a/operator/node/src/cli.rs +++ b/operator/node/src/cli.rs @@ -28,6 +28,7 @@ use shc_indexer_db::models::{FileFiltering, FileOrdering}; use shc_indexer_service::IndexerMode; use shc_rpc::RpcConfig; use shp_types::StorageDataUnit; +use sp_core::H256; // Available Sealing methods. #[derive(Copy, Clone, Debug, Default, ValueEnum)] @@ -73,6 +74,7 @@ pub struct Cli { "pending_db_url", "fisherman", "fisherman_database_url", "trusted_file_transfer_server", "trusted_file_transfer_server_host", "trusted_file_transfer_server_port", + "trusted_file_transfer_batch_size_bytes", "trusted_msps", ])] pub provider_config_file: Option, @@ -497,6 +499,26 @@ pub struct ProviderConfigurations { default_value = "7070" )] pub trusted_file_transfer_server_port: Option, + + /// Batch size in bytes used by MSP trusted upload ingestion (default: 2MB). + #[arg( + long, + value_name = "BYTES", + help_heading = "Trusted File Transfer Server Options", + default_value = "2097152", + value_parser = clap::value_parser!(u64).range(1..) + )] + pub trusted_file_transfer_batch_size_bytes: Option, + + /// Comma-separated list of trusted MSP IDs that this BSP accepts download requests from. + /// Only applicable when running as a BSP provider. + #[arg( + long = "trusted-msps", + value_delimiter = ',', + value_name = "MSP_ID", + help_heading = "BSP Download Authorisation" + )] + pub trusted_msps: Vec, } impl ProviderConfigurations { @@ -669,6 +691,8 @@ impl ProviderConfigurations { trusted_file_transfer_server: self.trusted_file_transfer_server, trusted_file_transfer_server_host: self.trusted_file_transfer_server_host.clone(), trusted_file_transfer_server_port: self.trusted_file_transfer_server_port, + trusted_file_transfer_batch_size_bytes: self.trusted_file_transfer_batch_size_bytes, + trusted_msps: self.trusted_msps.clone(), max_open_forests: self.max_open_forests, // We don't support maintenance mode for now. // maintenance_mode: self.maintenance_mode, diff --git a/operator/node/src/command.rs b/operator/node/src/command.rs index 7346833a..bcd4a3a4 100644 --- a/operator/node/src/command.rs +++ b/operator/node/src/command.rs @@ -37,6 +37,7 @@ use shc_client::builder::{ }; use shc_rpc::RpcConfig; use shp_types::StorageDataUnit; +use sp_core::H256; /// Configuration for the provider. #[derive(Debug, Clone, Deserialize)] @@ -92,6 +93,12 @@ pub struct ProviderOptions { /// Port for trusted file transfer HTTP server. #[serde(default, skip_serializing_if = "Option::is_none")] pub trusted_file_transfer_server_port: Option, + /// Batch size in bytes for trusted file transfer uploads. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub trusted_file_transfer_batch_size_bytes: Option, + /// List of trusted MSP IDs that BSP nodes accept download requests from. + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub trusted_msps: Vec, // Whether the node is running in maintenance mode. We are not supporting maintenance mode. // pub maintenance_mode: bool, } diff --git a/operator/node/src/service.rs b/operator/node/src/service.rs index b203e7c7..f8f34140 100644 --- a/operator/node/src/service.rs +++ b/operator/node/src/service.rs @@ -1192,19 +1192,10 @@ where let task_spawner = TaskSpawner::new(task_manager.spawn_handle(), task_spawner_name); let mut builder = StorageHubBuilder::::new(task_spawner, prometheus_registry); - // Setup file transfer service (common to all roles) let (file_transfer_request_protocol_name, file_transfer_request_receiver) = file_transfer_request_protocol .expect("FileTransfer request protocol should already be initialised."); - builder - .with_file_transfer( - file_transfer_request_receiver, - file_transfer_request_protocol_name, - network.clone(), - ) - .await; - // Role-specific configuration let rpc_config = match role_options { RoleOptions::Provider(ProviderOptions { @@ -1226,8 +1217,20 @@ where trusted_file_transfer_server, trusted_file_transfer_server_host, trusted_file_transfer_server_port, + trusted_file_transfer_batch_size_bytes, + trusted_msps, .. }) => { + // Setup file transfer service with trusted MSPs config + builder + .with_file_transfer( + client.clone(), + trusted_msps.clone(), + file_transfer_request_receiver, + file_transfer_request_protocol_name, + network.clone(), + ) + .await; info!( "Starting as a Storage Provider. Storage path: {:?}, Max storage capacity: {:?}, Jump capacity: {:?}, MSP charging period: {:?}", storage_path, max_storage_capacity, jump_capacity, msp_charging_period, @@ -1262,11 +1265,17 @@ where } if *trusted_file_transfer_server { + let batch_target_bytes = trusted_file_transfer_batch_size_bytes + .and_then(|size| usize::try_from(size).ok()) + .unwrap_or( + shc_client::trusted_file_transfer::server::DEFAULT_BATCH_TARGET_BYTES, + ); let file_transfer_config = shc_client::trusted_file_transfer::server::Config { host: trusted_file_transfer_server_host .clone() .unwrap_or_else(|| "127.0.0.1".to_string()), port: trusted_file_transfer_server_port.unwrap_or(7070), + batch_target_bytes, }; builder.with_trusted_file_transfer_server(file_transfer_config); } @@ -1281,6 +1290,17 @@ where rpc_config.clone() } RoleOptions::Fisherman(fisherman_options) => { + // Setup file transfer service (no trusted MSPs for fisherman) + builder + .with_file_transfer( + client.clone(), + vec![], + file_transfer_request_receiver, + file_transfer_request_protocol_name, + network.clone(), + ) + .await; + // Validate configuration compatibility with indexer if let Some(indexer_cfg) = indexer_options { if indexer_cfg.indexer_mode == shc_indexer_service::IndexerMode::Lite { From f0f99aee6f7f0fd4419a8ed711f4ba4355dbc383 Mon Sep 17 00:00:00 2001 From: Tobi Demeco <50408393+TDemeco@users.noreply.github.com> Date: Wed, 25 Feb 2026 13:35:13 -0300 Subject: [PATCH 4/4] fix: :bug: wire `trusted_msps` only when the provider is a BSP (#458) This is to better align the behaviour of the node with StorageHub's configurations, otherwise a MSP could pass `--trusted-msps` and use that functionality only intended for BSPs --- operator/node/src/service.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/operator/node/src/service.rs b/operator/node/src/service.rs index f8f34140..7b307420 100644 --- a/operator/node/src/service.rs +++ b/operator/node/src/service.rs @@ -1221,6 +1221,13 @@ where trusted_msps, .. }) => { + // Only BSP nodes can have trusted MSPs + let trusted_msps = if *provider_type == ProviderType::Bsp { + trusted_msps.clone() + } else { + Vec::new() + }; + // Setup file transfer service with trusted MSPs config builder .with_file_transfer(