diff --git a/.gitignore b/.gitignore index 4caf66d45..d541f6c74 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ .DS_Store .AppleDouble .LSOverride +.idea +.vscode # Rust .gitignore # https://github.com/github/gitignore/blob/main/Rust.gitignore @@ -19,6 +21,3 @@ target/ # reproducible local environment .direnv - -# Visual Studio Code -.vscode/ \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index e01be46b0..41c661f70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -651,6 +651,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.4.0", + "blocking", + "futures-lite 2.3.0", +] + [[package]] name = "async-io" version = "1.13.0" @@ -721,6 +732,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.3", + "blocking", + "futures-lite 2.3.0", +] + [[package]] name = "async-process" version = "1.8.1" @@ -738,6 +760,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.3.1", + "async-io 2.3.3", + "async-lock 3.4.0", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener 5.3.1", + "futures-lite 2.3.0", + "rustix 0.38.34", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "async-signal" version = "0.2.7" @@ -876,6 +918,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" @@ -955,6 +1003,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" dependencies = [ "bitcoin_hashes 0.11.0", + "serde", + "unicode-normalization", ] [[package]] @@ -1302,6 +1352,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" @@ -1477,7 +1533,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", "terminal_size", ] @@ -1499,6 +1555,10 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +[[package]] +name = "cli-primitives" +version = "0.1.0" + [[package]] name = "coarsetime" version = "0.1.34" @@ -2130,7 +2190,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", @@ -2521,8 +2581,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", @@ -2650,6 +2710,76 @@ dependencies = [ "syn 2.0.66", ] +[[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.66", +] + +[[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.66", +] + [[package]] name = "dashmap" version = "5.5.3" @@ -2755,6 +2885,17 @@ dependencies = [ "syn 2.0.66", ] +[[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.66", +] + [[package]] name = "derive_more" version = "0.99.17" @@ -3176,6 +3317,16 @@ dependencies = [ "pin-project-lite 0.2.14", ] +[[package]] +name = "event-listener" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +dependencies = [ + "concurrent-queue", + "pin-project-lite 0.2.14", +] + [[package]] name = "event-listener" version = "5.3.1" @@ -3361,6 +3512,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" @@ -3565,6 +3726,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" @@ -3587,7 +3759,7 @@ dependencies = [ "bitflags 1.3.2", "docify", "environmental", - "frame-metadata", + "frame-metadata 16.0.0", "frame-support-procedural", "impl-trait-for-tuples", "k256", @@ -3633,7 +3805,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.66", ] @@ -4330,6 +4502,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" @@ -4649,7 +4827,9 @@ 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", @@ -4704,6 +4884,26 @@ dependencies = [ "tracing", ] +[[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]] name = "jsonrpsee-proc-macros" version = "0.22.5" @@ -5502,6 +5702,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" @@ -7640,7 +7849,7 @@ dependencies = [ "memmap2 0.5.10", "parking_lot 0.12.3", "rand 0.8.5", - "siphasher", + "siphasher 0.3.11", "snap", "winapi", ] @@ -8027,6 +8236,25 @@ dependencies = [ "substrate-prometheus-endpoint", ] +[[package]] +name = "polka-storage-provider" +version = "0.1.0" +dependencies = [ + "chrono", + "clap", + "jsonrpsee", + "sc-cli", + "serde", + "serde_json", + "subxt", + "subxt-signer", + "thiserror", + "tokio", + "tracing", + "tracing-subscriber", + "url", +] + [[package]] name = "polka-storage-runtime" version = "0.0.0" @@ -8284,7 +8512,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", ] @@ -8606,7 +8834,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)", @@ -9841,6 +10069,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" @@ -10426,6 +10670,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" @@ -10559,7 +10814,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", @@ -10754,7 +11009,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", @@ -10811,7 +11066,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", @@ -10890,7 +11145,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", @@ -11515,7 +11770,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)", ] @@ -11600,7 +11855,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", @@ -11639,6 +11894,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" @@ -11665,6 +11987,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.66", + "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" @@ -12079,6 +12445,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" @@ -12129,15 +12501,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.3.1", + "async-executor", + "async-fs 2.1.2", + "async-io 2.3.3", + "async-lock 3.4.0", + "async-net 2.0.0", + "async-process 2.2.3", + "blocking", + "futures-lite 2.3.0", +] + [[package]] name = "smoldot" version = "0.11.0" @@ -12176,13 +12565,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.4.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", @@ -12221,10 +12665,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.3.1", + "async-lock 3.4.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.3", + "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", ] @@ -12471,7 +12951,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", @@ -12540,7 +13020,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)", @@ -12574,6 +13054,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" @@ -12593,7 +13087,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.66", ] @@ -12685,7 +13179,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)", @@ -12732,7 +13226,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", ] @@ -12959,7 +13453,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)", @@ -13285,7 +13779,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", @@ -13299,7 +13793,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", @@ -13339,6 +13833,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" @@ -13488,6 +13988,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.66", + "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.66", +] + +[[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" @@ -15415,6 +16066,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 26caa0a1a..d21a6badf 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", "storage/mater", "storage/polka-index"] +members = ["cli/polka-storage-provider", "node", "primitives/cli", "runtime", "storage/mater", "storage/polka-index"] resolver = "2" # FIXME(#@jmg-duarte,#7,14/5/24): remove the patch once something >1.11.0 is released @@ -42,6 +42,7 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = color-print = "0.3.4" criterion = "0.5.1" digest = "0.10.7" +env_logger = "0.11.2" futures = "0.3.28" hex-literal = { version = "0.4.1" } indexmap = "2.2.6" @@ -49,7 +50,7 @@ integer-encoding = "4.0.0" ipld-core = "0.4.1" ipld-dagpb = "0.2.1" itertools = "0.13.0" -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" @@ -67,6 +68,8 @@ serde_json = { version = "1.0.114", default-features = false } serde_yaml = { version = "0.9" } sha2 = "0.10.8" smallvec = "1.11.0" +subxt = { version = "0.37.0" } +subxt-signer = "0.37.0" syn = { version = "2.0.53" } tempfile = "3.10.1" thiserror = { version = "1.0.48" } @@ -75,9 +78,11 @@ tokio-stream = "0.1.15" tokio-util = "0.7.11" tracing = "0.1.40" tracing-subscriber = "0.3.18" +url = "2.5.0" uuid = "1.8.0" # Local +cli-primitives = { path = "primitives/cli" } polka-storage-runtime = { path = "runtime" } # Substrate 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..13d204756 --- /dev/null +++ b/cli/polka-storage-provider/Cargo.toml @@ -0,0 +1,26 @@ +[package] +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] +chrono = { workspace = true, features = ["serde"] } +clap = { workspace = true, features = ["derive"] } +jsonrpsee = { workspace = true, features = ["server"] } +sc-cli = { workspace = true } +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 } + +[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 000000000..edbf451d5 Binary files /dev/null and b/cli/polka-storage-provider/artifacts/metadata.scale differ diff --git a/cli/polka-storage-provider/src/cli.rs b/cli/polka-storage-provider/src/cli.rs new file mode 100644 index 000000000..f2d6dd5fd --- /dev/null +++ b/cli/polka-storage-provider/src/cli.rs @@ -0,0 +1,26 @@ +use clap::Parser; + +use crate::commands::{InfoCommand, InitCommand, RunCommand, WalletCommand}; + +/// 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)] +pub(crate) struct Cli { + #[command(subcommand)] + pub subcommand: SubCommand, +} + +/// Supported sub-commands. +#[derive(Debug, clap::Subcommand)] +pub enum SubCommand { + /// Initialize the polka storage provider + Init(InitCommand), + /// Start a polka storage provider + Run(RunCommand), + /// Info command to display information about the storage provider. + Info(InfoCommand), + /// Command to manage wallet operations. + #[command(subcommand)] + Wallet(WalletCommand), +} diff --git a/cli/polka-storage-provider/src/commands.rs b/cli/polka-storage-provider/src/commands.rs new file mode 100644 index 000000000..b3724cc1c --- /dev/null +++ b/cli/polka-storage-provider/src/commands.rs @@ -0,0 +1,11 @@ +mod info; +mod init; +mod run; +mod wallet; + +pub(crate) mod runner; + +pub(crate) use info::InfoCommand; +pub(crate) use init::InitCommand; +pub(crate) use run::RunCommand; +pub(crate) use wallet::WalletCommand; 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..971b14132 --- /dev/null +++ b/cli/polka-storage-provider/src/commands/info.rs @@ -0,0 +1,15 @@ +use clap::Parser; + +use crate::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<(), 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 new file mode 100644 index 000000000..248aa293b --- /dev/null +++ b/cli/polka-storage-provider/src/commands/init.rs @@ -0,0 +1,19 @@ +use clap::Parser; +use tracing::info; + +use crate::Error; + +/// Command to initialize the storage provider. +#[derive(Debug, Clone, Parser)] +pub(crate) struct InitCommand; + +impl InitCommand { + 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 + info!("Provider initialized successfully. Start it with `polka-storage-provider run`"); + + unimplemented!() + } +} 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..a27e5159f --- /dev/null +++ b/cli/polka-storage-provider/src/commands/run.rs @@ -0,0 +1,52 @@ +use std::{net::SocketAddr, sync::Arc}; + +use chrono::Utc; +use clap::Parser; +use tracing::info; +use url::Url; + +use crate::{ + rpc::{start_rpc, RpcServerState}, + substrate, Error, +}; + +const SERVER_DEFAULT_BIND_ADDR: &str = "127.0.0.1:8000"; +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. + #[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. + #[arg(short = 'a', long, default_value = SERVER_DEFAULT_BIND_ADDR)] + pub listen_addr: SocketAddr, +} + +impl RunCommand { + 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 { + start_time: Utc::now(), + substrate_client, + }); + + // Start RPC server + let handle = start_rpc(state, self.listen_addr).await?; + 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 + handle.stopped().await; + info!("RPC server stopped"); + + Ok(()) + } +} 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..6c9ec560d --- /dev/null +++ b/cli/polka-storage-provider/src/commands/runner.rs @@ -0,0 +1,26 @@ +use clap::Parser; + +use super::WalletCommand; +use crate::{cli::SubCommand, Cli, Error}; + +/// Parses command line arguments into the service configuration and runs the specified +/// command with it. +pub(crate) async fn run() -> Result<(), Error> { + // CLI arguments parsed and mapped to the struct. + let cli_arguments: Cli = Cli::parse(); + + match &cli_arguments.subcommand { + SubCommand::Init(cmd) => cmd.run().await, + SubCommand::Run(cmd) => cmd.run().await, + SubCommand::Info(cmd) => cmd.run().await, + SubCommand::Wallet(cmd) => match cmd { + WalletCommand::GenerateNodeKey(cmd) => Ok(cmd.run()?), + WalletCommand::Generate(cmd) => Ok(cmd.run()?), + WalletCommand::Inspect(cmd) => Ok(cmd.run()?), + WalletCommand::InspectNodeKey(cmd) => Ok(cmd.run()?), + WalletCommand::Vanity(cmd) => Ok(cmd.run()?), + WalletCommand::Verify(cmd) => Ok(cmd.run()?), + WalletCommand::Sign(cmd) => Ok(cmd.run()?), + }, + } +} diff --git a/cli/polka-storage-provider/src/commands/wallet.rs b/cli/polka-storage-provider/src/commands/wallet.rs new file mode 100644 index 000000000..f679d3c07 --- /dev/null +++ b/cli/polka-storage-provider/src/commands/wallet.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 WalletCommand { + /// 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/cli/polka-storage-provider/src/error.rs b/cli/polka-storage-provider/src/error.rs new file mode 100644 index 000000000..738d1f4e6 --- /dev/null +++ b/cli/polka-storage-provider/src/error.rs @@ -0,0 +1,17 @@ +use thiserror::Error; + +/// CLI components error handling implementor. +#[derive(Debug, Error)] +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), + + #[error(transparent)] + SubstrateCli(#[from] sc_cli::Error), +} diff --git a/cli/polka-storage-provider/src/main.rs b/cli/polka-storage-provider/src/main.rs new file mode 100644 index 000000000..bc437e3e2 --- /dev/null +++ b/cli/polka-storage-provider/src/main.rs @@ -0,0 +1,30 @@ +//! 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; +mod error; +mod rpc; +mod substrate; + +pub(crate) use cli::Cli; +use commands::runner; +pub(crate) use error::Error; +use tracing::level_filters::LevelFilter; +use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; + +#[tokio::main] +async fn main() -> Result<(), Error> { + // Logger initialization. + tracing_subscriber::registry() + .with(fmt::layer()) + .with( + EnvFilter::builder() + .with_default_directive(LevelFilter::INFO.into()) + .from_env()?, + ) + .init(); + + // Run requested command. + runner::run().await +} diff --git a/cli/polka-storage-provider/src/rpc.rs b/cli/polka-storage-provider/src/rpc.rs new file mode 100644 index 000000000..a3a826f0b --- /dev/null +++ b/cli/polka-storage-provider/src/rpc.rs @@ -0,0 +1,71 @@ +use std::{future::Future, net::SocketAddr, sync::Arc}; + +use chrono::Utc; +use error::ServerError; +use jsonrpsee::{ + server::{Server, ServerHandle}, + types::Params, + RpcModule, +}; +use methods::create_module; +use serde::{Deserialize, Serialize}; + +use crate::{substrate, Error}; + +pub mod error; +pub mod methods; + +/// 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; + /// Successful response type. + type Ok: Serialize; + + /// Logic for this method. + fn handle( + ctx: Arc, + params: Params, + ) -> impl Future> + Send; + + /// Register this method with an [`RpcModule`]. + fn register_async(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`. +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] +pub enum ApiVersion { + V0, +} + +pub struct RpcServerState { + pub start_time: chrono::DateTime, + pub substrate_client: substrate::Client, +} + +pub async fn start_rpc( + state: Arc, + listen_addr: SocketAddr, +) -> Result { + let server = Server::builder().build(listen_addr).await?; + + let module = create_module(state.clone()); + let server_handle = server.start(module); + + Ok(server_handle) +} 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..c90aa5e0b --- /dev/null +++ b/cli/polka-storage-provider/src/rpc/error.rs @@ -0,0 +1,42 @@ +use std::fmt::Display; + +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 + } +} + +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.rs b/cli/polka-storage-provider/src/rpc/methods.rs new file mode 100644 index 000000000..e62f231b1 --- /dev/null +++ b/cli/polka-storage-provider/src/rpc/methods.rs @@ -0,0 +1,17 @@ +use std::sync::Arc; + +use jsonrpsee::RpcModule; + +use super::{RpcMethod, RpcServerState}; + +pub mod common; +pub mod wallet; + +pub fn create_module(state: Arc) -> RpcModule { + let mut module = RpcModule::from_arc(state); + + common::Info::register_async(&mut module); + wallet::WalletBalance::register_async(&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 new file mode 100644 index 000000000..6232af8cf --- /dev/null +++ b/cli/polka-storage-provider/src/rpc/methods/common.rs @@ -0,0 +1,33 @@ +use std::sync::Arc; + +use chrono::{DateTime, Utc}; +use jsonrpsee::types::Params; +use serde::{Deserialize, Serialize}; + +use crate::rpc::{error::ServerError, ApiVersion, RpcMethod, RpcServerState}; + +/// This RPC method exposes the system information. +#[derive(Debug)] +pub struct Info; + +impl RpcMethod for Info { + const NAME: &'static str = "info"; + + const API_VERSION: ApiVersion = ApiVersion::V0; + + type Ok = InfoResult; + + async fn handle( + ctx: Arc, + _params: Params<'_>, + ) -> Result { + 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 new file mode 100644 index 000000000..e5d93fd2f --- /dev/null +++ b/cli/polka-storage-provider/src/rpc/methods/wallet.rs @@ -0,0 +1,42 @@ +use std::sync::Arc; + +use jsonrpsee::types::Params; +use serde::{Deserialize, Serialize}; +use subxt_signer::sr25519::dev; + +use crate::{ + rpc::{error::ServerError, ApiVersion, RpcMethod, RpcServerState}, + substrate::get_system_balances, +}; + +/// 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"; + const API_VERSION: ApiVersion = ApiVersion::V0; + + type Ok = Option; + + 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?; + + 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, +} diff --git a/cli/polka-storage-provider/src/substrate.rs b/cli/polka-storage-provider/src/substrate.rs new file mode 100644 index 000000000..97c73fcdc --- /dev/null +++ b/cli/polka-storage-provider/src/substrate.rs @@ -0,0 +1,37 @@ +use polkadot::runtime_types::{frame_system::AccountInfo, pallet_balances::types::AccountData}; +use subxt::{utils::AccountId32, Error, 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 = Client::from_url(url).await?; + info!("Connection with parachain established."); + Ok(inner) +} + +/// Get system balances for the particular account. +pub async fn get_system_balances( + client: &Client, + account: &AccountId32, +) -> Result>>, 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/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..6d9288b86 --- /dev/null +++ b/primitives/cli/Cargo.toml @@ -0,0 +1,13 @@ +[package] +authors.workspace = true +edition.workspace = true +homepage.workspace = true +license-file.workspace = true +name = "cli-primitives" +repository.workspace = true +version = "0.1.0" + +[dependencies] + +[lints] +workspace = true diff --git a/primitives/cli/src/lib.rs b/primitives/cli/src/lib.rs new file mode 100644 index 000000000..4534a2c5a --- /dev/null +++ b/primitives/cli/src/lib.rs @@ -0,0 +1 @@ +#![deny(unused_crate_dependencies)]