From a02a1a7961c52749f1c169cce09c5e3894df1680 Mon Sep 17 00:00:00 2001 From: Serhii Temchenko Date: Tue, 28 May 2024 17:37:39 -0700 Subject: [PATCH 01/40] chore(gitignore): Added .idea to the .gitignore file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 378be3110..6d4cd13b3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .DS_Store .AppleDouble .LSOverride +.idea # Rust .gitignore # https://github.com/github/gitignore/blob/main/Rust.gitignore From ff1797bca5fc1886cb8b22237547446532718a73 Mon Sep 17 00:00:00 2001 From: Serhii Temchenko Date: Tue, 28 May 2024 17:44:31 -0700 Subject: [PATCH 02/40] feat(primitives): Added cli primitives --- Cargo.lock | 7 +++++++ Cargo.toml | 2 +- primitives/.gitkeep | 0 primitives/cli/Cargo.toml | 14 ++++++++++++++ primitives/cli/src/error.rs | 7 +++++++ primitives/cli/src/lib.rs | 9 +++++++++ primitives/cli/src/logger.rs | 12 ++++++++++++ primitives/cli/src/result.rs | 9 +++++++++ 8 files changed, 59 insertions(+), 1 deletion(-) delete mode 100644 primitives/.gitkeep create mode 100644 primitives/cli/Cargo.toml create mode 100644 primitives/cli/src/error.rs create mode 100644 primitives/cli/src/lib.rs create mode 100644 primitives/cli/src/logger.rs create mode 100644 primitives/cli/src/result.rs diff --git a/Cargo.lock b/Cargo.lock index adef49283..bd3109f9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1416,6 +1416,13 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +[[package]] +name = "cli-primitives" +version = "0.1.0" +dependencies = [ + "thiserror", +] + [[package]] name = "coarsetime" version = "0.1.34" diff --git a/Cargo.toml b/Cargo.toml index 1c7a01905..cf584295f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ license-file = "LICENSE" repository = "https://github.com/eigerco/polka-storage" [workspace] -members = ["node", "runtime"] +members = ["node", "primitives/cli", "runtime"] resolver = "2" # FIXME(#@jmg-duarte,#7,14/5/24): remove the patch once something >1.11.0 is released diff --git a/primitives/.gitkeep b/primitives/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/primitives/cli/Cargo.toml b/primitives/cli/Cargo.toml new file mode 100644 index 000000000..509aa41f7 --- /dev/null +++ b/primitives/cli/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "cli-primitives" +version = "0.1.0" +authors.workspace = true +edition.workspace = true +homepage.workspace = true +license-file.workspace = true +repository.workspace = true + +[dependencies] +thiserror = { workspace = true } + +[lints] +workspace = true diff --git a/primitives/cli/src/error.rs b/primitives/cli/src/error.rs new file mode 100644 index 000000000..2af15e7f2 --- /dev/null +++ b/primitives/cli/src/error.rs @@ -0,0 +1,7 @@ +use thiserror::Error; + +/// CLI components error handling implementor. +#[derive(Debug, Error)] +pub enum Error { + // TODO(@serhii, no-ref, 2024-05-28): Add and extend with error variants required in the `polka-storage` or `polka-storage-provider` crates. +} diff --git a/primitives/cli/src/lib.rs b/primitives/cli/src/lib.rs new file mode 100644 index 000000000..b0c27e2ce --- /dev/null +++ b/primitives/cli/src/lib.rs @@ -0,0 +1,9 @@ +#![deny(unused_crate_dependencies)] + +mod error; +mod result; + +pub mod logger; + +pub use error::Error; +pub use result::Result; diff --git a/primitives/cli/src/logger.rs b/primitives/cli/src/logger.rs new file mode 100644 index 000000000..f75a2922c --- /dev/null +++ b/primitives/cli/src/logger.rs @@ -0,0 +1,12 @@ +/// Statically defined logging channels names (targets). +#[derive(Debug, Copy, Clone)] +pub enum Channel { + // TODO(@serhii, no-ref, 2024-05-28): Add and extend with error variants required in the `polka-storage` or `polka-storage-provider` crates. +} + +impl AsRef for Channel { + fn as_ref(&self) -> &str { + // TODO(@serhii, no-ref, 2024-05-28): Add and extend with error variants required in the `polka-storage` or `polka-storage-provider` crates. + todo!() + } +} diff --git a/primitives/cli/src/result.rs b/primitives/cli/src/result.rs new file mode 100644 index 000000000..314c46e85 --- /dev/null +++ b/primitives/cli/src/result.rs @@ -0,0 +1,9 @@ +//! Result type. +//! +//! This module defines an alias for the `Result` type with the error +//! type [`Error`](crate::Error). + +use crate::Error; + +/// Result Type. See module level [documentation](self). +pub type Result = std::result::Result; From 3d4c76bf1453357d346788c3ef61d7a0a1d88178 Mon Sep 17 00:00:00 2001 From: Serhii Temchenko Date: Tue, 28 May 2024 17:46:48 -0700 Subject: [PATCH 03/40] feat(storage-provider): Added a storage provider CLI component with defined barebones and commands --- Cargo.lock | 36 ++++++++++++++++++- Cargo.toml | 5 ++- cli/polka-storage-provider/.gitkeep | 0 cli/polka-storage-provider/Cargo.toml | 18 ++++++++++ cli/polka-storage-provider/src/cli.rs | 19 ++++++++++ cli/polka-storage-provider/src/commands.rs | 7 ++++ .../src/commands/run_rpc_cmd.rs | 10 ++++++ .../src/commands/runner.rs | 26 ++++++++++++++ .../src/commands/stop_rpc_cmd.rs | 5 +++ cli/polka-storage-provider/src/main.rs | 20 +++++++++++ 10 files changed, 144 insertions(+), 2 deletions(-) delete mode 100644 cli/polka-storage-provider/.gitkeep create mode 100644 cli/polka-storage-provider/Cargo.toml create mode 100644 cli/polka-storage-provider/src/cli.rs create mode 100644 cli/polka-storage-provider/src/commands.rs create mode 100644 cli/polka-storage-provider/src/commands/run_rpc_cmd.rs create mode 100644 cli/polka-storage-provider/src/commands/runner.rs create mode 100644 cli/polka-storage-provider/src/commands/stop_rpc_cmd.rs create mode 100644 cli/polka-storage-provider/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index bd3109f9a..d9749f765 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3010,6 +3010,16 @@ dependencies = [ "syn 2.0.61", ] +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +dependencies = [ + "log", + "regex", +] + [[package]] name = "env_logger" version = "0.10.2" @@ -3023,6 +3033,19 @@ dependencies = [ "termcolor", ] +[[package]] +name = "env_logger" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + [[package]] name = "environmental" version = "1.1.4" @@ -3236,7 +3259,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84f2e425d9790201ba4af4630191feac6dcc98765b118d4d18e91d23c2353866" dependencies = [ - "env_logger", + "env_logger 0.10.2", "log", ] @@ -7789,6 +7812,17 @@ dependencies = [ "substrate-prometheus-endpoint", ] +[[package]] +name = "polka-storage-provider" +version = "0.1.0" +dependencies = [ + "clap", + "cli-primitives", + "env_logger 0.11.3", + "tokio", + "url", +] + [[package]] name = "polka-storage-runtime" version = "0.0.0" diff --git a/Cargo.toml b/Cargo.toml index cf584295f..3cfb954b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ license-file = "LICENSE" repository = "https://github.com/eigerco/polka-storage" [workspace] -members = ["node", "primitives/cli", "runtime"] +members = ["cli/polka-storage-provider", "node", "primitives/cli", "runtime"] resolver = "2" # FIXME(#@jmg-duarte,#7,14/5/24): remove the patch once something >1.11.0 is released @@ -39,6 +39,9 @@ smallvec = "1.11.0" syn = { version = "2.0.53" } thiserror = { version = "1.0.48" } tracing-subscriber = { version = "0.3.18" } +url = "2.5.0" +env_logger = "0.11.2" +tokio = { version = "^1" } # Local polka-storage-runtime = { path = "runtime" } diff --git a/cli/polka-storage-provider/.gitkeep b/cli/polka-storage-provider/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/cli/polka-storage-provider/Cargo.toml b/cli/polka-storage-provider/Cargo.toml new file mode 100644 index 000000000..c6db0150a --- /dev/null +++ b/cli/polka-storage-provider/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "polka-storage-provider" +version = "0.1.0" +authors.workspace = true +edition.workspace = true +homepage.workspace = true +license-file.workspace = true +repository.workspace = true + +[dependencies] +cli-primitives = { path = "../../primitives/cli" } +clap = { workspace = true, features = ["derive"] } +url = { workspace = true } +env_logger = { workspace = true } +tokio = { workspace = true, features = ["full"] } + +[lints] +workspace = true diff --git a/cli/polka-storage-provider/src/cli.rs b/cli/polka-storage-provider/src/cli.rs new file mode 100644 index 000000000..eb20f3af7 --- /dev/null +++ b/cli/polka-storage-provider/src/cli.rs @@ -0,0 +1,19 @@ +use crate::commands::{RunRpcCmd, StopRpcCmd}; +use clap::Parser; + +/// A CLI application that facilitates management operations over a running full node and other components. +#[derive(Parser, Debug, Clone)] +#[command(author, version, about, long_about = None)] +pub(crate) struct Cli { + #[command(subcommand)] + pub subcommand: Option, +} + +/// Supported sub-commands. +#[derive(Debug, clap::Subcommand, Clone)] +pub enum Subcommand { + /// Command to run the RPC server. + RunRpc(RunRpcCmd), + /// Command to stop the RPC server. + StopRpc(StopRpcCmd), +} diff --git a/cli/polka-storage-provider/src/commands.rs b/cli/polka-storage-provider/src/commands.rs new file mode 100644 index 000000000..c1e77c298 --- /dev/null +++ b/cli/polka-storage-provider/src/commands.rs @@ -0,0 +1,7 @@ +mod run_rpc_cmd; +mod stop_rpc_cmd; + +pub(crate) mod runner; + +pub(crate) use run_rpc_cmd::RunRpcCmd; +pub(crate) use stop_rpc_cmd::StopRpcCmd; diff --git a/cli/polka-storage-provider/src/commands/run_rpc_cmd.rs b/cli/polka-storage-provider/src/commands/run_rpc_cmd.rs new file mode 100644 index 000000000..ff6c1c2e9 --- /dev/null +++ b/cli/polka-storage-provider/src/commands/run_rpc_cmd.rs @@ -0,0 +1,10 @@ +use clap::Parser; +use url::Url; + +/// The `run-rpc` command used to run a server to listen for RPC calls. +#[derive(Debug, Clone, Parser)] +pub(crate) struct RunRpcCmd { + /// RPC API endpoint of the parachain node. + #[arg(short = 'n', long, default_value = "ws://127.0.0.1:9944")] + pub node_rpc_address: Url, +} diff --git a/cli/polka-storage-provider/src/commands/runner.rs b/cli/polka-storage-provider/src/commands/runner.rs new file mode 100644 index 000000000..b1f892ca0 --- /dev/null +++ b/cli/polka-storage-provider/src/commands/runner.rs @@ -0,0 +1,26 @@ +use crate::cli::Subcommand; +use crate::Cli; +use clap::Parser; +use cli_primitives::Result; + +/// Parses command line arguments into the service configuration and runs the specified +/// command with it. +pub(crate) async fn run() -> Result<()> { + // CLI arguments parsed and mapped to the struct. + let cli_arguments: Cli = Cli::parse(); + + match &cli_arguments.subcommand { + Some(Subcommand::RunRpc(_cmd)) => { + // TODO(@serhii, #52, 2024-05-28): Implement an RPC server to listen for RPC calls, which will be used by the UI app to display information to the user. + Ok(()) + } + Some(Subcommand::StopRpc(_cmd)) => { + // TODO(@serhii, #52, 2024-05-28): Implement functionality to gracefully stop the previously started RPC server. + Ok(()) + } + None => { + // TODO(@serhii, #54, 2024-05-28): Add default logic for when no specific command is requested. + Ok(()) + } + } +} diff --git a/cli/polka-storage-provider/src/commands/stop_rpc_cmd.rs b/cli/polka-storage-provider/src/commands/stop_rpc_cmd.rs new file mode 100644 index 000000000..0af211e2a --- /dev/null +++ b/cli/polka-storage-provider/src/commands/stop_rpc_cmd.rs @@ -0,0 +1,5 @@ +use clap::Parser; + +/// The `stop-rpc` command used to stop a server that listen for RPC calls. +#[derive(Debug, Clone, Parser)] +pub(crate) struct StopRpcCmd {} diff --git a/cli/polka-storage-provider/src/main.rs b/cli/polka-storage-provider/src/main.rs new file mode 100644 index 000000000..b744a8cd5 --- /dev/null +++ b/cli/polka-storage-provider/src/main.rs @@ -0,0 +1,20 @@ +//! A CLI application that facilitates management operations over a running full node and other components. + +#![deny(unused_crate_dependencies)] + +mod cli; + +pub(crate) mod commands; +pub(crate) use cli::Cli; + +use cli_primitives::Result; +use commands::runner; + +#[tokio::main] +async fn main() -> Result<()> { + // Logger initialization. + env_logger::init(); + + // Run requested command. + runner::run().await +} From 9e9261696574ea9d484b3e8ef688e56adf7f1ae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Mon, 3 Jun 2024 15:39:52 +0200 Subject: [PATCH 04/40] feat: wip provider rpc --- .gitignore | 1 + Cargo.lock | 166 +++++++++++++----- Cargo.toml | 13 +- cli/polka-storage-provider/Cargo.toml | 17 +- cli/polka-storage-provider/src/cli.rs | 22 ++- cli/polka-storage-provider/src/commands.rs | 7 - .../src/commands/info.rs | 12 ++ .../src/commands/init.rs | 17 ++ .../src/commands/mod.rs | 9 + .../src/commands/run.rs | 41 +++++ .../src/commands/run_rpc_cmd.rs | 10 -- .../src/commands/runner.rs | 19 +- .../src/commands/stop_rpc_cmd.rs | 5 - cli/polka-storage-provider/src/main.rs | 4 +- .../src/rpc/methods/common.rs | 18 ++ .../src/rpc/methods/mod.rs | 30 ++++ cli/polka-storage-provider/src/rpc/mod.rs | 27 +++ cli/polka-storage-provider/src/rpc/reflect.rs | 55 ++++++ primitives/cli/Cargo.toml | 4 +- primitives/cli/src/error.rs | 2 + 20 files changed, 383 insertions(+), 96 deletions(-) delete mode 100644 cli/polka-storage-provider/src/commands.rs create mode 100644 cli/polka-storage-provider/src/commands/info.rs create mode 100644 cli/polka-storage-provider/src/commands/init.rs create mode 100644 cli/polka-storage-provider/src/commands/mod.rs create mode 100644 cli/polka-storage-provider/src/commands/run.rs delete mode 100644 cli/polka-storage-provider/src/commands/run_rpc_cmd.rs delete mode 100644 cli/polka-storage-provider/src/commands/stop_rpc_cmd.rs create mode 100644 cli/polka-storage-provider/src/rpc/methods/common.rs create mode 100644 cli/polka-storage-provider/src/rpc/methods/mod.rs create mode 100644 cli/polka-storage-provider/src/rpc/mod.rs create mode 100644 cli/polka-storage-provider/src/rpc/reflect.rs diff --git a/.gitignore b/.gitignore index 6d4cd13b3..d541f6c74 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ .AppleDouble .LSOverride .idea +.vscode # Rust .gitignore # https://github.com/github/gitignore/blob/main/Rust.gitignore diff --git a/Cargo.lock b/Cargo.lock index d9749f765..4c155fc56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1305,6 +1305,7 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", + "serde", "wasm-bindgen", "windows-targets 0.52.5", ] @@ -2925,9 +2926,9 @@ dependencies = [ [[package]] name = "either" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "elliptic-curve" @@ -3010,16 +3011,6 @@ dependencies = [ "syn 2.0.61", ] -[[package]] -name = "env_filter" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" -dependencies = [ - "log", - "regex", -] - [[package]] name = "env_logger" version = "0.10.2" @@ -3033,19 +3024,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "env_logger" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "humantime", - "log", -] - [[package]] name = "environmental" version = "1.1.4" @@ -3259,7 +3237,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84f2e425d9790201ba4af4630191feac6dcc98765b118d4d18e91d23c2353866" dependencies = [ - "env_logger 0.10.2", + "env_logger", "log", ] @@ -3796,6 +3774,10 @@ name = "futures-timer" version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" +dependencies = [ + "gloo-timers", + "send_wrapper", +] [[package]] name = "futures-util" @@ -3923,6 +3905,52 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "gloo-net" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43aaa242d1239a8822c15c645f02166398da4f8b5c4bae795c1f5b44e9eee173" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils", + "http", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gloo-utils" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "governor" version = "0.6.3" @@ -4390,9 +4418,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -4530,10 +4558,13 @@ version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfdb12a2381ea5b2e68c3469ec604a007b367778cdb14d09612c8069ebd616ad" dependencies = [ + "jsonrpsee-client-transport", "jsonrpsee-core", + "jsonrpsee-http-client", "jsonrpsee-proc-macros", "jsonrpsee-server", "jsonrpsee-types", + "jsonrpsee-wasm-client", "jsonrpsee-ws-client", "tokio", "tracing", @@ -4545,7 +4576,9 @@ version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4978087a58c3ab02efc5b07c5e5e2803024536106fd5506f558db172c889b3aa" dependencies = [ + "futures-channel", "futures-util", + "gloo-net", "http", "jsonrpsee-core", "pin-project", @@ -4558,6 +4591,7 @@ dependencies = [ "tokio-util", "tracing", "url", + "webpki-roots 0.26.1", ] [[package]] @@ -4583,6 +4617,27 @@ dependencies = [ "tokio", "tokio-stream", "tracing", + "wasm-bindgen-futures", +] + +[[package]] +name = "jsonrpsee-http-client" +version = "0.22.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ccf93fc4a0bfe05d851d37d7c32b7f370fe94336b52a2f0efc5f1981895c2e5" +dependencies = [ + "async-trait", + "hyper", + "hyper-rustls", + "jsonrpsee-core", + "jsonrpsee-types", + "serde", + "serde_json", + "thiserror", + "tokio", + "tower", + "tracing", + "url", ] [[package]] @@ -4635,6 +4690,17 @@ dependencies = [ "thiserror", ] +[[package]] +name = "jsonrpsee-wasm-client" +version = "0.22.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f448d8eacd945cc17b6c0b42c361531ca36a962ee186342a97cdb8fca679cd77" +dependencies = [ + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", +] + [[package]] name = "jsonrpsee-ws-client" version = "0.22.5" @@ -5132,7 +5198,7 @@ dependencies = [ "rw-stream-sink", "soketto", "url", - "webpki-roots", + "webpki-roots 0.22.6", ] [[package]] @@ -7816,10 +7882,15 @@ dependencies = [ name = "polka-storage-provider" version = "0.1.0" dependencies = [ + "chrono", "clap", "cli-primitives", - "env_logger 0.11.3", + "futures", + "jsonrpsee", + "serde", "tokio", + "tracing", + "tracing-subscriber", "url", ] @@ -9252,9 +9323,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.82" +version = "1.0.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" dependencies = [ "unicode-ident", ] @@ -11651,11 +11722,17 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +[[package]] +name = "send_wrapper" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" + [[package]] name = "serde" -version = "1.0.201" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] @@ -11671,9 +11748,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.201" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", @@ -13378,9 +13455,9 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.60" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] @@ -13407,9 +13484,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "1.0.60" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", @@ -14609,6 +14686,15 @@ dependencies = [ "webpki", ] +[[package]] +name = "webpki-roots" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "westend-runtime" version = "7.0.0" diff --git a/Cargo.toml b/Cargo.toml index 25b3fcb01..1290c2d6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,12 +28,13 @@ panic = 'abort' # Use abort on panic to reduce binary size substrate-build-script-utils = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0" } substrate-wasm-builder = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0" } +async-trait = { version = "0.1.18" } clap = { version = "4.5.3" } codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } color-print = "0.3.4" futures = "0.3.28" hex-literal = { version = "0.4.1" } -jsonrpsee = { version = "0.22" } +jsonrpsee = { version = "0.22.5" } log = { version = "0.4.21", default-features = false } polkavm = "0.9.3" polkavm-derive = "0.9.1" @@ -46,12 +47,14 @@ serde_derive = { version = "1.0.117" } serde_json = { version = "1.0.114", default-features = false } serde_yaml = { version = "0.9" } smallvec = "1.11.0" +subxt = { version = "0.37.0" } syn = { version = "2.0.53" } thiserror = { version = "1.0.48" } +tokio = { version = "^1" } +tracing = "0.1.40" tracing-subscriber = { version = "0.3.18" } url = "2.5.0" -env_logger = "0.11.2" -tokio = { version = "^1" } +chrono = "0.4.38" # Local polka-storage-runtime = { path = "runtime" } @@ -95,7 +98,9 @@ substrate-prometheus-endpoint = { git = "https://github.com/paritytech/polkadot- # Polkadot pallet-xcm = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", default-features = false } -polkadot-cli = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", features = ["rococo-native"] } +polkadot-cli = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", features = [ + "rococo-native", +] } polkadot-parachain-primitives = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", default-features = false } polkadot-primitives = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0" } polkadot-runtime-common = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", default-features = false } diff --git a/cli/polka-storage-provider/Cargo.toml b/cli/polka-storage-provider/Cargo.toml index c6db0150a..6c5675c3b 100644 --- a/cli/polka-storage-provider/Cargo.toml +++ b/cli/polka-storage-provider/Cargo.toml @@ -1,18 +1,25 @@ [package] -name = "polka-storage-provider" -version = "0.1.0" authors.workspace = true edition.workspace = true homepage.workspace = true license-file.workspace = true +name = "polka-storage-provider" repository.workspace = true +version = "0.1.0" [dependencies] -cli-primitives = { path = "../../primitives/cli" } +# async-trait = { workspace = true } clap = { workspace = true, features = ["derive"] } -url = { workspace = true } -env_logger = { workspace = true } +cli-primitives = { path = "../../primitives/cli" } +chrono = { workspace = true, features = ["serde"] } +jsonrpsee = { workspace = true, features = ["full"] } tokio = { workspace = true, features = ["full"] } +tracing = { workspace = true } +tracing-subscriber = { workspace = true } +url = { workspace = true } +# subxt = { workspace = true } +serde = { workspace = true } +futures = "0.3.30" [lints] workspace = true diff --git a/cli/polka-storage-provider/src/cli.rs b/cli/polka-storage-provider/src/cli.rs index eb20f3af7..6a75adaed 100644 --- a/cli/polka-storage-provider/src/cli.rs +++ b/cli/polka-storage-provider/src/cli.rs @@ -1,19 +1,23 @@ -use crate::commands::{RunRpcCmd, StopRpcCmd}; use clap::Parser; -/// A CLI application that facilitates management operations over a running full node and other components. +use crate::commands::{InfoCommand, InitCommand, RunCommand}; + +/// A CLI application that facilitates management operations over a running full +/// node and other components. #[derive(Parser, Debug, Clone)] -#[command(author, version, about, long_about = None)] +#[command(author, version, about, long_about = None, arg_required_else_help(true))] pub(crate) struct Cli { #[command(subcommand)] - pub subcommand: Option, + pub subcommand: Option, } /// Supported sub-commands. #[derive(Debug, clap::Subcommand, Clone)] -pub enum Subcommand { - /// Command to run the RPC server. - RunRpc(RunRpcCmd), - /// Command to stop the RPC server. - StopRpc(StopRpcCmd), +pub enum SubCommand { + /// Initialize the polka storage miner + Init(InitCommand), + /// Start a polka storage miner + Run(RunCommand), + /// Info command + Info(InfoCommand), } diff --git a/cli/polka-storage-provider/src/commands.rs b/cli/polka-storage-provider/src/commands.rs deleted file mode 100644 index c1e77c298..000000000 --- a/cli/polka-storage-provider/src/commands.rs +++ /dev/null @@ -1,7 +0,0 @@ -mod run_rpc_cmd; -mod stop_rpc_cmd; - -pub(crate) mod runner; - -pub(crate) use run_rpc_cmd::RunRpcCmd; -pub(crate) use stop_rpc_cmd::StopRpcCmd; diff --git a/cli/polka-storage-provider/src/commands/info.rs b/cli/polka-storage-provider/src/commands/info.rs new file mode 100644 index 000000000..44a0ffda1 --- /dev/null +++ b/cli/polka-storage-provider/src/commands/info.rs @@ -0,0 +1,12 @@ +use clap::Parser; +use cli_primitives::Result; + +#[derive(Debug, Clone, Parser)] +pub(crate) struct InfoCommand {} + +impl InfoCommand { + pub async fn handle(&self) -> Result<()> { + // TODO(@cernicc,31/05/2024): Print providers information + Ok(()) + } +} diff --git a/cli/polka-storage-provider/src/commands/init.rs b/cli/polka-storage-provider/src/commands/init.rs new file mode 100644 index 000000000..fc95126b5 --- /dev/null +++ b/cli/polka-storage-provider/src/commands/init.rs @@ -0,0 +1,17 @@ +use clap::Parser; +use cli_primitives::Result; +use tracing::info; + +#[derive(Debug, Clone, Parser)] +pub(crate) struct InitCommand {} + +impl InitCommand { + pub async fn handle(&self) -> Result<()> { + info!("Initializing polka storage miner..."); + // TODO(@cernicc,31/05/2024): Init needed configurations. + // TODO(@cernicc,31/05/2024): Check if full node is synced + info!("Miner initialized successfully. Start it with `polka-storage-provider run`"); + + Ok(()) + } +} diff --git a/cli/polka-storage-provider/src/commands/mod.rs b/cli/polka-storage-provider/src/commands/mod.rs new file mode 100644 index 000000000..22f52563c --- /dev/null +++ b/cli/polka-storage-provider/src/commands/mod.rs @@ -0,0 +1,9 @@ +mod info; +mod init; +mod run; + +pub(crate) mod runner; + +pub(crate) use info::InfoCommand; +pub(crate) use init::InitCommand; +pub(crate) use run::RunCommand; diff --git a/cli/polka-storage-provider/src/commands/run.rs b/cli/polka-storage-provider/src/commands/run.rs new file mode 100644 index 000000000..1ed0b63d3 --- /dev/null +++ b/cli/polka-storage-provider/src/commands/run.rs @@ -0,0 +1,41 @@ +use std::{net::SocketAddr, sync::Arc}; + +use chrono::Utc; +use clap::Parser; +use cli_primitives::Result; +use url::Url; + +use crate::rpc::{start_rpc, RpcServerState}; + +// use crate::rpc::{RpcServerImpl, ServiceServer}; + +const SERVER_DEFAULT_BIND_ADDR: &str = "127.0.0.1:8000"; +const SUBSTRATE_DEFAULT_RPC_ADDR: &str = "ws://127.0.0.1:9944"; + +#[derive(Debug, Clone, Parser)] +pub(crate) struct RunCommand { + /// RPC API endpoint of the parachain node + #[arg(short = 'n', long, default_value = SUBSTRATE_DEFAULT_RPC_ADDR)] + pub node_rpc_address: Url, + /// Address on which the miner will listen to + #[arg(short = 'a', long, default_value = SERVER_DEFAULT_BIND_ADDR)] + pub listen_addr: SocketAddr, +} + +impl RunCommand { + pub async fn handle(&self) -> Result<()> { + let state = Arc::new(RpcServerState { + start_time: Utc::now(), + }); + + let handle = start_rpc(state, self.listen_addr).await?; + let handle_clone = handle.clone(); + tokio::spawn(handle_clone.stopped()); + + // Monitor shutdown + tokio::signal::ctrl_c().await?; + let _ = handle.stop(); + + Ok(()) + } +} diff --git a/cli/polka-storage-provider/src/commands/run_rpc_cmd.rs b/cli/polka-storage-provider/src/commands/run_rpc_cmd.rs deleted file mode 100644 index ff6c1c2e9..000000000 --- a/cli/polka-storage-provider/src/commands/run_rpc_cmd.rs +++ /dev/null @@ -1,10 +0,0 @@ -use clap::Parser; -use url::Url; - -/// The `run-rpc` command used to run a server to listen for RPC calls. -#[derive(Debug, Clone, Parser)] -pub(crate) struct RunRpcCmd { - /// RPC API endpoint of the parachain node. - #[arg(short = 'n', long, default_value = "ws://127.0.0.1:9944")] - pub node_rpc_address: Url, -} diff --git a/cli/polka-storage-provider/src/commands/runner.rs b/cli/polka-storage-provider/src/commands/runner.rs index b1f892ca0..663998120 100644 --- a/cli/polka-storage-provider/src/commands/runner.rs +++ b/cli/polka-storage-provider/src/commands/runner.rs @@ -1,8 +1,8 @@ -use crate::cli::Subcommand; -use crate::Cli; use clap::Parser; use cli_primitives::Result; +use crate::{cli::SubCommand, Cli}; + /// Parses command line arguments into the service configuration and runs the specified /// command with it. pub(crate) async fn run() -> Result<()> { @@ -10,17 +10,12 @@ pub(crate) async fn run() -> Result<()> { let cli_arguments: Cli = Cli::parse(); match &cli_arguments.subcommand { - Some(Subcommand::RunRpc(_cmd)) => { - // TODO(@serhii, #52, 2024-05-28): Implement an RPC server to listen for RPC calls, which will be used by the UI app to display information to the user. - Ok(()) - } - Some(Subcommand::StopRpc(_cmd)) => { - // TODO(@serhii, #52, 2024-05-28): Implement functionality to gracefully stop the previously started RPC server. - Ok(()) - } + Some(SubCommand::Init(cmd)) => cmd.handle().await, + Some(SubCommand::Run(cmd)) => cmd.handle().await, + Some(SubCommand::Info(cmd)) => cmd.handle().await, None => { - // TODO(@serhii, #54, 2024-05-28): Add default logic for when no specific command is requested. - Ok(()) + // Help is shown if no subcommand is provided. + unreachable!() } } } diff --git a/cli/polka-storage-provider/src/commands/stop_rpc_cmd.rs b/cli/polka-storage-provider/src/commands/stop_rpc_cmd.rs deleted file mode 100644 index 0af211e2a..000000000 --- a/cli/polka-storage-provider/src/commands/stop_rpc_cmd.rs +++ /dev/null @@ -1,5 +0,0 @@ -use clap::Parser; - -/// The `stop-rpc` command used to stop a server that listen for RPC calls. -#[derive(Debug, Clone, Parser)] -pub(crate) struct StopRpcCmd {} diff --git a/cli/polka-storage-provider/src/main.rs b/cli/polka-storage-provider/src/main.rs index b744a8cd5..ad856f1b9 100644 --- a/cli/polka-storage-provider/src/main.rs +++ b/cli/polka-storage-provider/src/main.rs @@ -3,17 +3,17 @@ #![deny(unused_crate_dependencies)] mod cli; +mod rpc; pub(crate) mod commands; pub(crate) use cli::Cli; - use cli_primitives::Result; use commands::runner; #[tokio::main] async fn main() -> Result<()> { // Logger initialization. - env_logger::init(); + tracing_subscriber::fmt().init(); // Run requested command. runner::run().await diff --git a/cli/polka-storage-provider/src/rpc/methods/common.rs b/cli/polka-storage-provider/src/rpc/methods/common.rs new file mode 100644 index 000000000..ccaab179c --- /dev/null +++ b/cli/polka-storage-provider/src/rpc/methods/common.rs @@ -0,0 +1,18 @@ +use chrono::{DateTime, Utc}; +use jsonrpsee::types::{ErrorObjectOwned, Params}; + +use crate::rpc::reflect::{ApiVersion, Ctx, RpcMethod}; + +pub struct Info; + +impl RpcMethod for Info { + const NAME: &'static str = "info"; + + const API_VERSION: ApiVersion = ApiVersion::V0; + + type Ok = DateTime; + + async fn handle(ctx: Ctx, _params: Params<'_>) -> Result { + Ok(ctx.start_time) + } +} diff --git a/cli/polka-storage-provider/src/rpc/methods/mod.rs b/cli/polka-storage-provider/src/rpc/methods/mod.rs new file mode 100644 index 000000000..66c042959 --- /dev/null +++ b/cli/polka-storage-provider/src/rpc/methods/mod.rs @@ -0,0 +1,30 @@ +use std::sync::Arc; + +use jsonrpsee::RpcModule; + +use super::RpcServerState; +use crate::rpc::reflect::RpcMethod; + +pub mod common; + +/// The macro `callback` will be passed in each type that implements +/// [`RpcMethod`]. +/// +/// All methods should be entered here. +macro_rules! for_each_method { + ($callback:path) => { + // common + $callback!(common::Info); + }; +} + +pub fn create_module(state: Arc) -> RpcModule { + let mut module = RpcModule::from_arc(state); + macro_rules! register { + ($ty:ty) => { + <$ty>::register(&mut module).unwrap(); + }; + } + for_each_method!(register); + module +} diff --git a/cli/polka-storage-provider/src/rpc/mod.rs b/cli/polka-storage-provider/src/rpc/mod.rs new file mode 100644 index 000000000..bd78a37c0 --- /dev/null +++ b/cli/polka-storage-provider/src/rpc/mod.rs @@ -0,0 +1,27 @@ +use std::{net::SocketAddr, sync::Arc}; + +use chrono::Utc; +use jsonrpsee::server::{Server, ServerHandle}; +use methods::create_module; +use tracing::info; + +pub mod methods; +mod reflect; + +pub struct RpcServerState { + pub start_time: chrono::DateTime, +} + +pub async fn start_rpc( + state: Arc, + listen_addr: SocketAddr, +) -> cli_primitives::Result { + let server = Server::builder().build(listen_addr).await?; + + let module = create_module(state.clone()); + let server_handle = server.start(module); + + info!("RPC server started at {}", listen_addr); + + Ok(server_handle) +} diff --git a/cli/polka-storage-provider/src/rpc/reflect.rs b/cli/polka-storage-provider/src/rpc/reflect.rs new file mode 100644 index 000000000..b051130ad --- /dev/null +++ b/cli/polka-storage-provider/src/rpc/reflect.rs @@ -0,0 +1,55 @@ +use std::sync::Arc; + +use futures::Future; +use jsonrpsee::{ + types::{ErrorObjectOwned, Params}, + RpcModule, +}; +use serde::{Deserialize, Serialize}; + +use super::RpcServerState; + +/// Type to be used by [`RpcMethod::handle`]. +pub type Ctx = Arc; + +/// A definition of an RPC method handler which: +/// - can be [registered](RpcMethodExt::register) with an [`RpcModule`]. +pub trait RpcMethod { + /// Method name. + const NAME: &'static str; + /// See [`ApiVersion`]. + const API_VERSION: ApiVersion; + /// Return value of this method. + type Ok: Serialize; + + /// Logic for this method. + fn handle( + ctx: Ctx, + params: Params, + ) -> impl Future> + Send; + + /// Register this method with an [`RpcModule`]. + fn register( + module: &mut RpcModule, + ) -> Result<&mut jsonrpsee::MethodCallback, jsonrpsee::core::RegisterMethodError> + where + Self::Ok: Clone + 'static, + { + module.register_async_method(Self::NAME, move |params, ctx| async move { + let ok = Self::handle(ctx, params).await?; + Result::<_, jsonrpsee::types::ErrorObjectOwned>::Ok(ok) + }) + } +} + +/// Available API versions. +/// +/// These are significant because they are expressed in the URL path against +/// which RPC calls are made, e.g `rpc/v0` or `rpc/v1`. +/// +/// This information is important when using [`crate::rpc::client`]. +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] +pub enum ApiVersion { + V0, + V1, +} diff --git a/primitives/cli/Cargo.toml b/primitives/cli/Cargo.toml index 509aa41f7..4db5e395b 100644 --- a/primitives/cli/Cargo.toml +++ b/primitives/cli/Cargo.toml @@ -1,11 +1,11 @@ [package] -name = "cli-primitives" -version = "0.1.0" authors.workspace = true edition.workspace = true homepage.workspace = true license-file.workspace = true +name = "cli-primitives" repository.workspace = true +version = "0.1.0" [dependencies] thiserror = { workspace = true } diff --git a/primitives/cli/src/error.rs b/primitives/cli/src/error.rs index 2af15e7f2..2c4e20225 100644 --- a/primitives/cli/src/error.rs +++ b/primitives/cli/src/error.rs @@ -3,5 +3,7 @@ use thiserror::Error; /// CLI components error handling implementor. #[derive(Debug, Error)] pub enum Error { + #[error("IO error: {0}")] + IoError(#[from] std::io::Error), // TODO(@serhii, no-ref, 2024-05-28): Add and extend with error variants required in the `polka-storage` or `polka-storage-provider` crates. } From 7128aa6e2d1e64a4954b1a9a21020a97a8c99b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Tue, 4 Jun 2024 18:22:36 +0200 Subject: [PATCH 05/40] feat: wip calling parachain node --- Cargo.lock | 667 +++++++++++++++++- Cargo.toml | 6 +- cli/polka-storage-provider/Cargo.toml | 9 +- .../artifacts/metadata.scale | Bin 0 -> 116799 bytes .../src/commands/run.rs | 10 +- cli/polka-storage-provider/src/main.rs | 1 + cli/polka-storage-provider/src/polkadot.rs | 36 + .../src/rpc/methods/mod.rs | 3 + .../src/rpc/methods/wallet.rs | 23 + cli/polka-storage-provider/src/rpc/mod.rs | 3 + primitives/cli/Cargo.toml | 1 + primitives/cli/src/error.rs | 4 +- 12 files changed, 720 insertions(+), 43 deletions(-) create mode 100644 cli/polka-storage-provider/artifacts/metadata.scale create mode 100644 cli/polka-storage-provider/src/polkadot.rs create mode 100644 cli/polka-storage-provider/src/rpc/methods/wallet.rs diff --git a/Cargo.lock b/Cargo.lock index 4c155fc56..afaf0cd74 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -646,6 +646,17 @@ dependencies = [ "futures-lite 1.13.0", ] +[[package]] +name = "async-fs" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" +dependencies = [ + "async-lock 3.3.0", + "blocking", + "futures-lite 2.3.0", +] + [[package]] name = "async-io" version = "1.13.0" @@ -716,6 +727,17 @@ dependencies = [ "futures-lite 1.13.0", ] +[[package]] +name = "async-net" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" +dependencies = [ + "async-io 2.3.2", + "blocking", + "futures-lite 2.3.0", +] + [[package]] name = "async-process" version = "1.8.1" @@ -733,6 +755,26 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "async-process" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7eda79bbd84e29c2b308d1dc099d7de8dcc7035e48f4bf5dc4a531a44ff5e2a" +dependencies = [ + "async-channel 2.2.1", + "async-io 2.3.2", + "async-lock 3.3.0", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener 5.3.0", + "futures-lite 2.3.0", + "rustix 0.38.34", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "async-signal" version = "0.2.6" @@ -849,6 +891,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base58" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" + [[package]] name = "base64" version = "0.13.1" @@ -928,6 +976,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" dependencies = [ "bitcoin_hashes 0.11.0", + "serde", + "unicode-normalization", ] [[package]] @@ -1261,6 +1311,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chacha" version = "0.3.0" @@ -1395,7 +1451,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", "terminal_size", ] @@ -1421,6 +1477,7 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" name = "cli-primitives" version = "0.1.0" dependencies = [ + "subxt", "thiserror", ] @@ -2017,7 +2074,7 @@ dependencies = [ "sc-client-api", "scale-info", "sp-api", - "sp-crypto-hashing", + "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-inherents", "sp-runtime", "sp-state-machine", @@ -2408,8 +2465,8 @@ dependencies = [ "schnellru", "serde", "serde_json", - "smoldot", - "smoldot-light", + "smoldot 0.11.0", + "smoldot-light 0.9.0", "sp-api", "sp-authority-discovery", "sp-consensus-babe", @@ -2537,6 +2594,76 @@ dependencies = [ "syn 2.0.61", ] +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core 0.14.4", + "darling_macro 0.14.4", +] + +[[package]] +name = "darling" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +dependencies = [ + "darling_core 0.20.9", + "darling_macro 0.20.9", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 1.0.109", +] + +[[package]] +name = "darling_core" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.11.1", + "syn 2.0.61", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core 0.14.4", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +dependencies = [ + "darling_core 0.20.9", + "quote", + "syn 2.0.61", +] + [[package]] name = "dashmap" version = "5.5.3" @@ -2642,6 +2769,17 @@ dependencies = [ "syn 2.0.61", ] +[[package]] +name = "derive-where" +version = "1.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62d671cc41a825ebabc75757b62d3d168c577f9149b2d49ece1dad1f72119d25" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.61", +] + [[package]] name = "derive_more" version = "0.99.17" @@ -3269,6 +3407,16 @@ dependencies = [ "scale-info", ] +[[package]] +name = "finito" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2384245d85162258a14b43567a9ee3598f5ae746a1581fb5d3d2cb780f0dbf95" +dependencies = [ + "futures-timer", + "pin-project", +] + [[package]] name = "fixed-hash" version = "0.8.0" @@ -3473,6 +3621,17 @@ dependencies = [ "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", ] +[[package]] +name = "frame-metadata" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "878babb0b136e731cc77ec2fd883ff02745ff21e6fb662729953d44923df009c" +dependencies = [ + "cfg-if", + "parity-scale-codec", + "scale-info", +] + [[package]] name = "frame-metadata" version = "16.0.0" @@ -3495,7 +3654,7 @@ dependencies = [ "bitflags 1.3.2", "docify", "environmental", - "frame-metadata", + "frame-metadata 16.0.0", "frame-support-procedural", "impl-trait-for-tuples", "k256", @@ -3541,7 +3700,7 @@ dependencies = [ "proc-macro-warning", "proc-macro2", "quote", - "sp-crypto-hashing", + "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "syn 2.0.61", ] @@ -4272,6 +4431,12 @@ dependencies = [ "cc", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.2.3" @@ -5447,6 +5612,15 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" +[[package]] +name = "lru" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" +dependencies = [ + "hashbrown 0.14.5", +] + [[package]] name = "lru-cache" version = "0.1.2" @@ -7542,7 +7716,7 @@ dependencies = [ "memmap2 0.5.10", "parking_lot 0.12.2", "rand 0.8.5", - "siphasher", + "siphasher 0.3.11", "snap", "winapi", ] @@ -7888,6 +8062,8 @@ dependencies = [ "futures", "jsonrpsee", "serde", + "subxt", + "subxt-signer", "tokio", "tracing", "tracing-subscriber", @@ -8151,7 +8327,7 @@ dependencies = [ "sc-network-common", "sp-application-crypto", "sp-core", - "sp-crypto-hashing", + "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-keystore", "tracing-gum", ] @@ -8473,7 +8649,7 @@ dependencies = [ "sc-executor-wasmtime", "seccompiler", "sp-core", - "sp-crypto-hashing", + "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-io", "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", @@ -9708,6 +9884,22 @@ dependencies = [ "yasna", ] +[[package]] +name = "reconnecting-jsonrpsee-ws-client" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89cc4a6f1e641017e300c050f0c4c46a198627fb39ec03e7a028d20256b5e54" +dependencies = [ + "cfg_aliases 0.2.1", + "finito", + "futures", + "jsonrpsee", + "serde_json", + "thiserror", + "tokio", + "tracing", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -10293,6 +10485,17 @@ dependencies = [ "twox-hash", ] +[[package]] +name = "ruzstd" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c4eb8a81997cf040a091d1f7e1938aeab6749d3a0dfa73af43cdc32393483d" +dependencies = [ + "byteorder", + "derive_more", + "twox-hash", +] + [[package]] name = "rw-stream-sink" version = "0.3.0" @@ -10426,7 +10629,7 @@ dependencies = [ "serde_json", "sp-blockchain", "sp-core", - "sp-crypto-hashing", + "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-genesis-builder", "sp-io", "sp-runtime", @@ -10621,7 +10824,7 @@ dependencies = [ "sp-consensus-babe", "sp-consensus-slots", "sp-core", - "sp-crypto-hashing", + "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-inherents", "sp-keystore", "sp-runtime", @@ -10678,7 +10881,7 @@ dependencies = [ "sp-consensus", "sp-consensus-beefy", "sp-core", - "sp-crypto-hashing", + "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-keystore", "sp-mmr-primitives", "sp-runtime", @@ -10757,7 +10960,7 @@ dependencies = [ "sp-consensus", "sp-consensus-grandpa", "sp-core", - "sp-crypto-hashing", + "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-keystore", "sp-runtime", "substrate-prometheus-endpoint", @@ -11382,7 +11585,7 @@ dependencies = [ "serde", "serde_json", "sp-core", - "sp-crypto-hashing", + "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-io", "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", ] @@ -11467,7 +11670,7 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-core", - "sp-crypto-hashing", + "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-runtime", "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-transaction-pool", @@ -11506,6 +11709,73 @@ dependencies = [ "sp-arithmetic", ] +[[package]] +name = "scale-bits" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57b1e7f6b65ed1f04e79a85a57d755ad56d76fdf1e9bddcc9ae14f71fcdcf54" +dependencies = [ + "parity-scale-codec", + "scale-info", + "scale-type-resolver", + "serde", +] + +[[package]] +name = "scale-decode" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b12ebca36cec2a3f983c46295b282b35e5f8496346fb859a8776dad5389e5389" +dependencies = [ + "derive_more", + "parity-scale-codec", + "primitive-types", + "scale-bits", + "scale-decode-derive", + "scale-type-resolver", + "smallvec", +] + +[[package]] +name = "scale-decode-derive" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06a387a62a2be6ec532eb4f9e1fc800f26d462c06b335d9c3ee54559a355b9fb" +dependencies = [ + "darling 0.14.4", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "scale-encode" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ba0b9c48dc0eb20c60b083c29447c0c4617cb7c4a4c9fef72aa5c5bc539e15e" +dependencies = [ + "derive_more", + "parity-scale-codec", + "primitive-types", + "scale-bits", + "scale-encode-derive", + "scale-type-resolver", + "smallvec", +] + +[[package]] +name = "scale-encode-derive" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82ab7e60e2d9c8d47105f44527b26f04418e5e624ffc034f6b4a86c0ba19c5bf" +dependencies = [ + "darling 0.14.4", + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "scale-info" version = "2.11.3" @@ -11532,6 +11802,50 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "scale-type-resolver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0cded6518aa0bd6c1be2b88ac81bf7044992f0f154bfbabd5ad34f43512abcb" +dependencies = [ + "scale-info", + "smallvec", +] + +[[package]] +name = "scale-typegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498d1aecf2ea61325d4511787c115791639c0fd21ef4f8e11e49dd09eff2bbac" +dependencies = [ + "proc-macro2", + "quote", + "scale-info", + "syn 2.0.61", + "thiserror", +] + +[[package]] +name = "scale-value" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cf9738c263c665144177201126bdad39d3d62512152f178f35002228026976" +dependencies = [ + "base58", + "blake2 0.10.6", + "derive_more", + "either", + "frame-metadata 15.1.0", + "parity-scale-codec", + "scale-bits", + "scale-decode", + "scale-encode", + "scale-info", + "scale-type-resolver", + "serde", + "yap", +] + [[package]] name = "schannel" version = "0.1.23" @@ -11940,6 +12254,12 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + [[package]] name = "slab" version = "0.4.9" @@ -11990,15 +12310,32 @@ checksum = "13f2b548cd8447f8de0fdf1c592929f70f4fc7039a05e47404b0d096ec6987a1" dependencies = [ "async-channel 1.9.0", "async-executor", - "async-fs", + "async-fs 1.6.0", "async-io 1.13.0", "async-lock 2.8.0", - "async-net", - "async-process", + "async-net 1.8.0", + "async-process 1.8.1", "blocking", "futures-lite 1.13.0", ] +[[package]] +name = "smol" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e635339259e51ef85ac7aa29a1cd991b957047507288697a690e80ab97d07cad" +dependencies = [ + "async-channel 2.2.1", + "async-executor", + "async-fs 2.1.2", + "async-io 2.3.2", + "async-lock 3.3.0", + "async-net 2.0.0", + "async-process 2.2.3", + "blocking", + "futures-lite 2.3.0", +] + [[package]] name = "smoldot" version = "0.11.0" @@ -12037,13 +12374,68 @@ dependencies = [ "poly1305", "rand 0.8.5", "rand_chacha 0.3.1", - "ruzstd", + "ruzstd 0.4.0", "schnorrkel 0.10.2", "serde", "serde_json", "sha2 0.10.8", "sha3", - "siphasher", + "siphasher 0.3.11", + "slab", + "smallvec", + "soketto", + "twox-hash", + "wasmi", + "x25519-dalek 2.0.1", + "zeroize", +] + +[[package]] +name = "smoldot" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d1eaa97d77be4d026a1e7ffad1bb3b78448763b357ea6f8188d3e6f736a9b9" +dependencies = [ + "arrayvec 0.7.4", + "async-lock 3.3.0", + "atomic-take", + "base64 0.21.7", + "bip39", + "blake2-rfc", + "bs58 0.5.1", + "chacha20", + "crossbeam-queue", + "derive_more", + "ed25519-zebra 4.0.3", + "either", + "event-listener 4.0.3", + "fnv", + "futures-lite 2.3.0", + "futures-util", + "hashbrown 0.14.5", + "hex", + "hmac 0.12.1", + "itertools 0.12.1", + "libm", + "libsecp256k1", + "merlin", + "no-std-net", + "nom", + "num-bigint", + "num-rational", + "num-traits", + "pbkdf2", + "pin-project", + "poly1305", + "rand 0.8.5", + "rand_chacha 0.3.1", + "ruzstd 0.5.0", + "schnorrkel 0.11.4", + "serde", + "serde_json", + "sha2 0.10.8", + "sha3", + "siphasher 1.0.1", "slab", "smallvec", "soketto", @@ -12082,10 +12474,46 @@ dependencies = [ "rand_chacha 0.3.1", "serde", "serde_json", - "siphasher", + "siphasher 0.3.11", "slab", - "smol", - "smoldot", + "smol 1.3.0", + "smoldot 0.11.0", + "zeroize", +] + +[[package]] +name = "smoldot-light" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5496f2d116b7019a526b1039ec2247dd172b8670633b1a64a614c9ea12c9d8c7" +dependencies = [ + "async-channel 2.2.1", + "async-lock 3.3.0", + "base64 0.21.7", + "blake2-rfc", + "derive_more", + "either", + "event-listener 4.0.3", + "fnv", + "futures-channel", + "futures-lite 2.3.0", + "futures-util", + "hashbrown 0.14.5", + "hex", + "itertools 0.12.1", + "log", + "lru 0.12.3", + "no-std-net", + "parking_lot 0.12.2", + "pin-project", + "rand 0.8.5", + "rand_chacha 0.3.1", + "serde", + "serde_json", + "siphasher 1.0.1", + "slab", + "smol 2.0.0", + "smoldot 0.16.0", "zeroize", ] @@ -12332,7 +12760,7 @@ dependencies = [ "sp-api", "sp-application-crypto", "sp-core", - "sp-crypto-hashing", + "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-io", "sp-keystore", "sp-mmr-primitives", @@ -12401,7 +12829,7 @@ dependencies = [ "secp256k1", "secrecy", "serde", - "sp-crypto-hashing", + "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", @@ -12435,6 +12863,20 @@ dependencies = [ "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk)", ] +[[package]] +name = "sp-crypto-hashing" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc9927a7f81334ed5b8a98a4a978c81324d12bd9713ec76b5c68fd410174c5eb" +dependencies = [ + "blake2b_simd", + "byteorder", + "digest 0.10.7", + "sha2 0.10.8", + "sha3", + "twox-hash", +] + [[package]] name = "sp-crypto-hashing" version = "0.1.0" @@ -12454,7 +12896,7 @@ version = "0.1.0" source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0#0bb6249268c0b77d2834640b84cb52fdd3d7e860" dependencies = [ "quote", - "sp-crypto-hashing", + "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "syn 2.0.61", ] @@ -12546,7 +12988,7 @@ dependencies = [ "rustversion", "secp256k1", "sp-core", - "sp-crypto-hashing", + "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-keystore", "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", @@ -12593,7 +13035,7 @@ name = "sp-metadata-ir" version = "0.6.0" source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0#0bb6249268c0b77d2834640b84cb52fdd3d7e860" dependencies = [ - "frame-metadata", + "frame-metadata 16.0.0", "parity-scale-codec", "scale-info", ] @@ -12820,7 +13262,7 @@ dependencies = [ "sp-api", "sp-application-crypto", "sp-core", - "sp-crypto-hashing", + "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", "sp-runtime", "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.11.0)", @@ -13146,7 +13588,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a2a1c578e98c1c16fc3b8ec1328f7659a500737d7a0c6d625e73e830ff9c1f6" dependencies = [ "bitflags 1.3.2", - "cfg_aliases", + "cfg_aliases 0.1.1", "libc", "parking_lot 0.11.2", "parking_lot_core 0.8.6", @@ -13160,7 +13602,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70a2595fc3aa78f2d0e45dd425b22282dd863273761cc77780914b2cf3003acf" dependencies = [ - "cfg_aliases", + "cfg_aliases 0.1.1", "memchr", "proc-macro2", "quote", @@ -13200,6 +13642,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "strsim" version = "0.11.1" @@ -13349,6 +13797,157 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" +[[package]] +name = "subxt" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a160cba1edbf3ec4fbbeaea3f1a185f70448116a6bccc8276bb39adb3b3053bd" +dependencies = [ + "async-trait", + "derive-where", + "either", + "frame-metadata 16.0.0", + "futures", + "hex", + "impl-serde", + "instant", + "jsonrpsee", + "parity-scale-codec", + "primitive-types", + "reconnecting-jsonrpsee-ws-client", + "scale-bits", + "scale-decode", + "scale-encode", + "scale-info", + "scale-value", + "serde", + "serde_json", + "sp-crypto-hashing 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "subxt-core", + "subxt-lightclient", + "subxt-macro", + "subxt-metadata", + "thiserror", + "tokio-util", + "tracing", + "url", +] + +[[package]] +name = "subxt-codegen" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d703dca0905cc5272d7cc27a4ac5f37dcaae7671acc7fef0200057cc8c317786" +dependencies = [ + "frame-metadata 16.0.0", + "heck 0.5.0", + "hex", + "jsonrpsee", + "parity-scale-codec", + "proc-macro2", + "quote", + "scale-info", + "scale-typegen", + "subxt-metadata", + "syn 2.0.61", + "thiserror", + "tokio", +] + +[[package]] +name = "subxt-core" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59f41eb2e2eea6ed45649508cc735f92c27f1fcfb15229e75f8270ea73177345" +dependencies = [ + "base58", + "blake2 0.10.6", + "derive-where", + "frame-metadata 16.0.0", + "hashbrown 0.14.5", + "hex", + "impl-serde", + "parity-scale-codec", + "primitive-types", + "scale-bits", + "scale-decode", + "scale-encode", + "scale-info", + "scale-value", + "serde", + "serde_json", + "sp-crypto-hashing 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "subxt-metadata", + "tracing", +] + +[[package]] +name = "subxt-lightclient" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d9406fbdb9548c110803cb8afa750f8b911d51eefdf95474b11319591d225d9" +dependencies = [ + "futures", + "futures-util", + "serde", + "serde_json", + "smoldot-light 0.14.0", + "thiserror", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "subxt-macro" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c195f803d70687e409aba9be6c87115b5da8952cd83c4d13f2e043239818fcd" +dependencies = [ + "darling 0.20.9", + "parity-scale-codec", + "proc-macro-error", + "quote", + "scale-typegen", + "subxt-codegen", + "syn 2.0.61", +] + +[[package]] +name = "subxt-metadata" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "738be5890fdeff899bbffff4d9c0f244fe2a952fb861301b937e3aa40ebb55da" +dependencies = [ + "frame-metadata 16.0.0", + "hashbrown 0.14.5", + "parity-scale-codec", + "scale-info", + "sp-crypto-hashing 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "subxt-signer" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49888ae6ae90fe01b471193528eea5bd4ed52d8eecd2d13f4a2333b87388850" +dependencies = [ + "bip39", + "cfg-if", + "hex", + "hmac 0.12.1", + "parity-scale-codec", + "pbkdf2", + "regex", + "schnorrkel 0.11.4", + "secp256k1", + "secrecy", + "sha2 0.10.8", + "sp-crypto-hashing 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "subxt-core", + "zeroize", +] + [[package]] name = "syn" version = "1.0.109" @@ -15259,6 +15858,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "yap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4524214bc4629eba08d78ceb1d6507070cc0bcbbed23af74e19e6e924a24cf" + [[package]] name = "yasna" version = "0.5.2" diff --git a/Cargo.toml b/Cargo.toml index 1290c2d6f..325bed1a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ substrate-build-script-utils = { git = "https://github.com/paritytech/polkadot-s substrate-wasm-builder = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0" } async-trait = { version = "0.1.18" } +chrono = "0.4.38" clap = { version = "4.5.3" } codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } color-print = "0.3.4" @@ -54,7 +55,6 @@ tokio = { version = "^1" } tracing = "0.1.40" tracing-subscriber = { version = "0.3.18" } url = "2.5.0" -chrono = "0.4.38" # Local polka-storage-runtime = { path = "runtime" } @@ -98,9 +98,7 @@ substrate-prometheus-endpoint = { git = "https://github.com/paritytech/polkadot- # Polkadot pallet-xcm = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", default-features = false } -polkadot-cli = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", features = [ - "rococo-native", -] } +polkadot-cli = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", features = ["rococo-native"] } polkadot-parachain-primitives = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", default-features = false } polkadot-primitives = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0" } polkadot-runtime-common = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", default-features = false } diff --git a/cli/polka-storage-provider/Cargo.toml b/cli/polka-storage-provider/Cargo.toml index 6c5675c3b..3272890c7 100644 --- a/cli/polka-storage-provider/Cargo.toml +++ b/cli/polka-storage-provider/Cargo.toml @@ -9,17 +9,18 @@ version = "0.1.0" [dependencies] # async-trait = { workspace = true } +chrono = { workspace = true, features = ["serde"] } clap = { workspace = true, features = ["derive"] } cli-primitives = { path = "../../primitives/cli" } -chrono = { workspace = true, features = ["serde"] } +futures = "0.3.30" jsonrpsee = { workspace = true, features = ["full"] } +serde = { workspace = true } +subxt = { workspace = true } tokio = { workspace = true, features = ["full"] } tracing = { workspace = true } tracing-subscriber = { workspace = true } url = { workspace = true } -# subxt = { workspace = true } -serde = { workspace = true } -futures = "0.3.30" +subxt-signer = "0.37.0" [lints] workspace = true diff --git a/cli/polka-storage-provider/artifacts/metadata.scale b/cli/polka-storage-provider/artifacts/metadata.scale new file mode 100644 index 0000000000000000000000000000000000000000..edbf451d56e2f3d9114d950eaa3417400b70da29 GIT binary patch literal 116799 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 literal 0 HcmV?d00001 diff --git a/cli/polka-storage-provider/src/commands/run.rs b/cli/polka-storage-provider/src/commands/run.rs index 1ed0b63d3..540cd2da8 100644 --- a/cli/polka-storage-provider/src/commands/run.rs +++ b/cli/polka-storage-provider/src/commands/run.rs @@ -5,9 +5,10 @@ use clap::Parser; use cli_primitives::Result; use url::Url; -use crate::rpc::{start_rpc, RpcServerState}; - -// use crate::rpc::{RpcServerImpl, ServiceServer}; +use crate::{ + polkadot, + rpc::{start_rpc, RpcServerState}, +}; const SERVER_DEFAULT_BIND_ADDR: &str = "127.0.0.1:8000"; const SUBSTRATE_DEFAULT_RPC_ADDR: &str = "ws://127.0.0.1:9944"; @@ -24,8 +25,11 @@ pub(crate) struct RunCommand { impl RunCommand { pub async fn handle(&self) -> Result<()> { + let substrate_client = polkadot::init_client(self.node_rpc_address.as_str()).await?; + let state = Arc::new(RpcServerState { start_time: Utc::now(), + substrate_client, }); let handle = start_rpc(state, self.listen_addr).await?; diff --git a/cli/polka-storage-provider/src/main.rs b/cli/polka-storage-provider/src/main.rs index ad856f1b9..83d122eaf 100644 --- a/cli/polka-storage-provider/src/main.rs +++ b/cli/polka-storage-provider/src/main.rs @@ -3,6 +3,7 @@ #![deny(unused_crate_dependencies)] mod cli; +mod polkadot; mod rpc; pub(crate) mod commands; diff --git a/cli/polka-storage-provider/src/polkadot.rs b/cli/polka-storage-provider/src/polkadot.rs new file mode 100644 index 000000000..c44c9079f --- /dev/null +++ b/cli/polka-storage-provider/src/polkadot.rs @@ -0,0 +1,36 @@ +use polkadot::runtime_types::{frame_system::AccountInfo, pallet_balances::types::AccountData}; +use subxt::{utils::AccountId32, OnlineClient, PolkadotConfig}; +use tracing::info; + +#[subxt::subxt(runtime_metadata_path = "artifacts/metadata.scale")] +pub mod polkadot {} + +// PolkadotConfig or SubstrateConfig will suffice for this example at the moment, +// but PolkadotConfig is a little more correct, having the right `Address` type. +type Config = PolkadotConfig; + +/// Polkadot client type alias. +pub type Client = OnlineClient; + +/// Initialize a Polkadot client. +pub async fn init_client(url: impl AsRef) -> Result { + let inner = OnlineClient::::from_url(url).await?; + info!("Connection with parachain established."); + Ok(inner) +} + +pub async fn get_balance( + client: &Client, + account: &AccountId32, +) -> Result>>, cli_primitives::Error> { + let storage_query = polkadot::storage().system().account(account); + + let result = client + .storage() + .at_latest() + .await? + .fetch(&storage_query) + .await?; + + Ok(result) +} diff --git a/cli/polka-storage-provider/src/rpc/methods/mod.rs b/cli/polka-storage-provider/src/rpc/methods/mod.rs index 66c042959..07473547f 100644 --- a/cli/polka-storage-provider/src/rpc/methods/mod.rs +++ b/cli/polka-storage-provider/src/rpc/methods/mod.rs @@ -6,6 +6,7 @@ use super::RpcServerState; use crate::rpc::reflect::RpcMethod; pub mod common; +pub mod wallet; /// The macro `callback` will be passed in each type that implements /// [`RpcMethod`]. @@ -15,6 +16,8 @@ macro_rules! for_each_method { ($callback:path) => { // common $callback!(common::Info); + // wallet + $callback!(wallet::WalletBalance); }; } diff --git a/cli/polka-storage-provider/src/rpc/methods/wallet.rs b/cli/polka-storage-provider/src/rpc/methods/wallet.rs new file mode 100644 index 000000000..384e38c4c --- /dev/null +++ b/cli/polka-storage-provider/src/rpc/methods/wallet.rs @@ -0,0 +1,23 @@ +use jsonrpsee::types::{ErrorObjectOwned, Params}; +use subxt_signer::sr25519::dev; +use tracing::info; + +use crate::{ + polkadot::get_balance, + rpc::reflect::{ApiVersion, Ctx, RpcMethod}, +}; + +pub struct WalletBalance; +impl RpcMethod for WalletBalance { + const NAME: &'static str = "wallet_balance"; + const API_VERSION: ApiVersion = ApiVersion::V0; + + type Ok = String; + + async fn handle(ctx: Ctx, params: Params<'_>) -> Result { + let account = dev::alice().public_key().into(); + let balance = get_balance(&ctx.substrate_client, &account).await.unwrap(); + dbg!(balance); + todo!() + } +} diff --git a/cli/polka-storage-provider/src/rpc/mod.rs b/cli/polka-storage-provider/src/rpc/mod.rs index bd78a37c0..196076d31 100644 --- a/cli/polka-storage-provider/src/rpc/mod.rs +++ b/cli/polka-storage-provider/src/rpc/mod.rs @@ -5,11 +5,14 @@ use jsonrpsee::server::{Server, ServerHandle}; use methods::create_module; use tracing::info; +use crate::polkadot; + pub mod methods; mod reflect; pub struct RpcServerState { pub start_time: chrono::DateTime, + pub substrate_client: polkadot::Client, } pub async fn start_rpc( diff --git a/primitives/cli/Cargo.toml b/primitives/cli/Cargo.toml index 4db5e395b..4fa1fbaad 100644 --- a/primitives/cli/Cargo.toml +++ b/primitives/cli/Cargo.toml @@ -9,6 +9,7 @@ version = "0.1.0" [dependencies] thiserror = { workspace = true } +subxt = { workspace = true } [lints] workspace = true diff --git a/primitives/cli/src/error.rs b/primitives/cli/src/error.rs index 2c4e20225..27c3a8040 100644 --- a/primitives/cli/src/error.rs +++ b/primitives/cli/src/error.rs @@ -5,5 +5,7 @@ use thiserror::Error; pub enum Error { #[error("IO error: {0}")] IoError(#[from] std::io::Error), - // TODO(@serhii, no-ref, 2024-05-28): Add and extend with error variants required in the `polka-storage` or `polka-storage-provider` crates. + + #[error("Substrate error: {0}")] + Substrate(#[from] subxt::Error), } From a710f543b5653db7d71d62de19e32fd7e224cf71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Wed, 5 Jun 2024 09:48:46 +0200 Subject: [PATCH 06/40] fix: info rpc call --- .../src/rpc/methods/common.rs | 13 +++++++++++-- .../src/rpc/methods/wallet.rs | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/cli/polka-storage-provider/src/rpc/methods/common.rs b/cli/polka-storage-provider/src/rpc/methods/common.rs index ccaab179c..aaef752e1 100644 --- a/cli/polka-storage-provider/src/rpc/methods/common.rs +++ b/cli/polka-storage-provider/src/rpc/methods/common.rs @@ -1,8 +1,10 @@ use chrono::{DateTime, Utc}; use jsonrpsee::types::{ErrorObjectOwned, Params}; +use serde::{Deserialize, Serialize}; use crate::rpc::reflect::{ApiVersion, Ctx, RpcMethod}; +#[derive(Debug)] pub struct Info; impl RpcMethod for Info { @@ -10,9 +12,16 @@ impl RpcMethod for Info { const API_VERSION: ApiVersion = ApiVersion::V0; - type Ok = DateTime; + type Ok = InfoResult; async fn handle(ctx: Ctx, _params: Params<'_>) -> Result { - Ok(ctx.start_time) + Ok(InfoResult { + start_time: ctx.start_time, + }) } } + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct InfoResult { + pub start_time: DateTime, +} diff --git a/cli/polka-storage-provider/src/rpc/methods/wallet.rs b/cli/polka-storage-provider/src/rpc/methods/wallet.rs index 384e38c4c..08b1b507c 100644 --- a/cli/polka-storage-provider/src/rpc/methods/wallet.rs +++ b/cli/polka-storage-provider/src/rpc/methods/wallet.rs @@ -15,6 +15,7 @@ impl RpcMethod for WalletBalance { type Ok = String; async fn handle(ctx: Ctx, params: Params<'_>) -> Result { + // TODO(@cernicc,05/06/2024): Implement correctly. dev alice is used as a show case for now. let account = dev::alice().public_key().into(); let balance = get_balance(&ctx.substrate_client, &account).await.unwrap(); dbg!(balance); From e133d24f220f8c9c10300bbf87e142fe61650711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Wed, 5 Jun 2024 10:01:26 +0200 Subject: [PATCH 07/40] feat: change to newer moodule setup --- .../src/{commands/mod.rs => commands.rs} | 0 cli/polka-storage-provider/src/{rpc/mod.rs => rpc.rs} | 0 .../src/rpc/{methods/mod.rs => methods.rs} | 0 cli/polka-storage-provider/src/rpc/methods/wallet.rs | 3 +-- 4 files changed, 1 insertion(+), 2 deletions(-) rename cli/polka-storage-provider/src/{commands/mod.rs => commands.rs} (100%) rename cli/polka-storage-provider/src/{rpc/mod.rs => rpc.rs} (100%) rename cli/polka-storage-provider/src/rpc/{methods/mod.rs => methods.rs} (100%) diff --git a/cli/polka-storage-provider/src/commands/mod.rs b/cli/polka-storage-provider/src/commands.rs similarity index 100% rename from cli/polka-storage-provider/src/commands/mod.rs rename to cli/polka-storage-provider/src/commands.rs diff --git a/cli/polka-storage-provider/src/rpc/mod.rs b/cli/polka-storage-provider/src/rpc.rs similarity index 100% rename from cli/polka-storage-provider/src/rpc/mod.rs rename to cli/polka-storage-provider/src/rpc.rs diff --git a/cli/polka-storage-provider/src/rpc/methods/mod.rs b/cli/polka-storage-provider/src/rpc/methods.rs similarity index 100% rename from cli/polka-storage-provider/src/rpc/methods/mod.rs rename to cli/polka-storage-provider/src/rpc/methods.rs diff --git a/cli/polka-storage-provider/src/rpc/methods/wallet.rs b/cli/polka-storage-provider/src/rpc/methods/wallet.rs index 08b1b507c..685894d98 100644 --- a/cli/polka-storage-provider/src/rpc/methods/wallet.rs +++ b/cli/polka-storage-provider/src/rpc/methods/wallet.rs @@ -1,6 +1,5 @@ use jsonrpsee::types::{ErrorObjectOwned, Params}; use subxt_signer::sr25519::dev; -use tracing::info; use crate::{ polkadot::get_balance, @@ -14,7 +13,7 @@ impl RpcMethod for WalletBalance { type Ok = String; - async fn handle(ctx: Ctx, params: Params<'_>) -> Result { + async fn handle(ctx: Ctx, _params: Params<'_>) -> Result { // TODO(@cernicc,05/06/2024): Implement correctly. dev alice is used as a show case for now. let account = dev::alice().public_key().into(); let balance = get_balance(&ctx.substrate_client, &account).await.unwrap(); From 21f3ee8043e700fc1d22ccaf14636850ee71eb04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Wed, 5 Jun 2024 10:37:02 +0200 Subject: [PATCH 08/40] fix: use Feature trait from std --- Cargo.lock | 1 - Cargo.toml | 5 ++++- cli/polka-storage-provider/Cargo.toml | 3 +-- cli/polka-storage-provider/src/rpc/reflect.rs | 3 +-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index afaf0cd74..eba803dbb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8059,7 +8059,6 @@ dependencies = [ "chrono", "clap", "cli-primitives", - "futures", "jsonrpsee", "serde", "subxt", diff --git a/Cargo.toml b/Cargo.toml index 325bed1a5..a48b71e62 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,6 +49,7 @@ serde_json = { version = "1.0.114", default-features = false } serde_yaml = { version = "0.9" } smallvec = "1.11.0" subxt = { version = "0.37.0" } +subxt-signer = "0.37.0" syn = { version = "2.0.53" } thiserror = { version = "1.0.48" } tokio = { version = "^1" } @@ -98,7 +99,9 @@ substrate-prometheus-endpoint = { git = "https://github.com/paritytech/polkadot- # Polkadot pallet-xcm = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", default-features = false } -polkadot-cli = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", features = ["rococo-native"] } +polkadot-cli = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", features = [ + "rococo-native", +] } polkadot-parachain-primitives = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", default-features = false } polkadot-primitives = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0" } polkadot-runtime-common = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", default-features = false } diff --git a/cli/polka-storage-provider/Cargo.toml b/cli/polka-storage-provider/Cargo.toml index 3272890c7..766933ef3 100644 --- a/cli/polka-storage-provider/Cargo.toml +++ b/cli/polka-storage-provider/Cargo.toml @@ -12,7 +12,6 @@ version = "0.1.0" chrono = { workspace = true, features = ["serde"] } clap = { workspace = true, features = ["derive"] } cli-primitives = { path = "../../primitives/cli" } -futures = "0.3.30" jsonrpsee = { workspace = true, features = ["full"] } serde = { workspace = true } subxt = { workspace = true } @@ -20,7 +19,7 @@ tokio = { workspace = true, features = ["full"] } tracing = { workspace = true } tracing-subscriber = { workspace = true } url = { workspace = true } -subxt-signer = "0.37.0" +subxt-signer = { workspace = true } [lints] workspace = true diff --git a/cli/polka-storage-provider/src/rpc/reflect.rs b/cli/polka-storage-provider/src/rpc/reflect.rs index b051130ad..06c9fc92f 100644 --- a/cli/polka-storage-provider/src/rpc/reflect.rs +++ b/cli/polka-storage-provider/src/rpc/reflect.rs @@ -1,6 +1,5 @@ -use std::sync::Arc; +use std::{future::Future, sync::Arc}; -use futures::Future; use jsonrpsee::{ types::{ErrorObjectOwned, Params}, RpcModule, From 58286827161e45d08e8d71ebd54a8d50b466c60a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Wed, 5 Jun 2024 14:07:45 +0200 Subject: [PATCH 09/40] feat: wallet balance some changes --- .../src/rpc/methods/wallet.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/cli/polka-storage-provider/src/rpc/methods/wallet.rs b/cli/polka-storage-provider/src/rpc/methods/wallet.rs index 685894d98..e12276110 100644 --- a/cli/polka-storage-provider/src/rpc/methods/wallet.rs +++ b/cli/polka-storage-provider/src/rpc/methods/wallet.rs @@ -1,4 +1,5 @@ use jsonrpsee::types::{ErrorObjectOwned, Params}; +use serde::{Deserialize, Serialize}; use subxt_signer::sr25519::dev; use crate::{ @@ -11,13 +12,25 @@ impl RpcMethod for WalletBalance { const NAME: &'static str = "wallet_balance"; const API_VERSION: ApiVersion = ApiVersion::V0; - type Ok = String; + type Ok = Option; async fn handle(ctx: Ctx, _params: Params<'_>) -> Result { // TODO(@cernicc,05/06/2024): Implement correctly. dev alice is used as a show case for now. let account = dev::alice().public_key().into(); + // TODO(@cernicc,05/06/2024): Handle error. let balance = get_balance(&ctx.substrate_client, &account).await.unwrap(); - dbg!(balance); - todo!() + + Ok(balance.map(|balance| WalletBalanceResult { + free: balance.data.free.to_string(), + reserved: balance.data.reserved.to_string(), + frozen: balance.data.frozen.to_string(), + })) } } + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct WalletBalanceResult { + free: String, + reserved: String, + frozen: String, +} From b539fabc52bc339224f3f22c936472eb6b4fd966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Wed, 5 Jun 2024 15:26:01 +0200 Subject: [PATCH 10/40] chore: remove jsonrpsee unused features --- Cargo.lock | 83 +-------------------------- cli/polka-storage-provider/Cargo.toml | 3 +- 2 files changed, 2 insertions(+), 84 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eba803dbb..7e1d4f23b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3933,10 +3933,6 @@ name = "futures-timer" version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" -dependencies = [ - "gloo-timers", - "send_wrapper", -] [[package]] name = "futures-util" @@ -4064,52 +4060,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" -[[package]] -name = "gloo-net" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43aaa242d1239a8822c15c645f02166398da4f8b5c4bae795c1f5b44e9eee173" -dependencies = [ - "futures-channel", - "futures-core", - "futures-sink", - "gloo-utils", - "http", - "js-sys", - "pin-project", - "serde", - "serde_json", - "thiserror", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "gloo-utils" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" -dependencies = [ - "js-sys", - "serde", - "serde_json", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "governor" version = "0.6.3" @@ -4729,7 +4679,6 @@ dependencies = [ "jsonrpsee-proc-macros", "jsonrpsee-server", "jsonrpsee-types", - "jsonrpsee-wasm-client", "jsonrpsee-ws-client", "tokio", "tracing", @@ -4741,9 +4690,7 @@ version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4978087a58c3ab02efc5b07c5e5e2803024536106fd5506f558db172c889b3aa" dependencies = [ - "futures-channel", "futures-util", - "gloo-net", "http", "jsonrpsee-core", "pin-project", @@ -4756,7 +4703,6 @@ dependencies = [ "tokio-util", "tracing", "url", - "webpki-roots 0.26.1", ] [[package]] @@ -4782,7 +4728,6 @@ dependencies = [ "tokio", "tokio-stream", "tracing", - "wasm-bindgen-futures", ] [[package]] @@ -4855,17 +4800,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "jsonrpsee-wasm-client" -version = "0.22.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f448d8eacd945cc17b6c0b42c361531ca36a962ee186342a97cdb8fca679cd77" -dependencies = [ - "jsonrpsee-client-transport", - "jsonrpsee-core", - "jsonrpsee-types", -] - [[package]] name = "jsonrpsee-ws-client" version = "0.22.5" @@ -5363,7 +5297,7 @@ dependencies = [ "rw-stream-sink", "soketto", "url", - "webpki-roots 0.22.6", + "webpki-roots", ] [[package]] @@ -12035,12 +11969,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -[[package]] -name = "send_wrapper" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" - [[package]] name = "serde" version = "1.0.203" @@ -15284,15 +15212,6 @@ dependencies = [ "webpki", ] -[[package]] -name = "webpki-roots" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" -dependencies = [ - "rustls-pki-types", -] - [[package]] name = "westend-runtime" version = "7.0.0" diff --git a/cli/polka-storage-provider/Cargo.toml b/cli/polka-storage-provider/Cargo.toml index 766933ef3..578330849 100644 --- a/cli/polka-storage-provider/Cargo.toml +++ b/cli/polka-storage-provider/Cargo.toml @@ -8,11 +8,10 @@ repository.workspace = true version = "0.1.0" [dependencies] -# async-trait = { workspace = true } chrono = { workspace = true, features = ["serde"] } clap = { workspace = true, features = ["derive"] } cli-primitives = { path = "../../primitives/cli" } -jsonrpsee = { workspace = true, features = ["full"] } +jsonrpsee = { workspace = true, features = ["server"] } serde = { workspace = true } subxt = { workspace = true } tokio = { workspace = true, features = ["full"] } From 919e00ce312ea78ca48f11e06323804613374375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Wed, 5 Jun 2024 15:51:37 +0200 Subject: [PATCH 11/40] chore: polish --- Cargo.toml | 5 +---- cli/polka-storage-provider/Cargo.toml | 2 +- primitives/cli/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a48b71e62..ecbe8c7e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,6 @@ panic = 'abort' # Use abort on panic to reduce binary size substrate-build-script-utils = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0" } substrate-wasm-builder = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0" } -async-trait = { version = "0.1.18" } chrono = "0.4.38" clap = { version = "4.5.3" } codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } @@ -99,9 +98,7 @@ substrate-prometheus-endpoint = { git = "https://github.com/paritytech/polkadot- # Polkadot pallet-xcm = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", default-features = false } -polkadot-cli = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", features = [ - "rococo-native", -] } +polkadot-cli = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", features = ["rococo-native"] } polkadot-parachain-primitives = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", default-features = false } polkadot-primitives = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0" } polkadot-runtime-common = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0", default-features = false } diff --git a/cli/polka-storage-provider/Cargo.toml b/cli/polka-storage-provider/Cargo.toml index 578330849..a5f649755 100644 --- a/cli/polka-storage-provider/Cargo.toml +++ b/cli/polka-storage-provider/Cargo.toml @@ -14,11 +14,11 @@ cli-primitives = { path = "../../primitives/cli" } jsonrpsee = { workspace = true, features = ["server"] } serde = { workspace = true } subxt = { workspace = true } +subxt-signer = { workspace = true } tokio = { workspace = true, features = ["full"] } tracing = { workspace = true } tracing-subscriber = { workspace = true } url = { workspace = true } -subxt-signer = { workspace = true } [lints] workspace = true diff --git a/primitives/cli/Cargo.toml b/primitives/cli/Cargo.toml index 4fa1fbaad..25834b5d4 100644 --- a/primitives/cli/Cargo.toml +++ b/primitives/cli/Cargo.toml @@ -8,8 +8,8 @@ repository.workspace = true version = "0.1.0" [dependencies] -thiserror = { workspace = true } subxt = { workspace = true } +thiserror = { workspace = true } [lints] workspace = true From beb9174b475d6dccf5b546e6640bb8c498babb94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Wed, 5 Jun 2024 16:43:39 +0200 Subject: [PATCH 12/40] fix: remove optional for the subcommand --- cli/polka-storage-provider/src/cli.rs | 2 +- cli/polka-storage-provider/src/commands/runner.rs | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/cli/polka-storage-provider/src/cli.rs b/cli/polka-storage-provider/src/cli.rs index 6a75adaed..8b504f2e6 100644 --- a/cli/polka-storage-provider/src/cli.rs +++ b/cli/polka-storage-provider/src/cli.rs @@ -8,7 +8,7 @@ use crate::commands::{InfoCommand, InitCommand, RunCommand}; #[command(author, version, about, long_about = None, arg_required_else_help(true))] pub(crate) struct Cli { #[command(subcommand)] - pub subcommand: Option, + pub subcommand: SubCommand, } /// Supported sub-commands. diff --git a/cli/polka-storage-provider/src/commands/runner.rs b/cli/polka-storage-provider/src/commands/runner.rs index 663998120..db4395dcb 100644 --- a/cli/polka-storage-provider/src/commands/runner.rs +++ b/cli/polka-storage-provider/src/commands/runner.rs @@ -10,12 +10,8 @@ pub(crate) async fn run() -> Result<()> { let cli_arguments: Cli = Cli::parse(); match &cli_arguments.subcommand { - Some(SubCommand::Init(cmd)) => cmd.handle().await, - Some(SubCommand::Run(cmd)) => cmd.handle().await, - Some(SubCommand::Info(cmd)) => cmd.handle().await, - None => { - // Help is shown if no subcommand is provided. - unreachable!() - } + SubCommand::Init(cmd) => cmd.handle().await, + SubCommand::Run(cmd) => cmd.handle().await, + SubCommand::Info(cmd) => cmd.handle().await, } } From 17b12a56b39861207900974e87c6e87a94ff2cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Wed, 5 Jun 2024 17:26:04 +0200 Subject: [PATCH 13/40] fix: pr related suggestions --- Cargo.toml | 1 + cli/polka-storage-provider/Cargo.toml | 2 +- cli/polka-storage-provider/src/cli.rs | 2 +- cli/polka-storage-provider/src/commands/info.rs | 2 +- cli/polka-storage-provider/src/commands/init.rs | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ecbe8c7e4..9c357f46c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,6 +57,7 @@ tracing-subscriber = { version = "0.3.18" } url = "2.5.0" # Local +cli-primitives = { path = "primitives/cli" } polka-storage-runtime = { path = "runtime" } # Substrate diff --git a/cli/polka-storage-provider/Cargo.toml b/cli/polka-storage-provider/Cargo.toml index a5f649755..9f2ba6eff 100644 --- a/cli/polka-storage-provider/Cargo.toml +++ b/cli/polka-storage-provider/Cargo.toml @@ -10,7 +10,7 @@ version = "0.1.0" [dependencies] chrono = { workspace = true, features = ["serde"] } clap = { workspace = true, features = ["derive"] } -cli-primitives = { path = "../../primitives/cli" } +cli-primitives = { workspace = true } jsonrpsee = { workspace = true, features = ["server"] } serde = { workspace = true } subxt = { workspace = true } diff --git a/cli/polka-storage-provider/src/cli.rs b/cli/polka-storage-provider/src/cli.rs index 8b504f2e6..789c1ced2 100644 --- a/cli/polka-storage-provider/src/cli.rs +++ b/cli/polka-storage-provider/src/cli.rs @@ -5,7 +5,7 @@ use crate::commands::{InfoCommand, InitCommand, RunCommand}; /// A CLI application that facilitates management operations over a running full /// node and other components. #[derive(Parser, Debug, Clone)] -#[command(author, version, about, long_about = None, arg_required_else_help(true))] +#[command(author, version, about, long_about = None)] pub(crate) struct Cli { #[command(subcommand)] pub subcommand: SubCommand, diff --git a/cli/polka-storage-provider/src/commands/info.rs b/cli/polka-storage-provider/src/commands/info.rs index 44a0ffda1..b76e03c4f 100644 --- a/cli/polka-storage-provider/src/commands/info.rs +++ b/cli/polka-storage-provider/src/commands/info.rs @@ -7,6 +7,6 @@ pub(crate) struct InfoCommand {} impl InfoCommand { pub async fn handle(&self) -> Result<()> { // TODO(@cernicc,31/05/2024): Print providers information - Ok(()) + unimplemented!() } } diff --git a/cli/polka-storage-provider/src/commands/init.rs b/cli/polka-storage-provider/src/commands/init.rs index fc95126b5..ee54f6e9f 100644 --- a/cli/polka-storage-provider/src/commands/init.rs +++ b/cli/polka-storage-provider/src/commands/init.rs @@ -12,6 +12,6 @@ impl InitCommand { // TODO(@cernicc,31/05/2024): Check if full node is synced info!("Miner initialized successfully. Start it with `polka-storage-provider run`"); - Ok(()) + unimplemented!() } } From e948276fdc345a5f6325c8845e817b7e9a48f01a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Thu, 6 Jun 2024 10:40:23 +0200 Subject: [PATCH 14/40] feat: use EnvFilter --- cli/polka-storage-provider/src/main.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cli/polka-storage-provider/src/main.rs b/cli/polka-storage-provider/src/main.rs index 83d122eaf..784d598a9 100644 --- a/cli/polka-storage-provider/src/main.rs +++ b/cli/polka-storage-provider/src/main.rs @@ -10,11 +10,15 @@ pub(crate) mod commands; pub(crate) use cli::Cli; use cli_primitives::Result; use commands::runner; +use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; #[tokio::main] async fn main() -> Result<()> { // Logger initialization. - tracing_subscriber::fmt().init(); + tracing_subscriber::registry() + .with(fmt::layer()) + .with(EnvFilter::from_default_env()) + .init(); // Run requested command. runner::run().await From a9150675128b1c16d42b6fe836121bd5d01cca27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Thu, 6 Jun 2024 10:56:41 +0200 Subject: [PATCH 15/40] feat: remove macros --- cli/polka-storage-provider/src/main.rs | 9 ++- cli/polka-storage-provider/src/rpc.rs | 55 ++++++++++++++++++- cli/polka-storage-provider/src/rpc/methods.rs | 26 ++------- .../src/rpc/methods/common.rs | 2 +- .../src/rpc/methods/wallet.rs | 2 +- cli/polka-storage-provider/src/rpc/reflect.rs | 54 ------------------ 6 files changed, 66 insertions(+), 82 deletions(-) delete mode 100644 cli/polka-storage-provider/src/rpc/reflect.rs diff --git a/cli/polka-storage-provider/src/main.rs b/cli/polka-storage-provider/src/main.rs index 784d598a9..6b86e2ed1 100644 --- a/cli/polka-storage-provider/src/main.rs +++ b/cli/polka-storage-provider/src/main.rs @@ -3,13 +3,14 @@ #![deny(unused_crate_dependencies)] mod cli; +pub(crate) mod commands; mod polkadot; mod rpc; -pub(crate) mod commands; pub(crate) use cli::Cli; use cli_primitives::Result; use commands::runner; +use tracing::level_filters::LevelFilter; use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; #[tokio::main] @@ -17,7 +18,11 @@ async fn main() -> Result<()> { // Logger initialization. tracing_subscriber::registry() .with(fmt::layer()) - .with(EnvFilter::from_default_env()) + .with( + EnvFilter::builder() + .with_default_directive(LevelFilter::INFO.into()) + .from_env_lossy(), + ) .init(); // Run requested command. diff --git a/cli/polka-storage-provider/src/rpc.rs b/cli/polka-storage-provider/src/rpc.rs index 196076d31..84356c5f8 100644 --- a/cli/polka-storage-provider/src/rpc.rs +++ b/cli/polka-storage-provider/src/rpc.rs @@ -1,14 +1,63 @@ -use std::{net::SocketAddr, sync::Arc}; +use std::{future::Future, net::SocketAddr, sync::Arc}; use chrono::Utc; -use jsonrpsee::server::{Server, ServerHandle}; +use jsonrpsee::{ + server::{Server, ServerHandle}, + types::{ErrorObjectOwned, Params}, + RpcModule, +}; use methods::create_module; +use serde::{Deserialize, Serialize}; use tracing::info; use crate::polkadot; pub mod methods; -mod reflect; + +/// Type to be used by [`RpcMethod::handle`]. +pub type Ctx = Arc; + +/// A definition of an RPC method handler which: +/// - can be [registered](RpcMethodExt::register) with an [`RpcModule`]. +pub trait RpcMethod { + /// Method name. + const NAME: &'static str; + /// See [`ApiVersion`]. + const API_VERSION: ApiVersion; + /// Return value of this method. + type Ok: Serialize; + + /// Logic for this method. + fn handle( + ctx: Ctx, + params: Params, + ) -> impl Future> + Send; + + /// Register this method with an [`RpcModule`]. + fn register(module: &mut RpcModule) -> &mut jsonrpsee::MethodCallback + where + Self::Ok: Clone + 'static, + { + module + .register_async_method(Self::NAME, move |params, ctx| async move { + let ok = Self::handle(ctx, params).await?; + Result::<_, jsonrpsee::types::ErrorObjectOwned>::Ok(ok) + }) + .expect("method should be valid") // This is safe because we know the method registered is valid. + } +} + +/// Available API versions. +/// +/// These are significant because they are expressed in the URL path against +/// which RPC calls are made, e.g `rpc/v0` or `rpc/v1`. +/// +/// This information is important when using [`crate::rpc::client`]. +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] +pub enum ApiVersion { + V0, + V1, +} pub struct RpcServerState { pub start_time: chrono::DateTime, diff --git a/cli/polka-storage-provider/src/rpc/methods.rs b/cli/polka-storage-provider/src/rpc/methods.rs index 07473547f..6e6ee4376 100644 --- a/cli/polka-storage-provider/src/rpc/methods.rs +++ b/cli/polka-storage-provider/src/rpc/methods.rs @@ -2,32 +2,16 @@ use std::sync::Arc; use jsonrpsee::RpcModule; -use super::RpcServerState; -use crate::rpc::reflect::RpcMethod; +use super::{RpcMethod, RpcServerState}; pub mod common; pub mod wallet; -/// The macro `callback` will be passed in each type that implements -/// [`RpcMethod`]. -/// -/// All methods should be entered here. -macro_rules! for_each_method { - ($callback:path) => { - // common - $callback!(common::Info); - // wallet - $callback!(wallet::WalletBalance); - }; -} - pub fn create_module(state: Arc) -> RpcModule { let mut module = RpcModule::from_arc(state); - macro_rules! register { - ($ty:ty) => { - <$ty>::register(&mut module).unwrap(); - }; - } - for_each_method!(register); + + common::Info::register(&mut module); + wallet::WalletBalance::register(&mut module); + module } diff --git a/cli/polka-storage-provider/src/rpc/methods/common.rs b/cli/polka-storage-provider/src/rpc/methods/common.rs index aaef752e1..db1c03fd5 100644 --- a/cli/polka-storage-provider/src/rpc/methods/common.rs +++ b/cli/polka-storage-provider/src/rpc/methods/common.rs @@ -2,7 +2,7 @@ use chrono::{DateTime, Utc}; use jsonrpsee::types::{ErrorObjectOwned, Params}; use serde::{Deserialize, Serialize}; -use crate::rpc::reflect::{ApiVersion, Ctx, RpcMethod}; +use crate::rpc::{ApiVersion, Ctx, RpcMethod}; #[derive(Debug)] pub struct Info; diff --git a/cli/polka-storage-provider/src/rpc/methods/wallet.rs b/cli/polka-storage-provider/src/rpc/methods/wallet.rs index e12276110..b19f35679 100644 --- a/cli/polka-storage-provider/src/rpc/methods/wallet.rs +++ b/cli/polka-storage-provider/src/rpc/methods/wallet.rs @@ -4,7 +4,7 @@ use subxt_signer::sr25519::dev; use crate::{ polkadot::get_balance, - rpc::reflect::{ApiVersion, Ctx, RpcMethod}, + rpc::{ApiVersion, Ctx, RpcMethod}, }; pub struct WalletBalance; diff --git a/cli/polka-storage-provider/src/rpc/reflect.rs b/cli/polka-storage-provider/src/rpc/reflect.rs deleted file mode 100644 index 06c9fc92f..000000000 --- a/cli/polka-storage-provider/src/rpc/reflect.rs +++ /dev/null @@ -1,54 +0,0 @@ -use std::{future::Future, sync::Arc}; - -use jsonrpsee::{ - types::{ErrorObjectOwned, Params}, - RpcModule, -}; -use serde::{Deserialize, Serialize}; - -use super::RpcServerState; - -/// Type to be used by [`RpcMethod::handle`]. -pub type Ctx = Arc; - -/// A definition of an RPC method handler which: -/// - can be [registered](RpcMethodExt::register) with an [`RpcModule`]. -pub trait RpcMethod { - /// Method name. - const NAME: &'static str; - /// See [`ApiVersion`]. - const API_VERSION: ApiVersion; - /// Return value of this method. - type Ok: Serialize; - - /// Logic for this method. - fn handle( - ctx: Ctx, - params: Params, - ) -> impl Future> + Send; - - /// Register this method with an [`RpcModule`]. - fn register( - module: &mut RpcModule, - ) -> Result<&mut jsonrpsee::MethodCallback, jsonrpsee::core::RegisterMethodError> - where - Self::Ok: Clone + 'static, - { - module.register_async_method(Self::NAME, move |params, ctx| async move { - let ok = Self::handle(ctx, params).await?; - Result::<_, jsonrpsee::types::ErrorObjectOwned>::Ok(ok) - }) - } -} - -/// Available API versions. -/// -/// These are significant because they are expressed in the URL path against -/// which RPC calls are made, e.g `rpc/v0` or `rpc/v1`. -/// -/// This information is important when using [`crate::rpc::client`]. -#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] -pub enum ApiVersion { - V0, - V1, -} From 55644b579eccebf7b15b5e0d39f4689bfff27d8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Thu, 6 Jun 2024 11:10:56 +0200 Subject: [PATCH 16/40] fix: pr related changes --- cli/polka-storage-provider/src/commands/run.rs | 2 +- cli/polka-storage-provider/src/rpc.rs | 2 +- cli/polka-storage-provider/src/rpc/methods.rs | 4 ++-- cli/polka-storage-provider/src/rpc/methods/wallet.rs | 2 ++ 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/cli/polka-storage-provider/src/commands/run.rs b/cli/polka-storage-provider/src/commands/run.rs index 540cd2da8..026b1e0d7 100644 --- a/cli/polka-storage-provider/src/commands/run.rs +++ b/cli/polka-storage-provider/src/commands/run.rs @@ -18,7 +18,7 @@ pub(crate) struct RunCommand { /// RPC API endpoint of the parachain node #[arg(short = 'n', long, default_value = SUBSTRATE_DEFAULT_RPC_ADDR)] pub node_rpc_address: Url, - /// Address on which the miner will listen to + /// Address on which the storage provider will listen to #[arg(short = 'a', long, default_value = SERVER_DEFAULT_BIND_ADDR)] pub listen_addr: SocketAddr, } diff --git a/cli/polka-storage-provider/src/rpc.rs b/cli/polka-storage-provider/src/rpc.rs index 84356c5f8..bb98b827b 100644 --- a/cli/polka-storage-provider/src/rpc.rs +++ b/cli/polka-storage-provider/src/rpc.rs @@ -34,7 +34,7 @@ pub trait RpcMethod { ) -> impl Future> + Send; /// Register this method with an [`RpcModule`]. - fn register(module: &mut RpcModule) -> &mut jsonrpsee::MethodCallback + fn register_async(module: &mut RpcModule) -> &mut jsonrpsee::MethodCallback where Self::Ok: Clone + 'static, { diff --git a/cli/polka-storage-provider/src/rpc/methods.rs b/cli/polka-storage-provider/src/rpc/methods.rs index 6e6ee4376..e62f231b1 100644 --- a/cli/polka-storage-provider/src/rpc/methods.rs +++ b/cli/polka-storage-provider/src/rpc/methods.rs @@ -10,8 +10,8 @@ pub mod wallet; pub fn create_module(state: Arc) -> RpcModule { let mut module = RpcModule::from_arc(state); - common::Info::register(&mut module); - wallet::WalletBalance::register(&mut module); + common::Info::register_async(&mut module); + wallet::WalletBalance::register_async(&mut module); module } diff --git a/cli/polka-storage-provider/src/rpc/methods/wallet.rs b/cli/polka-storage-provider/src/rpc/methods/wallet.rs index b19f35679..19b65b34d 100644 --- a/cli/polka-storage-provider/src/rpc/methods/wallet.rs +++ b/cli/polka-storage-provider/src/rpc/methods/wallet.rs @@ -7,6 +7,8 @@ use crate::{ rpc::{ApiVersion, Ctx, RpcMethod}, }; +/// This RPC method exposes getting the system balances for the particular +/// account. pub struct WalletBalance; impl RpcMethod for WalletBalance { const NAME: &'static str = "wallet_balance"; From f157bb345a7650dfa8a5e6550ecfd24b12e8a046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Thu, 6 Jun 2024 13:20:22 +0200 Subject: [PATCH 17/40] feat: add rpc specific error type --- Cargo.lock | 1 + cli/polka-storage-provider/Cargo.toml | 1 + .../src/commands/run.rs | 4 +-- cli/polka-storage-provider/src/main.rs | 2 +- cli/polka-storage-provider/src/rpc.rs | 15 +++++---- cli/polka-storage-provider/src/rpc/error.rs | 32 +++++++++++++++++++ .../src/rpc/methods/common.rs | 6 ++-- .../src/rpc/methods/wallet.rs | 10 +++--- .../src/{polkadot.rs => substrate.rs} | 6 ++-- 9 files changed, 56 insertions(+), 21 deletions(-) create mode 100644 cli/polka-storage-provider/src/rpc/error.rs rename cli/polka-storage-provider/src/{polkadot.rs => substrate.rs} (85%) diff --git a/Cargo.lock b/Cargo.lock index 7e1d4f23b..0da9d6e40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7995,6 +7995,7 @@ dependencies = [ "cli-primitives", "jsonrpsee", "serde", + "serde_json", "subxt", "subxt-signer", "tokio", diff --git a/cli/polka-storage-provider/Cargo.toml b/cli/polka-storage-provider/Cargo.toml index 9f2ba6eff..dca070583 100644 --- a/cli/polka-storage-provider/Cargo.toml +++ b/cli/polka-storage-provider/Cargo.toml @@ -13,6 +13,7 @@ clap = { workspace = true, features = ["derive"] } cli-primitives = { workspace = true } jsonrpsee = { workspace = true, features = ["server"] } serde = { workspace = true } +serde_json = { workspace = true } subxt = { workspace = true } subxt-signer = { workspace = true } tokio = { workspace = true, features = ["full"] } diff --git a/cli/polka-storage-provider/src/commands/run.rs b/cli/polka-storage-provider/src/commands/run.rs index 026b1e0d7..c7ca6c60e 100644 --- a/cli/polka-storage-provider/src/commands/run.rs +++ b/cli/polka-storage-provider/src/commands/run.rs @@ -6,8 +6,8 @@ use cli_primitives::Result; use url::Url; use crate::{ - polkadot, rpc::{start_rpc, RpcServerState}, + substrate, }; const SERVER_DEFAULT_BIND_ADDR: &str = "127.0.0.1:8000"; @@ -25,7 +25,7 @@ pub(crate) struct RunCommand { impl RunCommand { pub async fn handle(&self) -> Result<()> { - let substrate_client = polkadot::init_client(self.node_rpc_address.as_str()).await?; + let substrate_client = substrate::init_client(self.node_rpc_address.as_str()).await?; let state = Arc::new(RpcServerState { start_time: Utc::now(), diff --git a/cli/polka-storage-provider/src/main.rs b/cli/polka-storage-provider/src/main.rs index 6b86e2ed1..4083768ba 100644 --- a/cli/polka-storage-provider/src/main.rs +++ b/cli/polka-storage-provider/src/main.rs @@ -4,8 +4,8 @@ mod cli; pub(crate) mod commands; -mod polkadot; mod rpc; +mod substrate; pub(crate) use cli::Cli; use cli_primitives::Result; diff --git a/cli/polka-storage-provider/src/rpc.rs b/cli/polka-storage-provider/src/rpc.rs index bb98b827b..3098ba9cf 100644 --- a/cli/polka-storage-provider/src/rpc.rs +++ b/cli/polka-storage-provider/src/rpc.rs @@ -1,37 +1,38 @@ use std::{future::Future, net::SocketAddr, sync::Arc}; use chrono::Utc; +use error::ServerError; use jsonrpsee::{ server::{Server, ServerHandle}, - types::{ErrorObjectOwned, Params}, + types::Params, RpcModule, }; use methods::create_module; use serde::{Deserialize, Serialize}; use tracing::info; -use crate::polkadot; +use crate::substrate; +pub mod error; pub mod methods; /// Type to be used by [`RpcMethod::handle`]. pub type Ctx = Arc; -/// A definition of an RPC method handler which: -/// - can be [registered](RpcMethodExt::register) with an [`RpcModule`]. +/// A definition of an RPC method handler which can be registered with an [`RpcModule`]. pub trait RpcMethod { /// Method name. const NAME: &'static str; /// See [`ApiVersion`]. const API_VERSION: ApiVersion; - /// Return value of this method. + /// Successful response type. type Ok: Serialize; /// Logic for this method. fn handle( ctx: Ctx, params: Params, - ) -> impl Future> + Send; + ) -> impl Future> + Send; /// Register this method with an [`RpcModule`]. fn register_async(module: &mut RpcModule) -> &mut jsonrpsee::MethodCallback @@ -61,7 +62,7 @@ pub enum ApiVersion { pub struct RpcServerState { pub start_time: chrono::DateTime, - pub substrate_client: polkadot::Client, + pub substrate_client: substrate::Client, } pub async fn start_rpc( diff --git a/cli/polka-storage-provider/src/rpc/error.rs b/cli/polka-storage-provider/src/rpc/error.rs new file mode 100644 index 000000000..6e5a8f353 --- /dev/null +++ b/cli/polka-storage-provider/src/rpc/error.rs @@ -0,0 +1,32 @@ +use std::fmt::Display; + +use jsonrpsee::types::{error::INTERNAL_ERROR_CODE, ErrorObjectOwned}; +use serde_json::Value; + +pub struct ServerError { + inner: ErrorObjectOwned, +} + +impl From for ErrorObjectOwned { + fn from(err: ServerError) -> Self { + err.inner + } +} + +impl ServerError { + pub fn new(code: i32, message: impl Display, data: impl Into>) -> Self { + Self { + inner: ErrorObjectOwned::owned(code, message.to_string(), data.into()), + } + } + + pub fn internal_error(message: impl Display, data: impl Into>) -> Self { + Self::new(INTERNAL_ERROR_CODE, message, data) + } +} + +impl From for ServerError { + fn from(err: subxt::Error) -> Self { + Self::internal_error(err, None) + } +} diff --git a/cli/polka-storage-provider/src/rpc/methods/common.rs b/cli/polka-storage-provider/src/rpc/methods/common.rs index db1c03fd5..06f5c190b 100644 --- a/cli/polka-storage-provider/src/rpc/methods/common.rs +++ b/cli/polka-storage-provider/src/rpc/methods/common.rs @@ -1,8 +1,8 @@ use chrono::{DateTime, Utc}; -use jsonrpsee::types::{ErrorObjectOwned, Params}; +use jsonrpsee::types::Params; use serde::{Deserialize, Serialize}; -use crate::rpc::{ApiVersion, Ctx, RpcMethod}; +use crate::rpc::{error::ServerError, ApiVersion, Ctx, RpcMethod}; #[derive(Debug)] pub struct Info; @@ -14,7 +14,7 @@ impl RpcMethod for Info { type Ok = InfoResult; - async fn handle(ctx: Ctx, _params: Params<'_>) -> Result { + async fn handle(ctx: Ctx, _params: Params<'_>) -> Result { Ok(InfoResult { start_time: ctx.start_time, }) diff --git a/cli/polka-storage-provider/src/rpc/methods/wallet.rs b/cli/polka-storage-provider/src/rpc/methods/wallet.rs index 19b65b34d..e65139f63 100644 --- a/cli/polka-storage-provider/src/rpc/methods/wallet.rs +++ b/cli/polka-storage-provider/src/rpc/methods/wallet.rs @@ -1,10 +1,10 @@ -use jsonrpsee::types::{ErrorObjectOwned, Params}; +use jsonrpsee::types::Params; use serde::{Deserialize, Serialize}; use subxt_signer::sr25519::dev; use crate::{ - polkadot::get_balance, - rpc::{ApiVersion, Ctx, RpcMethod}, + rpc::{error::ServerError, ApiVersion, Ctx, RpcMethod}, + substrate::get_balance, }; /// This RPC method exposes getting the system balances for the particular @@ -16,11 +16,11 @@ impl RpcMethod for WalletBalance { type Ok = Option; - async fn handle(ctx: Ctx, _params: Params<'_>) -> Result { + async fn handle(ctx: Ctx, _params: Params<'_>) -> Result { // TODO(@cernicc,05/06/2024): Implement correctly. dev alice is used as a show case for now. let account = dev::alice().public_key().into(); // TODO(@cernicc,05/06/2024): Handle error. - let balance = get_balance(&ctx.substrate_client, &account).await.unwrap(); + let balance = get_balance(&ctx.substrate_client, &account).await?; Ok(balance.map(|balance| WalletBalanceResult { free: balance.data.free.to_string(), diff --git a/cli/polka-storage-provider/src/polkadot.rs b/cli/polka-storage-provider/src/substrate.rs similarity index 85% rename from cli/polka-storage-provider/src/polkadot.rs rename to cli/polka-storage-provider/src/substrate.rs index c44c9079f..2f1b976ff 100644 --- a/cli/polka-storage-provider/src/polkadot.rs +++ b/cli/polka-storage-provider/src/substrate.rs @@ -1,5 +1,5 @@ use polkadot::runtime_types::{frame_system::AccountInfo, pallet_balances::types::AccountData}; -use subxt::{utils::AccountId32, OnlineClient, PolkadotConfig}; +use subxt::{utils::AccountId32, Error, OnlineClient, PolkadotConfig}; use tracing::info; #[subxt::subxt(runtime_metadata_path = "artifacts/metadata.scale")] @@ -13,7 +13,7 @@ type Config = PolkadotConfig; pub type Client = OnlineClient; /// Initialize a Polkadot client. -pub async fn init_client(url: impl AsRef) -> Result { +pub async fn init_client(url: impl AsRef) -> Result { let inner = OnlineClient::::from_url(url).await?; info!("Connection with parachain established."); Ok(inner) @@ -22,7 +22,7 @@ pub async fn init_client(url: impl AsRef) -> Result Result>>, cli_primitives::Error> { +) -> Result>>, Error> { let storage_query = polkadot::storage().system().account(account); let result = client From 49bc92c9a9339b3a87564aacc3168f9c8e433386 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Fri, 7 Jun 2024 09:09:40 +0200 Subject: [PATCH 18/40] fix: some docs --- cli/polka-storage-provider/Cargo.toml | 2 +- cli/polka-storage-provider/src/commands/info.rs | 1 + cli/polka-storage-provider/src/commands/init.rs | 1 + cli/polka-storage-provider/src/commands/run.rs | 1 + cli/polka-storage-provider/src/main.rs | 1 - cli/polka-storage-provider/src/rpc/error.rs | 1 + cli/polka-storage-provider/src/rpc/methods/common.rs | 1 + cli/polka-storage-provider/src/rpc/methods/wallet.rs | 4 ++-- cli/polka-storage-provider/src/substrate.rs | 3 ++- 9 files changed, 10 insertions(+), 5 deletions(-) diff --git a/cli/polka-storage-provider/Cargo.toml b/cli/polka-storage-provider/Cargo.toml index dca070583..862b0a581 100644 --- a/cli/polka-storage-provider/Cargo.toml +++ b/cli/polka-storage-provider/Cargo.toml @@ -18,7 +18,7 @@ subxt = { workspace = true } subxt-signer = { workspace = true } tokio = { workspace = true, features = ["full"] } tracing = { workspace = true } -tracing-subscriber = { workspace = true } +tracing-subscriber = { workspace = true, features = ["env-filter"] } url = { workspace = true } [lints] diff --git a/cli/polka-storage-provider/src/commands/info.rs b/cli/polka-storage-provider/src/commands/info.rs index b76e03c4f..fc8dbf502 100644 --- a/cli/polka-storage-provider/src/commands/info.rs +++ b/cli/polka-storage-provider/src/commands/info.rs @@ -1,6 +1,7 @@ use clap::Parser; use cli_primitives::Result; +/// Command to display information about the storage provider. #[derive(Debug, Clone, Parser)] pub(crate) struct InfoCommand {} diff --git a/cli/polka-storage-provider/src/commands/init.rs b/cli/polka-storage-provider/src/commands/init.rs index ee54f6e9f..507438197 100644 --- a/cli/polka-storage-provider/src/commands/init.rs +++ b/cli/polka-storage-provider/src/commands/init.rs @@ -2,6 +2,7 @@ use clap::Parser; use cli_primitives::Result; use tracing::info; +/// Command to initialize the storage provider.s #[derive(Debug, Clone, Parser)] pub(crate) struct InitCommand {} diff --git a/cli/polka-storage-provider/src/commands/run.rs b/cli/polka-storage-provider/src/commands/run.rs index c7ca6c60e..4d4166853 100644 --- a/cli/polka-storage-provider/src/commands/run.rs +++ b/cli/polka-storage-provider/src/commands/run.rs @@ -13,6 +13,7 @@ use crate::{ const SERVER_DEFAULT_BIND_ADDR: &str = "127.0.0.1:8000"; const SUBSTRATE_DEFAULT_RPC_ADDR: &str = "ws://127.0.0.1:9944"; +/// Command to start the storage provider. #[derive(Debug, Clone, Parser)] pub(crate) struct RunCommand { /// RPC API endpoint of the parachain node diff --git a/cli/polka-storage-provider/src/main.rs b/cli/polka-storage-provider/src/main.rs index 4083768ba..d8c22e561 100644 --- a/cli/polka-storage-provider/src/main.rs +++ b/cli/polka-storage-provider/src/main.rs @@ -1,5 +1,4 @@ //! A CLI application that facilitates management operations over a running full node and other components. - #![deny(unused_crate_dependencies)] mod cli; diff --git a/cli/polka-storage-provider/src/rpc/error.rs b/cli/polka-storage-provider/src/rpc/error.rs index 6e5a8f353..8c727085c 100644 --- a/cli/polka-storage-provider/src/rpc/error.rs +++ b/cli/polka-storage-provider/src/rpc/error.rs @@ -3,6 +3,7 @@ use std::fmt::Display; use jsonrpsee::types::{error::INTERNAL_ERROR_CODE, ErrorObjectOwned}; use serde_json::Value; +/// Error type for RPC server errors. pub struct ServerError { inner: ErrorObjectOwned, } diff --git a/cli/polka-storage-provider/src/rpc/methods/common.rs b/cli/polka-storage-provider/src/rpc/methods/common.rs index 06f5c190b..0164d9951 100644 --- a/cli/polka-storage-provider/src/rpc/methods/common.rs +++ b/cli/polka-storage-provider/src/rpc/methods/common.rs @@ -4,6 +4,7 @@ use serde::{Deserialize, Serialize}; use crate::rpc::{error::ServerError, ApiVersion, Ctx, RpcMethod}; +/// This RPC method exposes the system information. #[derive(Debug)] pub struct Info; diff --git a/cli/polka-storage-provider/src/rpc/methods/wallet.rs b/cli/polka-storage-provider/src/rpc/methods/wallet.rs index e65139f63..9b22ef4b8 100644 --- a/cli/polka-storage-provider/src/rpc/methods/wallet.rs +++ b/cli/polka-storage-provider/src/rpc/methods/wallet.rs @@ -4,7 +4,7 @@ use subxt_signer::sr25519::dev; use crate::{ rpc::{error::ServerError, ApiVersion, Ctx, RpcMethod}, - substrate::get_balance, + substrate::get_system_balances, }; /// This RPC method exposes getting the system balances for the particular @@ -20,7 +20,7 @@ impl RpcMethod for WalletBalance { // TODO(@cernicc,05/06/2024): Implement correctly. dev alice is used as a show case for now. let account = dev::alice().public_key().into(); // TODO(@cernicc,05/06/2024): Handle error. - let balance = get_balance(&ctx.substrate_client, &account).await?; + let balance = get_system_balances(&ctx.substrate_client, &account).await?; Ok(balance.map(|balance| WalletBalanceResult { free: balance.data.free.to_string(), diff --git a/cli/polka-storage-provider/src/substrate.rs b/cli/polka-storage-provider/src/substrate.rs index 2f1b976ff..5df0c639f 100644 --- a/cli/polka-storage-provider/src/substrate.rs +++ b/cli/polka-storage-provider/src/substrate.rs @@ -19,7 +19,8 @@ pub async fn init_client(url: impl AsRef) -> Result { Ok(inner) } -pub async fn get_balance( +/// Get system balances for the particular account. +pub async fn get_system_balances( client: &Client, account: &AccountId32, ) -> Result>>, Error> { From 0de7c22ac4e12eb2f75a63198ee4ed0d17018fd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Fri, 7 Jun 2024 16:22:38 +0200 Subject: [PATCH 19/40] fix: remove miner keyword --- cli/polka-storage-provider/src/cli.rs | 4 ++-- cli/polka-storage-provider/src/commands/init.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/polka-storage-provider/src/cli.rs b/cli/polka-storage-provider/src/cli.rs index 789c1ced2..87b87a44c 100644 --- a/cli/polka-storage-provider/src/cli.rs +++ b/cli/polka-storage-provider/src/cli.rs @@ -14,9 +14,9 @@ pub(crate) struct Cli { /// Supported sub-commands. #[derive(Debug, clap::Subcommand, Clone)] pub enum SubCommand { - /// Initialize the polka storage miner + /// Initialize the polka storage provider Init(InitCommand), - /// Start a polka storage miner + /// Start a polka storage provider Run(RunCommand), /// Info command Info(InfoCommand), diff --git a/cli/polka-storage-provider/src/commands/init.rs b/cli/polka-storage-provider/src/commands/init.rs index 507438197..69da6e169 100644 --- a/cli/polka-storage-provider/src/commands/init.rs +++ b/cli/polka-storage-provider/src/commands/init.rs @@ -8,10 +8,10 @@ pub(crate) struct InitCommand {} impl InitCommand { pub async fn handle(&self) -> Result<()> { - info!("Initializing polka storage miner..."); + info!("Initializing polka storage provider..."); // TODO(@cernicc,31/05/2024): Init needed configurations. // TODO(@cernicc,31/05/2024): Check if full node is synced - info!("Miner initialized successfully. Start it with `polka-storage-provider run`"); + info!("Provider initialized successfully. Start it with `polka-storage-provider run`"); unimplemented!() } From 0580838c72e75aec21ba6bf49fc3856028cd286b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Fri, 7 Jun 2024 16:33:18 +0200 Subject: [PATCH 20/40] fix: wait for the server to stop --- cli/polka-storage-provider/src/commands/run.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cli/polka-storage-provider/src/commands/run.rs b/cli/polka-storage-provider/src/commands/run.rs index 4d4166853..1a66425b8 100644 --- a/cli/polka-storage-provider/src/commands/run.rs +++ b/cli/polka-storage-provider/src/commands/run.rs @@ -35,12 +35,15 @@ impl RunCommand { let handle = start_rpc(state, self.listen_addr).await?; let handle_clone = handle.clone(); - tokio::spawn(handle_clone.stopped()); + let rpc_server_stopped = tokio::spawn(handle_clone.stopped()); // Monitor shutdown tokio::signal::ctrl_c().await?; let _ = handle.stop(); + // Wait for the server to stop + let _ = rpc_server_stopped.await; + Ok(()) } } From daab64940d48ca232c2a4b977628b8e9c9ca4ffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Fri, 7 Jun 2024 16:55:47 +0200 Subject: [PATCH 21/40] fix: impl Error for ServerError --- cli/polka-storage-provider/src/rpc/error.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cli/polka-storage-provider/src/rpc/error.rs b/cli/polka-storage-provider/src/rpc/error.rs index 8c727085c..c90aa5e0b 100644 --- a/cli/polka-storage-provider/src/rpc/error.rs +++ b/cli/polka-storage-provider/src/rpc/error.rs @@ -4,10 +4,19 @@ use jsonrpsee::types::{error::INTERNAL_ERROR_CODE, ErrorObjectOwned}; use serde_json::Value; /// Error type for RPC server errors. +#[derive(Debug)] pub struct ServerError { inner: ErrorObjectOwned, } +impl std::error::Error for ServerError {} + +impl Display for ServerError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "JSON-RPC error: {}", &self.inner) + } +} + impl From for ErrorObjectOwned { fn from(err: ServerError) -> Self { err.inner From 2cf213feef518ac21edfac9f6b86f526e0feace7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Fri, 7 Jun 2024 16:57:17 +0200 Subject: [PATCH 22/40] chore: remove todo comment --- cli/polka-storage-provider/src/rpc/methods/wallet.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/cli/polka-storage-provider/src/rpc/methods/wallet.rs b/cli/polka-storage-provider/src/rpc/methods/wallet.rs index 9b22ef4b8..0a93a7a2f 100644 --- a/cli/polka-storage-provider/src/rpc/methods/wallet.rs +++ b/cli/polka-storage-provider/src/rpc/methods/wallet.rs @@ -19,7 +19,6 @@ impl RpcMethod for WalletBalance { async fn handle(ctx: Ctx, _params: Params<'_>) -> Result { // TODO(@cernicc,05/06/2024): Implement correctly. dev alice is used as a show case for now. let account = dev::alice().public_key().into(); - // TODO(@cernicc,05/06/2024): Handle error. let balance = get_system_balances(&ctx.substrate_client, &account).await?; Ok(balance.map(|balance| WalletBalanceResult { From b07722829daa4a50788276c16e4ae5ddd6029d7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Fri, 7 Jun 2024 17:18:11 +0200 Subject: [PATCH 23/40] fix: fail if unknown directives for logger --- Cargo.lock | 1 + cli/polka-storage-provider/src/main.rs | 2 +- primitives/cli/Cargo.toml | 1 + primitives/cli/src/error.rs | 3 +++ 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 0da9d6e40..245107875 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1479,6 +1479,7 @@ version = "0.1.0" dependencies = [ "subxt", "thiserror", + "tracing-subscriber", ] [[package]] diff --git a/cli/polka-storage-provider/src/main.rs b/cli/polka-storage-provider/src/main.rs index d8c22e561..615f87c8f 100644 --- a/cli/polka-storage-provider/src/main.rs +++ b/cli/polka-storage-provider/src/main.rs @@ -20,7 +20,7 @@ async fn main() -> Result<()> { .with( EnvFilter::builder() .with_default_directive(LevelFilter::INFO.into()) - .from_env_lossy(), + .from_env()?, ) .init(); diff --git a/primitives/cli/Cargo.toml b/primitives/cli/Cargo.toml index 25834b5d4..966dd9ac2 100644 --- a/primitives/cli/Cargo.toml +++ b/primitives/cli/Cargo.toml @@ -10,6 +10,7 @@ version = "0.1.0" [dependencies] subxt = { workspace = true } thiserror = { workspace = true } +tracing-subscriber = { workspace = true } [lints] workspace = true diff --git a/primitives/cli/src/error.rs b/primitives/cli/src/error.rs index 27c3a8040..c1e9c000b 100644 --- a/primitives/cli/src/error.rs +++ b/primitives/cli/src/error.rs @@ -6,6 +6,9 @@ pub enum Error { #[error("IO error: {0}")] IoError(#[from] std::io::Error), + #[error("FromEnv error: {0}")] + EnvError(#[from] tracing_subscriber::filter::FromEnvError), + #[error("Substrate error: {0}")] Substrate(#[from] subxt::Error), } From 00e0adfef7b86fe08b7fc48580d7048870562132 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Fri, 7 Jun 2024 17:50:01 +0200 Subject: [PATCH 24/40] chore: add comment --- cli/polka-storage-provider/src/commands/info.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cli/polka-storage-provider/src/commands/info.rs b/cli/polka-storage-provider/src/commands/info.rs index fc8dbf502..fc1257044 100644 --- a/cli/polka-storage-provider/src/commands/info.rs +++ b/cli/polka-storage-provider/src/commands/info.rs @@ -7,7 +7,8 @@ pub(crate) struct InfoCommand {} impl InfoCommand { pub async fn handle(&self) -> Result<()> { - // TODO(@cernicc,31/05/2024): Print providers information + // TODO(@cernicc,31/05/2024): Print start time of the provider + // TODO(@cernicc,07/06/2024): Print address used by the provider unimplemented!() } } From 82f55d38f70cf81cbc9b9e158e282fed45306198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Fri, 7 Jun 2024 17:52:59 +0200 Subject: [PATCH 25/40] chore: small change to the commit --- cli/polka-storage-provider/src/commands/info.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/polka-storage-provider/src/commands/info.rs b/cli/polka-storage-provider/src/commands/info.rs index fc1257044..c9d7ba4f3 100644 --- a/cli/polka-storage-provider/src/commands/info.rs +++ b/cli/polka-storage-provider/src/commands/info.rs @@ -8,7 +8,7 @@ pub(crate) struct InfoCommand {} impl InfoCommand { pub async fn handle(&self) -> Result<()> { // TODO(@cernicc,31/05/2024): Print start time of the provider - // TODO(@cernicc,07/06/2024): Print address used by the provider + // TODO(@cernicc,07/06/2024): Print polkadot address used by the provider unimplemented!() } } From 3dd75a95f6b148ea9858f0884ff1ae3c5355ecad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Mon, 10 Jun 2024 09:55:51 +0200 Subject: [PATCH 26/40] fix: add issue numbers --- cli/polka-storage-provider/src/commands/info.rs | 4 ++-- cli/polka-storage-provider/src/commands/init.rs | 6 +++--- cli/polka-storage-provider/src/rpc/methods/wallet.rs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cli/polka-storage-provider/src/commands/info.rs b/cli/polka-storage-provider/src/commands/info.rs index c9d7ba4f3..e71add1a6 100644 --- a/cli/polka-storage-provider/src/commands/info.rs +++ b/cli/polka-storage-provider/src/commands/info.rs @@ -7,8 +7,8 @@ pub(crate) struct InfoCommand {} impl InfoCommand { pub async fn handle(&self) -> Result<()> { - // TODO(@cernicc,31/05/2024): Print start time of the provider - // TODO(@cernicc,07/06/2024): Print polkadot address used by the provider + // TODO(#66,@cernicc,31/05/2024): Print start time of the provider + // TODO(#67,@cernicc,07/06/2024): Print polkadot address used by the provider unimplemented!() } } diff --git a/cli/polka-storage-provider/src/commands/init.rs b/cli/polka-storage-provider/src/commands/init.rs index 69da6e169..91cb96af7 100644 --- a/cli/polka-storage-provider/src/commands/init.rs +++ b/cli/polka-storage-provider/src/commands/init.rs @@ -2,15 +2,15 @@ use clap::Parser; use cli_primitives::Result; use tracing::info; -/// Command to initialize the storage provider.s +/// Command to initialize the storage provider. #[derive(Debug, Clone, Parser)] pub(crate) struct InitCommand {} impl InitCommand { pub async fn handle(&self) -> Result<()> { info!("Initializing polka storage provider..."); - // TODO(@cernicc,31/05/2024): Init needed configurations. - // TODO(@cernicc,31/05/2024): Check if full node is synced + // TODO(#64,@cernicc,31/05/2024): Init needed configurations. + // TODO(#65,@cernicc,31/05/2024): Check if full node is synced info!("Provider initialized successfully. Start it with `polka-storage-provider run`"); unimplemented!() diff --git a/cli/polka-storage-provider/src/rpc/methods/wallet.rs b/cli/polka-storage-provider/src/rpc/methods/wallet.rs index 0a93a7a2f..4978a2f18 100644 --- a/cli/polka-storage-provider/src/rpc/methods/wallet.rs +++ b/cli/polka-storage-provider/src/rpc/methods/wallet.rs @@ -17,7 +17,7 @@ impl RpcMethod for WalletBalance { type Ok = Option; async fn handle(ctx: Ctx, _params: Params<'_>) -> Result { - // TODO(@cernicc,05/06/2024): Implement correctly. dev alice is used as a show case for now. + // TODO(#68,@cernicc,05/06/2024): Implement correctly. dev alice is used as a show case for now. let account = dev::alice().public_key().into(); let balance = get_system_balances(&ctx.substrate_client, &account).await?; From 0084091227c455a636acbadc36511fccee1e3651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Mon, 10 Jun 2024 10:03:42 +0200 Subject: [PATCH 27/40] fix: remove loger channels --- primitives/cli/src/lib.rs | 2 -- primitives/cli/src/logger.rs | 12 ------------ 2 files changed, 14 deletions(-) delete mode 100644 primitives/cli/src/logger.rs diff --git a/primitives/cli/src/lib.rs b/primitives/cli/src/lib.rs index b0c27e2ce..87d718e1f 100644 --- a/primitives/cli/src/lib.rs +++ b/primitives/cli/src/lib.rs @@ -3,7 +3,5 @@ mod error; mod result; -pub mod logger; - pub use error::Error; pub use result::Result; diff --git a/primitives/cli/src/logger.rs b/primitives/cli/src/logger.rs deleted file mode 100644 index f75a2922c..000000000 --- a/primitives/cli/src/logger.rs +++ /dev/null @@ -1,12 +0,0 @@ -/// Statically defined logging channels names (targets). -#[derive(Debug, Copy, Clone)] -pub enum Channel { - // TODO(@serhii, no-ref, 2024-05-28): Add and extend with error variants required in the `polka-storage` or `polka-storage-provider` crates. -} - -impl AsRef for Channel { - fn as_ref(&self) -> &str { - // TODO(@serhii, no-ref, 2024-05-28): Add and extend with error variants required in the `polka-storage` or `polka-storage-provider` crates. - todo!() - } -} From 8eab2bec11ff84f13604332eca4d0023358fa7f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Mon, 10 Jun 2024 10:49:54 +0200 Subject: [PATCH 28/40] chore: removed v1 version --- cli/polka-storage-provider/src/rpc.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/cli/polka-storage-provider/src/rpc.rs b/cli/polka-storage-provider/src/rpc.rs index 3098ba9cf..3e376f202 100644 --- a/cli/polka-storage-provider/src/rpc.rs +++ b/cli/polka-storage-provider/src/rpc.rs @@ -57,7 +57,6 @@ pub trait RpcMethod { #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] pub enum ApiVersion { V0, - V1, } pub struct RpcServerState { From 00d229282d32d77e87721c93305a4ae5aa440562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Mon, 10 Jun 2024 13:26:36 +0200 Subject: [PATCH 29/40] fix: change some comments --- cli/polka-storage-provider/src/commands/run.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/polka-storage-provider/src/commands/run.rs b/cli/polka-storage-provider/src/commands/run.rs index 1a66425b8..9dbb7bafd 100644 --- a/cli/polka-storage-provider/src/commands/run.rs +++ b/cli/polka-storage-provider/src/commands/run.rs @@ -11,15 +11,15 @@ use crate::{ }; const SERVER_DEFAULT_BIND_ADDR: &str = "127.0.0.1:8000"; -const SUBSTRATE_DEFAULT_RPC_ADDR: &str = "ws://127.0.0.1:9944"; +const FULL_NODE_DEFAULT_RPC_ADDR: &str = "ws://127.0.0.1:9944"; /// Command to start the storage provider. #[derive(Debug, Clone, Parser)] pub(crate) struct RunCommand { - /// RPC API endpoint of the parachain node - #[arg(short = 'n', long, default_value = SUBSTRATE_DEFAULT_RPC_ADDR)] + /// RPC API endpoint used by the parachain node + #[arg(short = 'n', long, default_value = FULL_NODE_DEFAULT_RPC_ADDR)] pub node_rpc_address: Url, - /// Address on which the storage provider will listen to + /// Address used for RPC. By default binds on localhost on port 8000 #[arg(short = 'a', long, default_value = SERVER_DEFAULT_BIND_ADDR)] pub listen_addr: SocketAddr, } From 8a9f5b9473d086728dc48a7b9f7cf76f2888c357 Mon Sep 17 00:00:00 2001 From: Serhii Temchenko Date: Tue, 11 Jun 2024 07:36:59 -0700 Subject: [PATCH 30/40] feat(polka-storage-provider): Added wallet functionality --- Cargo.lock | 2 ++ Cargo.toml | 4 +-- cli/polka-storage-provider/Cargo.toml | 9 ++--- cli/polka-storage-provider/src/cli.rs | 9 +++-- cli/polka-storage-provider/src/commands.rs | 2 ++ .../src/commands/runner.rs | 10 ++++++ .../src/commands/wallet_cmd.rs | 36 +++++++++++++++++++ primitives/cli/Cargo.toml | 5 +-- primitives/cli/src/error.rs | 3 +- 9 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 cli/polka-storage-provider/src/commands/wallet_cmd.rs diff --git a/Cargo.lock b/Cargo.lock index d9749f765..0a57e1971 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1420,6 +1420,7 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" name = "cli-primitives" version = "0.1.0" dependencies = [ + "sc-cli", "thiserror", ] @@ -7819,6 +7820,7 @@ dependencies = [ "clap", "cli-primitives", "env_logger 0.11.3", + "sc-cli", "tokio", "url", ] diff --git a/Cargo.toml b/Cargo.toml index 25b3fcb01..90a65d8e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,7 @@ substrate-wasm-builder = { git = "https://github.com/paritytech/polkadot-sdk", t clap = { version = "4.5.3" } codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } color-print = "0.3.4" +env_logger = "0.11.2" futures = "0.3.28" hex-literal = { version = "0.4.1" } jsonrpsee = { version = "0.22" } @@ -48,10 +49,9 @@ serde_yaml = { version = "0.9" } smallvec = "1.11.0" syn = { version = "2.0.53" } thiserror = { version = "1.0.48" } +tokio = { version = "^1" } tracing-subscriber = { version = "0.3.18" } url = "2.5.0" -env_logger = "0.11.2" -tokio = { version = "^1" } # Local polka-storage-runtime = { path = "runtime" } diff --git a/cli/polka-storage-provider/Cargo.toml b/cli/polka-storage-provider/Cargo.toml index c6db0150a..cb373a937 100644 --- a/cli/polka-storage-provider/Cargo.toml +++ b/cli/polka-storage-provider/Cargo.toml @@ -1,18 +1,19 @@ [package] -name = "polka-storage-provider" -version = "0.1.0" authors.workspace = true edition.workspace = true homepage.workspace = true license-file.workspace = true +name = "polka-storage-provider" repository.workspace = true +version = "0.1.0" [dependencies] -cli-primitives = { path = "../../primitives/cli" } clap = { workspace = true, features = ["derive"] } -url = { workspace = true } +cli-primitives = { path = "../../primitives/cli" } env_logger = { workspace = true } +sc-cli = { workspace = true } tokio = { workspace = true, features = ["full"] } +url = { workspace = true } [lints] workspace = true diff --git a/cli/polka-storage-provider/src/cli.rs b/cli/polka-storage-provider/src/cli.rs index eb20f3af7..45648bff1 100644 --- a/cli/polka-storage-provider/src/cli.rs +++ b/cli/polka-storage-provider/src/cli.rs @@ -1,8 +1,8 @@ -use crate::commands::{RunRpcCmd, StopRpcCmd}; +use crate::commands::{RunRpcCmd, StopRpcCmd, WalletCmd}; use clap::Parser; /// A CLI application that facilitates management operations over a running full node and other components. -#[derive(Parser, Debug, Clone)] +#[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] pub(crate) struct Cli { #[command(subcommand)] @@ -10,10 +10,13 @@ pub(crate) struct Cli { } /// Supported sub-commands. -#[derive(Debug, clap::Subcommand, Clone)] +#[derive(Debug, clap::Subcommand)] pub enum Subcommand { /// Command to run the RPC server. RunRpc(RunRpcCmd), /// Command to stop the RPC server. StopRpc(StopRpcCmd), + /// Command to manage wallet operations. + #[command(subcommand)] + Wallet(WalletCmd), } diff --git a/cli/polka-storage-provider/src/commands.rs b/cli/polka-storage-provider/src/commands.rs index c1e77c298..886333f02 100644 --- a/cli/polka-storage-provider/src/commands.rs +++ b/cli/polka-storage-provider/src/commands.rs @@ -1,7 +1,9 @@ mod run_rpc_cmd; mod stop_rpc_cmd; +mod wallet_cmd; pub(crate) mod runner; pub(crate) use run_rpc_cmd::RunRpcCmd; pub(crate) use stop_rpc_cmd::StopRpcCmd; +pub(crate) use wallet_cmd::WalletCmd; diff --git a/cli/polka-storage-provider/src/commands/runner.rs b/cli/polka-storage-provider/src/commands/runner.rs index b1f892ca0..35c829a2c 100644 --- a/cli/polka-storage-provider/src/commands/runner.rs +++ b/cli/polka-storage-provider/src/commands/runner.rs @@ -1,4 +1,5 @@ use crate::cli::Subcommand; +use crate::commands::WalletCmd; use crate::Cli; use clap::Parser; use cli_primitives::Result; @@ -18,6 +19,15 @@ pub(crate) async fn run() -> Result<()> { // TODO(@serhii, #52, 2024-05-28): Implement functionality to gracefully stop the previously started RPC server. Ok(()) } + Some(Subcommand::Wallet(cmd)) => match cmd { + WalletCmd::GenerateNodeKey(cmd) => Ok(cmd.run()?), + WalletCmd::Generate(cmd) => Ok(cmd.run()?), + WalletCmd::Inspect(cmd) => Ok(cmd.run()?), + WalletCmd::InspectNodeKey(cmd) => Ok(cmd.run()?), + WalletCmd::Vanity(cmd) => Ok(cmd.run()?), + WalletCmd::Verify(cmd) => Ok(cmd.run()?), + WalletCmd::Sign(cmd) => Ok(cmd.run()?), + }, None => { // TODO(@serhii, #54, 2024-05-28): Add default logic for when no specific command is requested. Ok(()) diff --git a/cli/polka-storage-provider/src/commands/wallet_cmd.rs b/cli/polka-storage-provider/src/commands/wallet_cmd.rs new file mode 100644 index 000000000..0261c2754 --- /dev/null +++ b/cli/polka-storage-provider/src/commands/wallet_cmd.rs @@ -0,0 +1,36 @@ +use clap::Parser; +use sc_cli::{ + GenerateCmd, GenerateKeyCmdCommon, InspectKeyCmd, InspectNodeKeyCmd, SignCmd, VanityCmd, + VerifyCmd, +}; + +/// Wallet sub-commands. +#[derive(Debug, Parser)] +#[command( + name = "wallet", + about = "Utility for generating and restoring keys", + version +)] +pub enum WalletCmd { + /// Generate a random node key, write it to a file or stdout and write the + /// corresponding peer-id to stderr + GenerateNodeKey(GenerateKeyCmdCommon), + + /// Generate a random account + Generate(GenerateCmd), + + /// Gets a public key and a SS58 address from the provided Secret URI + Inspect(InspectKeyCmd), + + /// Load a node key from a file or stdin and print the corresponding peer-id + InspectNodeKey(InspectNodeKeyCmd), + + /// Sign a message, with a given (secret) key. + Sign(SignCmd), + + /// Generate a seed that provides a vanity address. + Vanity(VanityCmd), + + /// Verify a signature for a message, provided on STDIN, with a given (public or secret) key. + Verify(VerifyCmd), +} diff --git a/primitives/cli/Cargo.toml b/primitives/cli/Cargo.toml index 509aa41f7..3d39755b0 100644 --- a/primitives/cli/Cargo.toml +++ b/primitives/cli/Cargo.toml @@ -1,13 +1,14 @@ [package] -name = "cli-primitives" -version = "0.1.0" authors.workspace = true edition.workspace = true homepage.workspace = true license-file.workspace = true +name = "cli-primitives" repository.workspace = true +version = "0.1.0" [dependencies] +sc-cli = { workspace = true } thiserror = { workspace = true } [lints] diff --git a/primitives/cli/src/error.rs b/primitives/cli/src/error.rs index 2af15e7f2..516e1baa5 100644 --- a/primitives/cli/src/error.rs +++ b/primitives/cli/src/error.rs @@ -3,5 +3,6 @@ use thiserror::Error; /// CLI components error handling implementor. #[derive(Debug, Error)] pub enum Error { - // TODO(@serhii, no-ref, 2024-05-28): Add and extend with error variants required in the `polka-storage` or `polka-storage-provider` crates. + #[error(transparent)] + SubstrateCli(#[from] sc_cli::Error), } From 4f1dbbaf778901cc132eadd65d6d2afe726206f5 Mon Sep 17 00:00:00 2001 From: Serhii Temchenko Date: Tue, 11 Jun 2024 09:21:26 -0700 Subject: [PATCH 31/40] fix(cs): Code style fixes --- cli/polka-storage-provider/src/cli.rs | 3 ++- cli/polka-storage-provider/src/commands/runner.rs | 5 ++--- cli/polka-storage-provider/src/main.rs | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/cli/polka-storage-provider/src/cli.rs b/cli/polka-storage-provider/src/cli.rs index 45648bff1..d2003698c 100644 --- a/cli/polka-storage-provider/src/cli.rs +++ b/cli/polka-storage-provider/src/cli.rs @@ -1,6 +1,7 @@ -use crate::commands::{RunRpcCmd, StopRpcCmd, WalletCmd}; use clap::Parser; +use crate::commands::{RunRpcCmd, StopRpcCmd, WalletCmd}; + /// A CLI application that facilitates management operations over a running full node and other components. #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] diff --git a/cli/polka-storage-provider/src/commands/runner.rs b/cli/polka-storage-provider/src/commands/runner.rs index 35c829a2c..3c22e084e 100644 --- a/cli/polka-storage-provider/src/commands/runner.rs +++ b/cli/polka-storage-provider/src/commands/runner.rs @@ -1,9 +1,8 @@ -use crate::cli::Subcommand; -use crate::commands::WalletCmd; -use crate::Cli; use clap::Parser; use cli_primitives::Result; +use crate::{cli::Subcommand, commands::WalletCmd, Cli}; + /// Parses command line arguments into the service configuration and runs the specified /// command with it. pub(crate) async fn run() -> Result<()> { diff --git a/cli/polka-storage-provider/src/main.rs b/cli/polka-storage-provider/src/main.rs index b744a8cd5..5e5634f6e 100644 --- a/cli/polka-storage-provider/src/main.rs +++ b/cli/polka-storage-provider/src/main.rs @@ -6,7 +6,6 @@ mod cli; pub(crate) mod commands; pub(crate) use cli::Cli; - use cli_primitives::Result; use commands::runner; From 74f46f785ac455a99760d778711bbccbcc87e8c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Wed, 12 Jun 2024 09:53:12 +0200 Subject: [PATCH 32/40] fix: merge --- Cargo.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 263ec1f36..7b8bffbf4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,9 @@ panic = 'abort' # Use abort on panic to reduce binary size [workspace.dependencies] # Build dependencies +substrate-build-script-utils = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0" } +substrate-wasm-builder = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0" } + async-stream = "0.3.5" bitflags = "2.5.0" byteorder = "1.5.0" @@ -62,8 +65,6 @@ serde_json = { version = "1.0.114", default-features = false } serde_yaml = { version = "0.9" } sha2 = "0.10.8" smallvec = "1.11.0" -substrate-build-script-utils = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0" } -substrate-wasm-builder = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-v1.11.0" } subxt = { version = "0.37.0" } subxt-signer = "0.37.0" syn = { version = "2.0.53" } From 372660d9e79df68a03dc2ff43b9998dce168b320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Wed, 12 Jun 2024 12:04:20 +0200 Subject: [PATCH 33/40] fix: merge --- cli/polka-storage-provider/src/cli.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/cli/polka-storage-provider/src/cli.rs b/cli/polka-storage-provider/src/cli.rs index 482ff933d..ac57b7ae9 100644 --- a/cli/polka-storage-provider/src/cli.rs +++ b/cli/polka-storage-provider/src/cli.rs @@ -12,7 +12,6 @@ pub(crate) struct Cli { } /// Supported sub-commands. - #[derive(Debug, clap::Subcommand)] pub enum SubCommand { /// Initialize the polka storage provider From 9995d7bc29d05e5aa9719826e5c3eee5d0d34a7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Thu, 13 Jun 2024 09:32:04 +0200 Subject: [PATCH 34/40] fix: pr related suggestions --- cli/polka-storage-provider/src/cli.rs | 2 +- cli/polka-storage-provider/src/commands/info.rs | 2 +- cli/polka-storage-provider/src/commands/init.rs | 2 +- cli/polka-storage-provider/src/commands/run.rs | 10 +++++++--- cli/polka-storage-provider/src/rpc.rs | 9 +-------- cli/polka-storage-provider/src/rpc/methods/common.rs | 9 +++++++-- cli/polka-storage-provider/src/rpc/methods/wallet.rs | 9 +++++++-- 7 files changed, 25 insertions(+), 18 deletions(-) diff --git a/cli/polka-storage-provider/src/cli.rs b/cli/polka-storage-provider/src/cli.rs index ac57b7ae9..f2d6dd5fd 100644 --- a/cli/polka-storage-provider/src/cli.rs +++ b/cli/polka-storage-provider/src/cli.rs @@ -18,7 +18,7 @@ pub enum SubCommand { Init(InitCommand), /// Start a polka storage provider Run(RunCommand), - /// Info command + /// Info command to display information about the storage provider. Info(InfoCommand), /// Command to manage wallet operations. #[command(subcommand)] diff --git a/cli/polka-storage-provider/src/commands/info.rs b/cli/polka-storage-provider/src/commands/info.rs index ddd160d37..e4a856959 100644 --- a/cli/polka-storage-provider/src/commands/info.rs +++ b/cli/polka-storage-provider/src/commands/info.rs @@ -3,7 +3,7 @@ use cli_primitives::Result; /// Command to display information about the storage provider. #[derive(Debug, Clone, Parser)] -pub(crate) struct InfoCommand {} +pub(crate) struct InfoCommand; impl InfoCommand { pub async fn run(&self) -> Result<()> { diff --git a/cli/polka-storage-provider/src/commands/init.rs b/cli/polka-storage-provider/src/commands/init.rs index e8e942af2..ef933e0e4 100644 --- a/cli/polka-storage-provider/src/commands/init.rs +++ b/cli/polka-storage-provider/src/commands/init.rs @@ -4,7 +4,7 @@ use tracing::info; /// Command to initialize the storage provider. #[derive(Debug, Clone, Parser)] -pub(crate) struct InitCommand {} +pub(crate) struct InitCommand; impl InitCommand { pub async fn run(&self) -> Result<()> { diff --git a/cli/polka-storage-provider/src/commands/run.rs b/cli/polka-storage-provider/src/commands/run.rs index b197d0dae..933d5952a 100644 --- a/cli/polka-storage-provider/src/commands/run.rs +++ b/cli/polka-storage-provider/src/commands/run.rs @@ -3,6 +3,7 @@ use std::{net::SocketAddr, sync::Arc}; use chrono::Utc; use clap::Parser; use cli_primitives::Result; +use tracing::info; use url::Url; use crate::{ @@ -33,16 +34,19 @@ impl RunCommand { substrate_client, }); + // Start RPC server let handle = start_rpc(state, self.listen_addr).await?; - let handle_clone = handle.clone(); - let rpc_server_stopped = tokio::spawn(handle_clone.stopped()); + info!("RPC server started at {}", self.listen_addr); // Monitor shutdown tokio::signal::ctrl_c().await?; + + // Stop the Server let _ = handle.stop(); // Wait for the server to stop - let _ = rpc_server_stopped.await; + handle.stopped().await; + info!("RPC server stopped"); Ok(()) } diff --git a/cli/polka-storage-provider/src/rpc.rs b/cli/polka-storage-provider/src/rpc.rs index 3e376f202..b3a6d7a12 100644 --- a/cli/polka-storage-provider/src/rpc.rs +++ b/cli/polka-storage-provider/src/rpc.rs @@ -16,9 +16,6 @@ use crate::substrate; pub mod error; pub mod methods; -/// Type to be used by [`RpcMethod::handle`]. -pub type Ctx = Arc; - /// A definition of an RPC method handler which can be registered with an [`RpcModule`]. pub trait RpcMethod { /// Method name. @@ -30,7 +27,7 @@ pub trait RpcMethod { /// Logic for this method. fn handle( - ctx: Ctx, + ctx: Arc, params: Params, ) -> impl Future> + Send; @@ -52,8 +49,6 @@ pub trait RpcMethod { /// /// These are significant because they are expressed in the URL path against /// which RPC calls are made, e.g `rpc/v0` or `rpc/v1`. -/// -/// This information is important when using [`crate::rpc::client`]. #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] pub enum ApiVersion { V0, @@ -73,7 +68,5 @@ pub async fn start_rpc( let module = create_module(state.clone()); let server_handle = server.start(module); - info!("RPC server started at {}", listen_addr); - Ok(server_handle) } diff --git a/cli/polka-storage-provider/src/rpc/methods/common.rs b/cli/polka-storage-provider/src/rpc/methods/common.rs index 0164d9951..6232af8cf 100644 --- a/cli/polka-storage-provider/src/rpc/methods/common.rs +++ b/cli/polka-storage-provider/src/rpc/methods/common.rs @@ -1,8 +1,10 @@ +use std::sync::Arc; + use chrono::{DateTime, Utc}; use jsonrpsee::types::Params; use serde::{Deserialize, Serialize}; -use crate::rpc::{error::ServerError, ApiVersion, Ctx, RpcMethod}; +use crate::rpc::{error::ServerError, ApiVersion, RpcMethod, RpcServerState}; /// This RPC method exposes the system information. #[derive(Debug)] @@ -15,7 +17,10 @@ impl RpcMethod for Info { type Ok = InfoResult; - async fn handle(ctx: Ctx, _params: Params<'_>) -> Result { + async fn handle( + ctx: Arc, + _params: Params<'_>, + ) -> Result { Ok(InfoResult { start_time: ctx.start_time, }) diff --git a/cli/polka-storage-provider/src/rpc/methods/wallet.rs b/cli/polka-storage-provider/src/rpc/methods/wallet.rs index 4978a2f18..e5d93fd2f 100644 --- a/cli/polka-storage-provider/src/rpc/methods/wallet.rs +++ b/cli/polka-storage-provider/src/rpc/methods/wallet.rs @@ -1,9 +1,11 @@ +use std::sync::Arc; + use jsonrpsee::types::Params; use serde::{Deserialize, Serialize}; use subxt_signer::sr25519::dev; use crate::{ - rpc::{error::ServerError, ApiVersion, Ctx, RpcMethod}, + rpc::{error::ServerError, ApiVersion, RpcMethod, RpcServerState}, substrate::get_system_balances, }; @@ -16,7 +18,10 @@ impl RpcMethod for WalletBalance { type Ok = Option; - async fn handle(ctx: Ctx, _params: Params<'_>) -> Result { + async fn handle( + ctx: Arc, + _params: Params<'_>, + ) -> Result { // TODO(#68,@cernicc,05/06/2024): Implement correctly. dev alice is used as a show case for now. let account = dev::alice().public_key().into(); let balance = get_system_balances(&ctx.substrate_client, &account).await?; From 886008e71881f4a10c84769d4b2c2fb1b3d2b3b4 Mon Sep 17 00:00:00 2001 From: Serhii Temchenko Date: Thu, 13 Jun 2024 22:40:22 -0700 Subject: [PATCH 35/40] fix(cs): Removed result type --- cli/polka-storage-provider/src/commands/info.rs | 4 ++-- cli/polka-storage-provider/src/commands/init.rs | 4 ++-- cli/polka-storage-provider/src/commands/run.rs | 4 ++-- cli/polka-storage-provider/src/commands/runner.rs | 4 ++-- cli/polka-storage-provider/src/main.rs | 4 ++-- cli/polka-storage-provider/src/rpc.rs | 3 ++- primitives/cli/src/lib.rs | 2 -- primitives/cli/src/result.rs | 9 --------- 8 files changed, 12 insertions(+), 22 deletions(-) delete mode 100644 primitives/cli/src/result.rs diff --git a/cli/polka-storage-provider/src/commands/info.rs b/cli/polka-storage-provider/src/commands/info.rs index e4a856959..aa6f9f2bd 100644 --- a/cli/polka-storage-provider/src/commands/info.rs +++ b/cli/polka-storage-provider/src/commands/info.rs @@ -1,12 +1,12 @@ use clap::Parser; -use cli_primitives::Result; +use cli_primitives::Error; /// Command to display information about the storage provider. #[derive(Debug, Clone, Parser)] pub(crate) struct InfoCommand; impl InfoCommand { - pub async fn run(&self) -> Result<()> { + pub async fn run(&self) -> Result<(), Error> { // TODO(#66,@cernicc,31/05/2024): Print start time of the provider // TODO(#67,@cernicc,07/06/2024): Print polkadot address used by the provider unimplemented!() diff --git a/cli/polka-storage-provider/src/commands/init.rs b/cli/polka-storage-provider/src/commands/init.rs index ef933e0e4..6ece41418 100644 --- a/cli/polka-storage-provider/src/commands/init.rs +++ b/cli/polka-storage-provider/src/commands/init.rs @@ -1,5 +1,5 @@ use clap::Parser; -use cli_primitives::Result; +use cli_primitives::Error; use tracing::info; /// Command to initialize the storage provider. @@ -7,7 +7,7 @@ use tracing::info; pub(crate) struct InitCommand; impl InitCommand { - pub async fn run(&self) -> Result<()> { + pub async fn run(&self) -> Result<(), Error> { info!("Initializing polka storage provider..."); // TODO(#64,@cernicc,31/05/2024): Init needed configurations. // TODO(#65,@cernicc,31/05/2024): Check if full node is synced diff --git a/cli/polka-storage-provider/src/commands/run.rs b/cli/polka-storage-provider/src/commands/run.rs index 933d5952a..5fd52ebb5 100644 --- a/cli/polka-storage-provider/src/commands/run.rs +++ b/cli/polka-storage-provider/src/commands/run.rs @@ -2,7 +2,7 @@ use std::{net::SocketAddr, sync::Arc}; use chrono::Utc; use clap::Parser; -use cli_primitives::Result; +use cli_primitives::Error; use tracing::info; use url::Url; @@ -26,7 +26,7 @@ pub(crate) struct RunCommand { } impl RunCommand { - pub async fn run(&self) -> Result<()> { + pub async fn run(&self) -> Result<(), Error> { let substrate_client = substrate::init_client(self.node_rpc_address.as_str()).await?; let state = Arc::new(RpcServerState { diff --git a/cli/polka-storage-provider/src/commands/runner.rs b/cli/polka-storage-provider/src/commands/runner.rs index 4220feeb5..a2fa88013 100644 --- a/cli/polka-storage-provider/src/commands/runner.rs +++ b/cli/polka-storage-provider/src/commands/runner.rs @@ -1,12 +1,12 @@ use clap::Parser; -use cli_primitives::Result; +use cli_primitives::Error; use super::WalletCommand; use crate::{cli::SubCommand, Cli}; /// Parses command line arguments into the service configuration and runs the specified /// command with it. -pub(crate) async fn run() -> Result<()> { +pub(crate) async fn run() -> Result<(), Error> { // CLI arguments parsed and mapped to the struct. let cli_arguments: Cli = Cli::parse(); diff --git a/cli/polka-storage-provider/src/main.rs b/cli/polka-storage-provider/src/main.rs index 615f87c8f..46171b176 100644 --- a/cli/polka-storage-provider/src/main.rs +++ b/cli/polka-storage-provider/src/main.rs @@ -7,13 +7,13 @@ mod rpc; mod substrate; pub(crate) use cli::Cli; -use cli_primitives::Result; +use cli_primitives::Error; use commands::runner; use tracing::level_filters::LevelFilter; use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; #[tokio::main] -async fn main() -> Result<()> { +async fn main() -> Result<(), Error> { // Logger initialization. tracing_subscriber::registry() .with(fmt::layer()) diff --git a/cli/polka-storage-provider/src/rpc.rs b/cli/polka-storage-provider/src/rpc.rs index b3a6d7a12..c49404e0e 100644 --- a/cli/polka-storage-provider/src/rpc.rs +++ b/cli/polka-storage-provider/src/rpc.rs @@ -1,6 +1,7 @@ use std::{future::Future, net::SocketAddr, sync::Arc}; use chrono::Utc; +use cli_primitives::Error; use error::ServerError; use jsonrpsee::{ server::{Server, ServerHandle}, @@ -62,7 +63,7 @@ pub struct RpcServerState { pub async fn start_rpc( state: Arc, listen_addr: SocketAddr, -) -> cli_primitives::Result { +) -> Result { let server = Server::builder().build(listen_addr).await?; let module = create_module(state.clone()); diff --git a/primitives/cli/src/lib.rs b/primitives/cli/src/lib.rs index 87d718e1f..3f7a35931 100644 --- a/primitives/cli/src/lib.rs +++ b/primitives/cli/src/lib.rs @@ -1,7 +1,5 @@ #![deny(unused_crate_dependencies)] mod error; -mod result; pub use error::Error; -pub use result::Result; diff --git a/primitives/cli/src/result.rs b/primitives/cli/src/result.rs deleted file mode 100644 index 314c46e85..000000000 --- a/primitives/cli/src/result.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! Result type. -//! -//! This module defines an alias for the `Result` type with the error -//! type [`Error`](crate::Error). - -use crate::Error; - -/// Result Type. See module level [documentation](self). -pub type Result = std::result::Result; From 4f339d1f23bffd52b1019730cb16909238a3a1e1 Mon Sep 17 00:00:00 2001 From: Serhii Temchenko Date: Thu, 13 Jun 2024 22:41:30 -0700 Subject: [PATCH 36/40] build(deps): Removed unused features of the dependency --- cli/polka-storage-provider/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/polka-storage-provider/Cargo.toml b/cli/polka-storage-provider/Cargo.toml index 8b122af10..ca5ccf413 100644 --- a/cli/polka-storage-provider/Cargo.toml +++ b/cli/polka-storage-provider/Cargo.toml @@ -17,7 +17,7 @@ serde = { workspace = true } serde_json = { workspace = true } subxt = { workspace = true } subxt-signer = { workspace = true } -tokio = { workspace = true, features = ["full"] } +tokio = { workspace = true } tracing = { workspace = true } tracing-subscriber = { workspace = true, features = ["env-filter"] } url = { workspace = true } From 859b88fd9c5825af1dd4386c0596dd0130049df5 Mon Sep 17 00:00:00 2001 From: Serhii Temchenko Date: Thu, 13 Jun 2024 22:41:56 -0700 Subject: [PATCH 37/40] fix(cs): Code style fixes --- cli/polka-storage-provider/src/commands/run.rs | 4 ++-- cli/polka-storage-provider/src/commands/wallet.rs | 10 +++++----- cli/polka-storage-provider/src/rpc.rs | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/cli/polka-storage-provider/src/commands/run.rs b/cli/polka-storage-provider/src/commands/run.rs index 5fd52ebb5..d7c92406f 100644 --- a/cli/polka-storage-provider/src/commands/run.rs +++ b/cli/polka-storage-provider/src/commands/run.rs @@ -17,10 +17,10 @@ const FULL_NODE_DEFAULT_RPC_ADDR: &str = "ws://127.0.0.1:9944"; /// Command to start the storage provider. #[derive(Debug, Clone, Parser)] pub(crate) struct RunCommand { - /// RPC API endpoint used by the parachain node + /// RPC API endpoint used by the parachain node. #[arg(short = 'n', long, default_value = FULL_NODE_DEFAULT_RPC_ADDR)] pub node_rpc_address: Url, - /// Address used for RPC. By default binds on localhost on port 8000 + /// Address used for RPC. By default binds on localhost on port 8000. #[arg(short = 'a', long, default_value = SERVER_DEFAULT_BIND_ADDR)] pub listen_addr: SocketAddr, } diff --git a/cli/polka-storage-provider/src/commands/wallet.rs b/cli/polka-storage-provider/src/commands/wallet.rs index 21d6c9d01..f679d3c07 100644 --- a/cli/polka-storage-provider/src/commands/wallet.rs +++ b/cli/polka-storage-provider/src/commands/wallet.rs @@ -8,21 +8,21 @@ use sc_cli::{ #[derive(Debug, Parser)] #[command( name = "wallet", - about = "Utility for generating and restoring keys", + about = "Utility for generating and restoring keys.", version )] pub enum WalletCommand { /// Generate a random node key, write it to a file or stdout and write the - /// corresponding peer-id to stderr + /// corresponding peer-id to stderr. GenerateNodeKey(GenerateKeyCmdCommon), - /// Generate a random account + /// Generate a random account. Generate(GenerateCmd), - /// Gets a public key and a SS58 address from the provided Secret URI + /// Gets a public key and a SS58 address from the provided Secret URI. Inspect(InspectKeyCmd), - /// Load a node key from a file or stdin and print the corresponding peer-id + /// Load a node key from a file or stdin and print the corresponding peer-id. InspectNodeKey(InspectNodeKeyCmd), /// Sign a message, with a given (secret) key. diff --git a/cli/polka-storage-provider/src/rpc.rs b/cli/polka-storage-provider/src/rpc.rs index c49404e0e..356a8b39d 100644 --- a/cli/polka-storage-provider/src/rpc.rs +++ b/cli/polka-storage-provider/src/rpc.rs @@ -10,7 +10,6 @@ use jsonrpsee::{ }; use methods::create_module; use serde::{Deserialize, Serialize}; -use tracing::info; use crate::substrate; From 647775386d47336fd7ec0d549701c347e146fbdf Mon Sep 17 00:00:00 2001 From: Serhii Temchenko Date: Tue, 18 Jun 2024 05:47:53 -0700 Subject: [PATCH 38/40] fix(cs): Code style fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: José Duarte --- cli/polka-storage-provider/src/substrate.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/polka-storage-provider/src/substrate.rs b/cli/polka-storage-provider/src/substrate.rs index 5df0c639f..97c73fcdc 100644 --- a/cli/polka-storage-provider/src/substrate.rs +++ b/cli/polka-storage-provider/src/substrate.rs @@ -14,7 +14,7 @@ pub type Client = OnlineClient; /// Initialize a Polkadot client. pub async fn init_client(url: impl AsRef) -> Result { - let inner = OnlineClient::::from_url(url).await?; + let inner = Client::from_url(url).await?; info!("Connection with parachain established."); Ok(inner) } From 818d250d849c4e8b04d735ece00f23e880d8f146 Mon Sep 17 00:00:00 2001 From: Serhii Temchenko Date: Tue, 18 Jun 2024 06:00:47 -0700 Subject: [PATCH 39/40] feat: Common error type moved to specific crate --- Cargo.lock | 8 +------- cli/polka-storage-provider/Cargo.toml | 2 +- cli/polka-storage-provider/src/commands/info.rs | 2 +- cli/polka-storage-provider/src/commands/init.rs | 2 +- cli/polka-storage-provider/src/commands/run.rs | 2 +- cli/polka-storage-provider/src/commands/runner.rs | 2 +- .../cli => cli/polka-storage-provider}/src/error.rs | 0 cli/polka-storage-provider/src/main.rs | 3 ++- cli/polka-storage-provider/src/rpc.rs | 2 +- primitives/cli/Cargo.toml | 4 ---- primitives/cli/src/lib.rs | 4 ---- 11 files changed, 9 insertions(+), 22 deletions(-) rename {primitives/cli => cli/polka-storage-provider}/src/error.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 6efd49b3a..25bf82378 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1546,12 +1546,6 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "cli-primitives" version = "0.1.0" -dependencies = [ - "sc-cli", - "subxt", - "thiserror", - "tracing-subscriber", -] [[package]] name = "coarsetime" @@ -8152,13 +8146,13 @@ version = "0.1.0" dependencies = [ "chrono", "clap", - "cli-primitives", "jsonrpsee", "sc-cli", "serde", "serde_json", "subxt", "subxt-signer", + "thiserror", "tokio", "tracing", "tracing-subscriber", diff --git a/cli/polka-storage-provider/Cargo.toml b/cli/polka-storage-provider/Cargo.toml index ca5ccf413..e9a2fcef0 100644 --- a/cli/polka-storage-provider/Cargo.toml +++ b/cli/polka-storage-provider/Cargo.toml @@ -10,7 +10,6 @@ version = "0.1.0" [dependencies] chrono = { workspace = true, features = ["serde"] } clap = { workspace = true, features = ["derive"] } -cli-primitives = { workspace = true } jsonrpsee = { workspace = true, features = ["server"] } sc-cli = { workspace = true } serde = { workspace = true } @@ -21,6 +20,7 @@ tokio = { workspace = true } tracing = { workspace = true } tracing-subscriber = { workspace = true, features = ["env-filter"] } url = { workspace = true } +thiserror = { workspace = true } [lints] workspace = true diff --git a/cli/polka-storage-provider/src/commands/info.rs b/cli/polka-storage-provider/src/commands/info.rs index aa6f9f2bd..7724beeee 100644 --- a/cli/polka-storage-provider/src/commands/info.rs +++ b/cli/polka-storage-provider/src/commands/info.rs @@ -1,5 +1,5 @@ +use crate::Error; use clap::Parser; -use cli_primitives::Error; /// Command to display information about the storage provider. #[derive(Debug, Clone, Parser)] diff --git a/cli/polka-storage-provider/src/commands/init.rs b/cli/polka-storage-provider/src/commands/init.rs index 6ece41418..fc8da6882 100644 --- a/cli/polka-storage-provider/src/commands/init.rs +++ b/cli/polka-storage-provider/src/commands/init.rs @@ -1,5 +1,5 @@ +use crate::Error; use clap::Parser; -use cli_primitives::Error; use tracing::info; /// Command to initialize the storage provider. diff --git a/cli/polka-storage-provider/src/commands/run.rs b/cli/polka-storage-provider/src/commands/run.rs index d7c92406f..26f84babf 100644 --- a/cli/polka-storage-provider/src/commands/run.rs +++ b/cli/polka-storage-provider/src/commands/run.rs @@ -1,8 +1,8 @@ use std::{net::SocketAddr, sync::Arc}; +use crate::Error; use chrono::Utc; use clap::Parser; -use cli_primitives::Error; use tracing::info; use url::Url; diff --git a/cli/polka-storage-provider/src/commands/runner.rs b/cli/polka-storage-provider/src/commands/runner.rs index a2fa88013..b400a467f 100644 --- a/cli/polka-storage-provider/src/commands/runner.rs +++ b/cli/polka-storage-provider/src/commands/runner.rs @@ -1,5 +1,5 @@ +use crate::Error; use clap::Parser; -use cli_primitives::Error; use super::WalletCommand; use crate::{cli::SubCommand, Cli}; diff --git a/primitives/cli/src/error.rs b/cli/polka-storage-provider/src/error.rs similarity index 100% rename from primitives/cli/src/error.rs rename to cli/polka-storage-provider/src/error.rs diff --git a/cli/polka-storage-provider/src/main.rs b/cli/polka-storage-provider/src/main.rs index 46171b176..bc437e3e2 100644 --- a/cli/polka-storage-provider/src/main.rs +++ b/cli/polka-storage-provider/src/main.rs @@ -3,12 +3,13 @@ mod cli; pub(crate) mod commands; +mod error; mod rpc; mod substrate; pub(crate) use cli::Cli; -use cli_primitives::Error; use commands::runner; +pub(crate) use error::Error; use tracing::level_filters::LevelFilter; use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; diff --git a/cli/polka-storage-provider/src/rpc.rs b/cli/polka-storage-provider/src/rpc.rs index 356a8b39d..b5656cbb8 100644 --- a/cli/polka-storage-provider/src/rpc.rs +++ b/cli/polka-storage-provider/src/rpc.rs @@ -1,7 +1,7 @@ use std::{future::Future, net::SocketAddr, sync::Arc}; +use crate::Error; use chrono::Utc; -use cli_primitives::Error; use error::ServerError; use jsonrpsee::{ server::{Server, ServerHandle}, diff --git a/primitives/cli/Cargo.toml b/primitives/cli/Cargo.toml index 0bedf6d52..6d9288b86 100644 --- a/primitives/cli/Cargo.toml +++ b/primitives/cli/Cargo.toml @@ -8,10 +8,6 @@ repository.workspace = true version = "0.1.0" [dependencies] -sc-cli = { workspace = true } -subxt = { workspace = true } -thiserror = { workspace = true } -tracing-subscriber = { workspace = true } [lints] workspace = true diff --git a/primitives/cli/src/lib.rs b/primitives/cli/src/lib.rs index 3f7a35931..4534a2c5a 100644 --- a/primitives/cli/src/lib.rs +++ b/primitives/cli/src/lib.rs @@ -1,5 +1 @@ #![deny(unused_crate_dependencies)] - -mod error; - -pub use error::Error; From a0711b5cf7685ede1974745ced6d786da39ea538 Mon Sep 17 00:00:00 2001 From: Serhii Temchenko Date: Tue, 18 Jun 2024 07:14:39 -0700 Subject: [PATCH 40/40] fix(cs): Code style fixes --- cli/polka-storage-provider/Cargo.toml | 2 +- cli/polka-storage-provider/src/commands/info.rs | 3 ++- cli/polka-storage-provider/src/commands/init.rs | 3 ++- cli/polka-storage-provider/src/commands/run.rs | 3 +-- cli/polka-storage-provider/src/commands/runner.rs | 3 +-- cli/polka-storage-provider/src/rpc.rs | 3 +-- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/cli/polka-storage-provider/Cargo.toml b/cli/polka-storage-provider/Cargo.toml index e9a2fcef0..13d204756 100644 --- a/cli/polka-storage-provider/Cargo.toml +++ b/cli/polka-storage-provider/Cargo.toml @@ -16,11 +16,11 @@ serde = { workspace = true } serde_json = { workspace = true } subxt = { workspace = true } subxt-signer = { workspace = true } +thiserror = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } tracing-subscriber = { workspace = true, features = ["env-filter"] } url = { workspace = true } -thiserror = { workspace = true } [lints] workspace = true diff --git a/cli/polka-storage-provider/src/commands/info.rs b/cli/polka-storage-provider/src/commands/info.rs index 7724beeee..971b14132 100644 --- a/cli/polka-storage-provider/src/commands/info.rs +++ b/cli/polka-storage-provider/src/commands/info.rs @@ -1,6 +1,7 @@ -use crate::Error; use clap::Parser; +use crate::Error; + /// Command to display information about the storage provider. #[derive(Debug, Clone, Parser)] pub(crate) struct InfoCommand; diff --git a/cli/polka-storage-provider/src/commands/init.rs b/cli/polka-storage-provider/src/commands/init.rs index fc8da6882..248aa293b 100644 --- a/cli/polka-storage-provider/src/commands/init.rs +++ b/cli/polka-storage-provider/src/commands/init.rs @@ -1,7 +1,8 @@ -use crate::Error; use clap::Parser; use tracing::info; +use crate::Error; + /// Command to initialize the storage provider. #[derive(Debug, Clone, Parser)] pub(crate) struct InitCommand; diff --git a/cli/polka-storage-provider/src/commands/run.rs b/cli/polka-storage-provider/src/commands/run.rs index 26f84babf..a27e5159f 100644 --- a/cli/polka-storage-provider/src/commands/run.rs +++ b/cli/polka-storage-provider/src/commands/run.rs @@ -1,6 +1,5 @@ use std::{net::SocketAddr, sync::Arc}; -use crate::Error; use chrono::Utc; use clap::Parser; use tracing::info; @@ -8,7 +7,7 @@ use url::Url; use crate::{ rpc::{start_rpc, RpcServerState}, - substrate, + substrate, Error, }; const SERVER_DEFAULT_BIND_ADDR: &str = "127.0.0.1:8000"; diff --git a/cli/polka-storage-provider/src/commands/runner.rs b/cli/polka-storage-provider/src/commands/runner.rs index b400a467f..6c9ec560d 100644 --- a/cli/polka-storage-provider/src/commands/runner.rs +++ b/cli/polka-storage-provider/src/commands/runner.rs @@ -1,8 +1,7 @@ -use crate::Error; use clap::Parser; use super::WalletCommand; -use crate::{cli::SubCommand, Cli}; +use crate::{cli::SubCommand, Cli, Error}; /// Parses command line arguments into the service configuration and runs the specified /// command with it. diff --git a/cli/polka-storage-provider/src/rpc.rs b/cli/polka-storage-provider/src/rpc.rs index b5656cbb8..a3a826f0b 100644 --- a/cli/polka-storage-provider/src/rpc.rs +++ b/cli/polka-storage-provider/src/rpc.rs @@ -1,6 +1,5 @@ use std::{future::Future, net::SocketAddr, sync::Arc}; -use crate::Error; use chrono::Utc; use error::ServerError; use jsonrpsee::{ @@ -11,7 +10,7 @@ use jsonrpsee::{ use methods::create_module; use serde::{Deserialize, Serialize}; -use crate::substrate; +use crate::{substrate, Error}; pub mod error; pub mod methods;