diff --git a/.github/workflows/rust-checks.yaml b/.github/workflows/rust-checks.yaml index 13a63fd02a3..d7c6766e6a8 100644 --- a/.github/workflows/rust-checks.yaml +++ b/.github/workflows/rust-checks.yaml @@ -85,6 +85,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] + toolchain: [stable] runs-on: ${{ matrix.os }} env: RUSTFLAGS: "-Cdebug-assertions=y" diff --git a/README.md b/README.md index 2b44b4bb90f..831a1c3b272 100644 --- a/README.md +++ b/README.md @@ -184,14 +184,14 @@ cargo build --features try-runtime --release && cp target/release/substrate . ```bash # Assuming local nodes are running (e.g., `./substrate --dev --tmp --ws-port 9999`). -# Multiple --uri flags can be provided for parallel state download. +# Multiple URIs can be provided for parallel state download, either +# comma-separated or via repeated --uri flags. try-runtime \ --runtime /path-to-substrate/target/release/wbuild/my-runtime.wasm \ on-runtime-upgrade \ --disable-mbm-checks \ live \ - --uri ws://localhost:9999 \ - --uri ws://localhost:9998 + --uri ws://localhost:9999,ws://localhost:9998 ... ``` @@ -199,6 +199,14 @@ To speed up state download, you can provide multiple URIs for parallel fetching: ```bash # assuming multiple substrate nodes running on ports 9999, 9998, 9997 +# comma-separated: +try-runtime \ + --runtime /path-to-substrate/target/release/wbuild/my-runtime.wasm \ + on-runtime-upgrade \ + live \ + --uri ws://localhost:9999,ws://localhost:9998,ws://localhost:9997 + +# or repeated flags: try-runtime \ --runtime /path-to-substrate/target/release/wbuild/my-runtime.wasm \ on-runtime-upgrade \ @@ -210,8 +218,8 @@ try-runtime \ * Same as the previous example, but run it at specific block number's state and using the live polkadot network. This means that this block hash's state should not yet have been pruned by - the node running at `rpc.polkadot.io`. Multiple `--uri` flags can be provided for parallel - state download. + the node running at `rpc.polkadot.io`. Multiple URIs can be provided for parallel + state download (comma-separated or via repeated `--uri` flags). ```bash try-runtime \ @@ -236,8 +244,7 @@ For faster snapshot creation with large state, use multiple RPC endpoints: ```bash try-runtime --runtime existing create-snapshot \ - --uri ws://localhost:9999 \ - --uri ws://localhost:9998 \ + --uri ws://localhost:9999,ws://localhost:9998 \ -- my-snapshot.snap ``` diff --git a/cli/main.rs b/cli/main.rs index eaac5208088..f0fbde3c6d0 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -200,21 +200,28 @@ //! //! ```bash //! # Assuming local nodes are running (e.g., `./substrate --dev --tmp --ws-port 9999`). -//! # Multiple --uri flags can be provided for parallel state download. +//! # Multiple URIs can be provided for parallel state download, either +//! # comma-separated or via repeated --uri flags. //! try-runtime \ //! --runtime /path-to-substrate/target/release/wbuild/my-runtime.wasm \ //! on-runtime-upgrade \ //! --disable-mbm-checks \ //! live \ -//! --uri ws://localhost:9999 \ -//! --uri ws://localhost:9998 +//! --uri ws://localhost:9999,ws://localhost:9998 //! ... //! ``` //! //! To speed up state download, you can provide multiple URIs for parallel fetching: //! //! ```bash -//! # assuming multiple substrate nodes running on ports 9999, 9998, 9997 +//! # comma-separated: +//! try-runtime \ +//! --runtime /path-to-substrate/target/release/wbuild/my-runtime.wasm \ +//! on-runtime-upgrade \ +//! live \ +//! --uri ws://localhost:9999,ws://localhost:9998,ws://localhost:9997 +//! +//! # or repeated flags: //! try-runtime \ //! --runtime /path-to-substrate/target/release/wbuild/my-runtime.wasm \ //! on-runtime-upgrade \ @@ -226,8 +233,8 @@ //! //! * Same as the previous example, but run it at specific block number's state and using the live //! polkadot network. This means that this block hash's state should not yet have been pruned by -//! the node running at `rpc.polkadot.io`. Multiple `--uri` flags can be provided for parallel -//! state download. +//! the node running at `rpc.polkadot.io`. Multiple URIs can be provided for parallel state +//! download (comma-separated or via repeated `--uri` flags). //! //! ```bash //! try-runtime \ @@ -252,8 +259,7 @@ //! //! ```bash //! try-runtime --runtime existing create-snapshot \ -//! --uri ws://localhost:9999 \ -//! --uri ws://localhost:9998 \ +//! --uri ws://localhost:9999,ws://localhost:9998 \ //! -- my-snapshot.snap //! ``` //! diff --git a/core/src/common/state.rs b/core/src/common/state.rs index bb3f7665c94..fb19c9b0506 100644 --- a/core/src/common/state.rs +++ b/core/src/common/state.rs @@ -49,12 +49,12 @@ use crate::{ /// A `Live` variant for [`State`] #[derive(Debug, Clone, clap::Args)] pub struct LiveState { - /// The url(s) to connect to. Can be provided multiple times for parallel state download. + /// The url(s) to connect to. Can be comma-separated (no spaces) for parallel download. #[arg( short, long, value_parser = parse::url, - num_args = 1.., + value_delimiter = ',', required = true, )] pub uri: Vec, @@ -483,3 +483,110 @@ fn storage_proof_to_raw_json(storage_proof: &sp_state_machine::StorageProof) -> ) .to_string() } + +#[cfg(test)] +mod tests { + use clap::Parser; + + use super::*; + + #[derive(Parser)] + struct TestCli { + #[command(subcommand)] + state: State, + } + + /// Multiple URIs via repeated `--uri` flags. + #[test] + fn uri_repeated_flags() { + let cli = TestCli::parse_from([ + "test", + "live", + "--uri", + "ws://localhost:9999", + "--uri", + "ws://localhost:9998", + ]); + match cli.state { + State::Live(live) => { + assert_eq!(live.uri, vec!["ws://localhost:9999", "ws://localhost:9998"]); + } + _ => panic!("expected Live variant"), + } + } + + /// Multiple URIs via comma-separated value in a single `--uri`. + #[test] + fn uri_comma_separated() { + let cli = TestCli::parse_from([ + "test", + "live", + "--uri", + "ws://localhost:9999,ws://localhost:9998", + ]); + match cli.state { + State::Live(live) => { + assert_eq!(live.uri, vec!["ws://localhost:9999", "ws://localhost:9998"]); + } + _ => panic!("expected Live variant"), + } + } + + /// Mixing repeated flags with comma-separated values in a single invocation. + #[test] + fn uri_mixed_repeated_and_comma() { + let cli = TestCli::parse_from([ + "test", + "live", + "--uri", + "ws://localhost:9999,ws://localhost:9998", + "--uri", + "ws://localhost:9997", + ]); + match cli.state { + State::Live(live) => { + assert_eq!( + live.uri, + vec![ + "ws://localhost:9999", + "ws://localhost:9998", + "ws://localhost:9997", + ] + ); + } + _ => panic!("expected Live variant"), + } + } + + /// Single URI, the common case. + #[test] + fn uri_single_value() { + let cli = TestCli::parse_from(["test", "live", "--uri", "wss://rpc.polkadot.io:443"]); + match cli.state { + State::Live(live) => { + assert_eq!(live.uri, vec!["wss://rpc.polkadot.io:443"]); + } + _ => panic!("expected Live variant"), + } + } + + /// Arguments after `--uri` are not greedily consumed (the original bug). + #[test] + fn uri_positional_not_swallowed() { + let cli = TestCli::parse_from([ + "test", + "live", + "--uri", + "ws://localhost:9999", + "--pallet", + "System", + ]); + match cli.state { + State::Live(live) => { + assert_eq!(live.uri, vec!["ws://localhost:9999"]); + assert_eq!(live.pallet, vec!["System"]); + } + _ => panic!("expected Live variant"), + } + } +}