From 9e2552ce5e6afdabb6857cc9ee098086625933c6 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Fri, 20 Aug 2021 18:49:20 -0400 Subject: [PATCH 01/13] include hacky legacy metadata (before v12) in desub --- .gitignore | 2 +- TODO.md | 2 - core/Cargo.toml | 20 +- integration_tests/Cargo.toml | 6 +- .../metadatav10/Cargo.lock | 1803 +++++++++++++++++ .../metadatav10/Cargo.toml | 21 + .../metadatav10/src/lib.rs | 407 ++++ .../metadatav11/Cargo.lock | 1437 ++----------- .../metadatav11/Cargo.toml | 28 + .../metadatav11/src/lib.rs | 425 ++++ .../metadatav8/Cargo.lock | 1803 +++++++++++++++++ .../metadatav8/Cargo.toml | 23 + .../metadatav8/src/lib.rs | 407 ++++ .../metadatav9/Cargo.lock | 1803 +++++++++++++++++ .../metadatav9/Cargo.toml | 20 + .../metadatav9/src/lib.rs | 405 ++++ 16 files changed, 7280 insertions(+), 1332 deletions(-) delete mode 100644 TODO.md create mode 100644 substrate-metadata-versions/metadatav10/Cargo.lock create mode 100644 substrate-metadata-versions/metadatav10/Cargo.toml create mode 100644 substrate-metadata-versions/metadatav10/src/lib.rs rename Cargo.lock => substrate-metadata-versions/metadatav11/Cargo.lock (50%) create mode 100644 substrate-metadata-versions/metadatav11/Cargo.toml create mode 100644 substrate-metadata-versions/metadatav11/src/lib.rs create mode 100644 substrate-metadata-versions/metadatav8/Cargo.lock create mode 100644 substrate-metadata-versions/metadatav8/Cargo.toml create mode 100644 substrate-metadata-versions/metadatav8/src/lib.rs create mode 100644 substrate-metadata-versions/metadatav9/Cargo.lock create mode 100644 substrate-metadata-versions/metadatav9/Cargo.toml create mode 100644 substrate-metadata-versions/metadatav9/src/lib.rs diff --git a/.gitignore b/.gitignore index ec90a305..80b49d9b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -/target +target/ **/*.rs.bk .cargo-remote.toml .idea/ diff --git a/TODO.md b/TODO.md deleted file mode 100644 index ab809ea1..00000000 --- a/TODO.md +++ /dev/null @@ -1,2 +0,0 @@ -- Don't expose regex public functions -- move `RustTypeMarker` into its own file diff --git a/core/Cargo.toml b/core/Cargo.toml index f18d43ae..ed2297ae 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -8,23 +8,23 @@ repository = "https://github.com/paritytech/desub" [dependencies] log = "0.4" thiserror = "1.0.22" -codec = { version = "1", package = "parity-scale-codec" } -serde = { version = "1.0", features = ["derive"] } -serde_json = { version = "1.0", features = ["preserve_order"] } +codec = { version = "2", package = "parity-scale-codec" } +serde = { version = "1", features = ["derive"] } +serde_json = { version = "1", features = ["preserve_order"] } onig = { version = "5.0", default-features = false } derive_more = "0.99.3" dyn-clone = "1.0" hex = "0.4" -runtime-version = { package = "sp-version", git = "https://github.com/paritytech/substrate", rev = "a364e27d6e3971d756d28435efc468d95add52d3" } -pallet-indices = { package = "pallet-indices", git = "https://github.com/paritytech/substrate", rev = "a364e27d6e3971d756d28435efc468d95add52d3" } -pallet-democracy = { package = "pallet-democracy", git = "https://github.com/paritytech/substrate", rev = "a364e27d6e3971d756d28435efc468d95add52d3" } -pallet-identity = { package = "pallet-identity", git = "https://github.com/paritytech/substrate", rev = "a364e27d6e3971d756d28435efc468d95add52d3" } +runtime-version = { package = "sp-version", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } +pallet-indices = { package = "pallet-indices", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } +pallet-democracy = { package = "pallet-democracy", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } +pallet-identity = { package = "pallet-identity", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } -primitives = { package = "sp-core", git = "https://github.com/paritytech/substrate", rev = "a364e27d6e3971d756d28435efc468d95add52d3" } -runtime-primitives = { package = "sp-runtime", git = "https://github.com/paritytech/substrate", rev = "a364e27d6e3971d756d28435efc468d95add52d3" } +primitives = { package = "sp-core", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } +runtime-primitives = { package = "sp-runtime", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } -runtime-metadata-latest = { package = "frame-metadata", git = "https://github.com/paritytech/substrate", rev = "a364e27d6e3971d756d28435efc468d95add52d3" } +frame-metadata = { package = "frame-metadata", git = "https://github.com/paritytech/frame-metadata", features = ["v12", "v13", "v14"] } runtime-metadata11 = { git = "https://github.com/insipx/substrate-metadata-versions", package = "frame-metadatav11", branch = "master" } runtime-metadata10 = { git = "https://github.com/insipx/substrate-metadata-versions", package = "frame-metadatav10", branch = "master" } runtime-metadata09 = { git = "https://github.com/insipx/substrate-metadata-versions", package = "frame-metadatav9", branch = "master" } diff --git a/integration_tests/Cargo.toml b/integration_tests/Cargo.toml index d25c5fed..9fd073c4 100644 --- a/integration_tests/Cargo.toml +++ b/integration_tests/Cargo.toml @@ -13,9 +13,9 @@ extras = { path = "../extras", package = "desub-extras" } serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0", features = ["preserve_order"] } codec = { version = "1", package = "parity-scale-codec" } -primitives = { package = "sp-core", git = "https://github.com/paritytech/substrate", rev = "a364e27d6e3971d756d28435efc468d95add52d3" } -frame-system = { git = "https://github.com/paritytech/substrate", rev = "a364e27d6e3971d756d28435efc468d95add52d3" } -pallet-balances = { git = "https://github.com/paritytech/substrate", rev = "a364e27d6e3971d756d28435efc468d95add52d3" } +primitives = { package = "sp-core", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } pretty_env_logger = "0.4" log = "0.4" hex = "0.4" diff --git a/substrate-metadata-versions/metadatav10/Cargo.lock b/substrate-metadata-versions/metadatav10/Cargo.lock new file mode 100644 index 00000000..897e2794 --- /dev/null +++ b/substrate-metadata-versions/metadatav10/Cargo.lock @@ -0,0 +1,1803 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "addr2line" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", +] + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "backtrace" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01" +dependencies = [ + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base58" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitvec" +version = "0.17.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" +dependencies = [ + "either", + "radium", +] + +[[package]] +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +dependencies = [ + "arrayvec 0.4.12", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array 0.12.4", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array 0.14.4", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "byte-slice-cast" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cc" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "winapi", +] + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cpufeatures" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-mac" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +dependencies = [ + "generic-array 0.12.4", + "subtle 1.0.0", +] + +[[package]] +name = "curve25519-dalek" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b85542f99a2dfa2a1b8e192662741c9859a846b296bef1c92ef9b58b5a216" +dependencies = [ + "byteorder", + "digest 0.8.1", + "rand_core 0.5.1", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "derive_more" +version = "0.99.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.4", +] + +[[package]] +name = "dyn-clonable" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4" +dependencies = [ + "dyn-clonable-impl", + "dyn-clone", +] + +[[package]] +name = "dyn-clonable-impl" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dyn-clone" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" + +[[package]] +name = "ed25519" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4620d40f6d2601794401d6dd95a5cf69b6c157852539470eeda433a99b3c0efc" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519", + "rand 0.7.3", + "serde", + "sha2 0.9.5", + "zeroize", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "environmental" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b91989ae21441195d7d9b9993a2f9295c7e1a8c96255d8b729accddc124797" + +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "fixed-hash" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11498d382790b7a8f2fd211780bec78619bba81cdad3a283997c0c41f836759c" +dependencies = [ + "byteorder", + "rand 0.7.3", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "frame-metadatav10" +version = "10.0.0" +dependencies = [ + "parity-scale-codec", + "serde", + "sp-core", + "sp-std", +] + +[[package]] +name = "futures" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" + +[[package]] +name = "futures-executor" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582" + +[[package]] +name = "futures-macro" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57" +dependencies = [ + "autocfg", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" + +[[package]] +name = "futures-task" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2" + +[[package]] +name = "futures-util" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78" +dependencies = [ + "autocfg", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "gimli" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" + +[[package]] +name = "hash-db" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" + +[[package]] +name = "hash256-std-hasher" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" +dependencies = [ + "crunchy", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" +dependencies = [ + "crypto-mac", + "digest 0.8.1", +] + +[[package]] +name = "hmac-drbg" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" +dependencies = [ + "digest 0.8.1", + "generic-array 0.12.4", + "hmac", +] + +[[package]] +name = "impl-codec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-serde" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b47ca4d2b6931707a55fce5cf66aff80e2178c8b63bbb4ecb5695cbc870ddf6f" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "instant" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "itoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" + +[[package]] +name = "keccak" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" + +[[package]] +name = "libsecp256k1" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" +dependencies = [ + "arrayref", + "crunchy", + "digest 0.8.1", + "hmac-drbg", + "rand 0.7.3", + "sha2 0.8.2", + "subtle 2.4.1", + "typenum", +] + +[[package]] +name = "lock_api" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "lock_api" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "matchers" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memory_units" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" + +[[package]] +name = "merlin" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e261cf0f8b3c42ded9f7d2bb59dea03aa52bc8a1cbc7482f9fc3fd1229d3b42" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2766204889d09937d00bfbb7fec56bb2a199e2ade963cab19185d8a6104c7c" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +dependencies = [ + "parking_lot 0.11.1", +] + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "parity-scale-codec" +version = "1.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b26b16c7687c3075982af47719e481815df30bc544f7a6690763a25ca16e9d" +dependencies = [ + "arrayvec 0.5.2", + "bitvec", + "byte-slice-cast", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41512944b1faff334a5f1b9447611bf4ef40638ccb6328173dacefb338e878c" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "parity-util-mem" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297ff91fa36aec49ce183484b102f6b75b46776822bd81525bfc4cc9b0dd0f5c" +dependencies = [ + "cfg-if 0.1.10", + "impl-trait-for-tuples", + "parity-util-mem-derive", + "primitive-types", + "winapi", +] + +[[package]] +name = "parity-util-mem-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" +dependencies = [ + "proc-macro2", + "syn", + "synstructure", +] + +[[package]] +name = "parity-wasm" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" + +[[package]] +name = "parking_lot" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" +dependencies = [ + "lock_api 0.3.4", + "parking_lot_core 0.7.2", +] + +[[package]] +name = "parking_lot" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +dependencies = [ + "instant", + "lock_api 0.4.4", + "parking_lot_core 0.8.3", +] + +[[package]] +name = "parking_lot_core" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" +dependencies = [ + "cfg-if 0.1.10", + "cloudabi", + "libc", + "redox_syscall 0.1.57", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall 0.2.10", + "smallvec", + "winapi", +] + +[[package]] +name = "pbkdf2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" +dependencies = [ + "byteorder", + "crypto-mac", +] + +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "primitive-types" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd39dcacf71411ba488570da7bbc89b717225e46478b30ba99b92db6b149809" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-serde", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro-nested" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" + +[[package]] +name = "proc-macro2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.3", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "ref-cast" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300f2a835d808734ee295d45007adacb9ebb29dd3ae2424acfa17930cae541da" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c38e3aecd2b21cb3959637b883bb3714bc7e43f0268b9a29d3743ee3e55cdd2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "rustc-demangle" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "schnorrkel" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "curve25519-dalek 2.1.3", + "getrandom 0.1.16", + "merlin", + "rand 0.7.3", + "rand_core 0.5.1", + "sha2 0.8.2", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "secrecy" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9182278ed645df3477a9c27bfee0621c621aa16f6972635f7f795dae3d81070f" +dependencies = [ + "zeroize", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "serde" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +dependencies = [ + "block-buffer 0.7.3", + "digest 0.8.1", + "fake-simd", + "opaque-debug 0.2.3", +] + +[[package]] +name = "sha2" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "sharded-slab" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740223c51853f3145fe7c90360d2d4232f2b62e3449489c207eccde818979982" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signature" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335" + +[[package]] +name = "slab" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" + +[[package]] +name = "smallvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" + +[[package]] +name = "sp-core" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "base58", + "blake2-rfc", + "byteorder", + "derive_more", + "dyn-clonable", + "ed25519-dalek", + "futures", + "hash-db", + "hash256-std-hasher", + "hex", + "impl-serde", + "lazy_static", + "libsecp256k1", + "log", + "merlin", + "num-traits", + "parity-scale-codec", + "parity-util-mem", + "parking_lot 0.10.2", + "primitive-types", + "rand 0.7.3", + "regex", + "schnorrkel", + "secrecy", + "serde", + "sha2 0.8.2", + "sp-debug-derive", + "sp-externalities", + "sp-runtime-interface", + "sp-std", + "sp-storage", + "substrate-bip39", + "tiny-bip39", + "tiny-keccak", + "twox-hash", + "wasmi", + "zeroize", +] + +[[package]] +name = "sp-debug-derive" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-externalities" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "environmental", + "parity-scale-codec", + "sp-std", + "sp-storage", +] + +[[package]] +name = "sp-runtime-interface" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "parity-scale-codec", + "primitive-types", + "sp-externalities", + "sp-runtime-interface-proc-macro", + "sp-std", + "sp-storage", + "sp-tracing", + "sp-wasm-interface", + "static_assertions", +] + +[[package]] +name = "sp-runtime-interface-proc-macro" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "Inflector", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-std" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" + +[[package]] +name = "sp-storage" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "impl-serde", + "parity-scale-codec", + "ref-cast", + "serde", + "sp-debug-derive", + "sp-std", +] + +[[package]] +name = "sp-tracing" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "log", + "parity-scale-codec", + "sp-std", + "tracing", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "sp-wasm-interface" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "impl-trait-for-tuples", + "parity-scale-codec", + "sp-std", + "wasmi", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "substrate-bip39" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bed6646a0159b9935b5d045611560eeef842b78d7adc3ba36f5ca325a13a0236" +dependencies = [ + "hmac", + "pbkdf2", + "schnorrkel", + "sha2 0.8.2", + "zeroize", +] + +[[package]] +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "474aaa926faa1603c40b7885a9eaea29b444d1cb2850cb7c0e37bb1a4182f4fa" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "thread_local" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tiny-bip39" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0165e045cc2ae1660270ca65e1676dbaab60feb0f91b10f7d0665e9b47e31f2" +dependencies = [ + "failure", + "hmac", + "once_cell", + "pbkdf2", + "rand 0.7.3", + "rustc-hash", + "sha2 0.8.2", + "unicode-normalization", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +dependencies = [ + "cfg-if 1.0.0", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ca517f43f0fb96e0c3072ed5c275fe5eece87e8cb52f4a77b69226d3b1c9df8" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tracing-log" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cbe87a2fa7e35900ce5de20220a582a9483a7063811defce79d7cbd59d4cfe" +dependencies = [ + "ansi_term", + "chrono", + "lazy_static", + "matchers", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "twox-hash" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f559b464de2e2bdabcac6a210d12e9b5a5973c251e102c44c585c71d51bd78e" +dependencies = [ + "cfg-if 1.0.0", + "rand 0.8.4", + "static_assertions", +] + +[[package]] +name = "typenum" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" + +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + +[[package]] +name = "uint" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9db035e67dfaf7edd9aebfe8676afcd63eed53c8a4044fed514c8cccf1835177" +dependencies = [ + "byteorder", + "crunchy", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasmi" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf617d864d25af3587aa745529f7aaa541066c876d57e050c0d0c85c61c92aff" +dependencies = [ + "libc", + "memory_units", + "num-rational", + "num-traits", + "parity-wasm", + "wasmi-validation", +] + +[[package]] +name = "wasmi-validation" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea78c597064ba73596099281e2f4cfc019075122a65cdda3205af94f0b264d93" +dependencies = [ + "parity-wasm", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "zeroize" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "377db0846015f7ae377174787dd452e1c5f5a9050bc6f954911d01f116daa0cd" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] diff --git a/substrate-metadata-versions/metadatav10/Cargo.toml b/substrate-metadata-versions/metadatav10/Cargo.toml new file mode 100644 index 00000000..00094381 --- /dev/null +++ b/substrate-metadata-versions/metadatav10/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "frame-metadatav10" +version = "10.0.0" +authors = ["Parity Technologies "] +edition = "2018" +license = "GPL-3.0" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1", default-features = false, features = ["derive"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +sp-std = { version = "2.0.0-rc6", default-features = false, git = "https://github.com/paritytech/substrate" , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } +sp-core = { version = "2.0.0-rc6", default-features = false, git = "https://github.com/paritytech/substrate" , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } + +[features] +default = ["std"] +std = [ + "codec/std", + "sp-std/std", + "sp-core/std", + "serde", +] diff --git a/substrate-metadata-versions/metadatav10/src/lib.rs b/substrate-metadata-versions/metadatav10/src/lib.rs new file mode 100644 index 00000000..f6e280be --- /dev/null +++ b/substrate-metadata-versions/metadatav10/src/lib.rs @@ -0,0 +1,407 @@ +// Copyright 2018-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Decodable variant of the RuntimeMetadata. +//! +//! This really doesn't belong here, but is necessary for the moment. In the future +//! it should be removed entirely to an external module for shimming on to the +//! codec-encoded metadata. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(feature = "std")] +use serde::Serialize; +#[cfg(feature = "std")] +use codec::{Decode, Input, Error}; +use codec::{Encode, Output}; +use sp_std::vec::Vec; +use sp_core::RuntimeDebug; + +#[cfg(feature = "std")] +type StringBuf = String; + +/// Curent prefix of metadata +pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness + +/// On `no_std` we do not support `Decode` and thus `StringBuf` is just `&'static str`. +/// So, if someone tries to decode this stuff on `no_std`, they will get a compilation error. +#[cfg(not(feature = "std"))] +type StringBuf = &'static str; + +/// A type that decodes to a different type than it encodes. +/// The user needs to make sure that both types use the same encoding. +/// +/// For example a `&'static [ &'static str ]` can be decoded to a `Vec`. +#[derive(Clone)] +pub enum DecodeDifferent where B: 'static, O: 'static { + Encode(B), + Decoded(O), +} + +impl Encode for DecodeDifferent where B: Encode + 'static, O: Encode + 'static { + fn encode_to(&self, dest: &mut W) { + match self { + DecodeDifferent::Encode(b) => b.encode_to(dest), + DecodeDifferent::Decoded(o) => o.encode_to(dest), + } + } +} + +impl codec::EncodeLike for DecodeDifferent where B: Encode + 'static, O: Encode + 'static {} + +#[cfg(feature = "std")] +impl Decode for DecodeDifferent where B: 'static, O: Decode + 'static { + fn decode(input: &mut I) -> Result { + ::decode(input).map(|val| { + DecodeDifferent::Decoded(val) + }) + } +} + +impl PartialEq for DecodeDifferent +where + B: Encode + Eq + PartialEq + 'static, + O: Encode + Eq + PartialEq + 'static, +{ + fn eq(&self, other: &Self) -> bool { + self.encode() == other.encode() + } +} + +impl Eq for DecodeDifferent + where B: Encode + Eq + PartialEq + 'static, O: Encode + Eq + PartialEq + 'static +{} + +impl sp_std::fmt::Debug for DecodeDifferent + where + B: sp_std::fmt::Debug + Eq + 'static, + O: sp_std::fmt::Debug + Eq + 'static, +{ + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + match self { + DecodeDifferent::Encode(b) => b.fmt(f), + DecodeDifferent::Decoded(o) => o.fmt(f), + } + } +} + +#[cfg(feature = "std")] +impl serde::Serialize for DecodeDifferent + where + B: serde::Serialize + 'static, + O: serde::Serialize + 'static, +{ + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + match self { + DecodeDifferent::Encode(b) => b.serialize(serializer), + DecodeDifferent::Decoded(o) => o.serialize(serializer), + } + } +} + +pub type DecodeDifferentArray = DecodeDifferent<&'static [B], Vec>; + +type DecodeDifferentStr = DecodeDifferent<&'static str, StringBuf>; + +/// All the metadata about a function. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct FunctionMetadata { + pub name: DecodeDifferentStr, + pub arguments: DecodeDifferentArray, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about a function argument. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct FunctionArgumentMetadata { + pub name: DecodeDifferentStr, + pub ty: DecodeDifferentStr, +} + +/// Newtype wrapper for support encoding functions (actual the result of the function). +#[derive(Clone, Eq)] +pub struct FnEncode(pub fn() -> E) where E: Encode + 'static; + +impl Encode for FnEncode { + fn encode_to(&self, dest: &mut W) { + self.0().encode_to(dest); + } +} + +impl codec::EncodeLike for FnEncode {} + +impl PartialEq for FnEncode { + fn eq(&self, other: &Self) -> bool { + self.0().eq(&other.0()) + } +} + +impl sp_std::fmt::Debug for FnEncode { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + self.0().fmt(f) + } +} + +#[cfg(feature = "std")] +impl serde::Serialize for FnEncode { + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + self.0().serialize(serializer) + } +} + +/// All the metadata about an outer event. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct OuterEventMetadata { + pub name: DecodeDifferentStr, + pub events: DecodeDifferentArray< + (&'static str, FnEncode<&'static [EventMetadata]>), + (StringBuf, Vec) + >, +} + +/// All the metadata about an event. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct EventMetadata { + pub name: DecodeDifferentStr, + pub arguments: DecodeDifferentArray<&'static str, StringBuf>, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about one storage entry. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct StorageEntryMetadata { + pub name: DecodeDifferentStr, + pub modifier: StorageEntryModifier, + pub ty: StorageEntryType, + pub default: ByteGetter, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about one module constant. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct ModuleConstantMetadata { + pub name: DecodeDifferentStr, + pub ty: DecodeDifferentStr, + pub value: ByteGetter, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about a module error. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct ErrorMetadata { + pub name: DecodeDifferentStr, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about errors in a module. +pub trait ModuleErrorMetadata { + fn metadata() -> &'static [ErrorMetadata]; +} + +impl ModuleErrorMetadata for &'static str { + fn metadata() -> &'static [ErrorMetadata] { + &[] + } +} + +/// A technical trait to store lazy initiated vec value as static dyn pointer. +pub trait DefaultByte: Send + Sync { + fn default_byte(&self) -> Vec; +} + +/// Wrapper over dyn pointer for accessing a cached once byte value. +#[derive(Clone)] +pub struct DefaultByteGetter(pub &'static dyn DefaultByte); + +/// Decode different for static lazy initiated byte value. +pub type ByteGetter = DecodeDifferent>; + +impl Encode for DefaultByteGetter { + fn encode_to(&self, dest: &mut W) { + self.0.default_byte().encode_to(dest) + } +} + +impl codec::EncodeLike for DefaultByteGetter {} + +impl PartialEq for DefaultByteGetter { + fn eq(&self, other: &DefaultByteGetter) -> bool { + let left = self.0.default_byte(); + let right = other.0.default_byte(); + left.eq(&right) + } +} + +impl Eq for DefaultByteGetter { } + +#[cfg(feature = "std")] +impl serde::Serialize for DefaultByteGetter { + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + self.0.default_byte().serialize(serializer) + } +} + +impl sp_std::fmt::Debug for DefaultByteGetter { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + self.0.default_byte().fmt(f) + } +} + +/// Hasher used by storage maps +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub enum StorageHasher { + Blake2_128, + Blake2_256, + Blake2_128Concat, + Twox128, + Twox256, + Twox64Concat, +} + +/// A storage entry type. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub enum StorageEntryType { + Plain(DecodeDifferentStr), + Map { + hasher: StorageHasher, + key: DecodeDifferentStr, + value: DecodeDifferentStr, + is_linked: bool, + }, + DoubleMap { + hasher: StorageHasher, + key1: DecodeDifferentStr, + key2: DecodeDifferentStr, + value: DecodeDifferentStr, + key2_hasher: StorageHasher, + }, +} + +/// A storage entry modifier. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub enum StorageEntryModifier { + Optional, + Default, +} + +/// All metadata of the storage. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct StorageMetadata { + /// The common prefix used by all storage entries. + pub prefix: DecodeDifferent<&'static str, StringBuf>, + pub entries: DecodeDifferent<&'static [StorageEntryMetadata], Vec>, +} + +#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +/// Metadata prefixed by a u32 for reserved usage +pub struct RuntimeMetadataPrefixed(pub u32, pub RuntimeMetadata); + +/// The metadata of a runtime. +/// The version ID encoded/decoded through +/// the enum nature of `RuntimeMetadata`. +#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub enum RuntimeMetadata { + /// Unused; enum filler. + V0(RuntimeMetadataDeprecated), + /// Version 1 for runtime metadata. No longer used. + V1(RuntimeMetadataDeprecated), + /// Version 2 for runtime metadata. No longer used. + V2(RuntimeMetadataDeprecated), + /// Version 3 for runtime metadata. No longer used. + V3(RuntimeMetadataDeprecated), + /// Version 4 for runtime metadata. No longer used. + V4(RuntimeMetadataDeprecated), + /// Version 5 for runtime metadata. No longer used. + V5(RuntimeMetadataDeprecated), + /// Version 6 for runtime metadata. No longer used. + V6(RuntimeMetadataDeprecated), + /// Version 7 for runtime metadata. No longer used. + V7(RuntimeMetadataDeprecated), + /// Version 8 for runtime metadata. No longer used. + V8(RuntimeMetadataDeprecated), + /// Version 9 for runtime metadata. No longer used. + V9(RuntimeMetadataDeprecated), + /// Version 10 for runtime metadata. + V10(RuntimeMetadataV10), +} + +/// Enum that should fail. +#[derive(Eq, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize))] +pub enum RuntimeMetadataDeprecated { } + +impl Encode for RuntimeMetadataDeprecated { + fn encode_to(&self, _dest: &mut W) {} +} + +impl codec::EncodeLike for RuntimeMetadataDeprecated {} + +#[cfg(feature = "std")] +impl Decode for RuntimeMetadataDeprecated { + fn decode(_input: &mut I) -> Result { + Err("Decoding is not supported".into()) + } +} + +/// The metadata of a runtime. +#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct RuntimeMetadataV10 { + pub modules: DecodeDifferentArray, +} + +/// The latest version of the metadata. +pub type RuntimeMetadataLastVersion = RuntimeMetadataV10; + +/// All metadata about an runtime module. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct ModuleMetadata { + pub name: DecodeDifferentStr, + pub storage: Option, StorageMetadata>>, + pub calls: ODFnA, + pub event: ODFnA, + pub constants: DFnA, + pub errors: DFnA, +} + +type ODFnA = Option>; +type DFnA = DecodeDifferent, Vec>; + +impl Into for RuntimeMetadataPrefixed { + fn into(self) -> sp_core::OpaqueMetadata { + sp_core::OpaqueMetadata::new(self.encode()) + } +} + +impl Into for RuntimeMetadataLastVersion { + fn into(self) -> RuntimeMetadataPrefixed { + RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V10(self)) + } +} diff --git a/Cargo.lock b/substrate-metadata-versions/metadatav11/Cargo.lock similarity index 50% rename from Cargo.lock rename to substrate-metadata-versions/metadatav11/Cargo.lock index 2278ab7c..979ced02 100644 --- a/Cargo.lock +++ b/substrate-metadata-versions/metadatav11/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "Inflector" version = "0.11.4" @@ -12,9 +14,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.14.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423" +checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072" dependencies = [ "gimli", ] @@ -25,30 +27,15 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" -[[package]] -name = "ahash" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217" - [[package]] name = "aho-corasick" -version = "0.7.15" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +checksum = "b476ce7103678b0c6d3d395dbbae31d48ff910bd28be979ba5d48c6351131d0d" dependencies = [ "memchr", ] -[[package]] -name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -dependencies = [ - "winapi", -] - [[package]] name = "ansi_term" version = "0.12.1" @@ -58,21 +45,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "anyhow" -version = "1.0.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7" - -[[package]] -name = "approx" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" -dependencies = [ - "num-traits", -] - [[package]] name = "arrayref" version = "0.3.6" @@ -94,28 +66,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" -[[package]] -name = "async-trait" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3a45e77e34375a7923b1e8febb049bb011f064714a8e17a1a616fef01da13d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.0.1" @@ -124,9 +74,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "backtrace" -version = "0.3.55" +version = "0.3.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef5140344c85b01f9bbb4d4b7288a8aa4b3287ccef913a14bcc78a1063623598" +checksum = "707b586e0e2f247cbde68cdd2c3ce69ea7b7be43e1c5b426e37c9319c4b9838e" dependencies = [ "addr2line", "cfg-if 1.0.0", @@ -142,30 +92,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" -[[package]] -name = "bindgen" -version = "0.55.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b13ce559e6433d360c26305643803cb52cfbabbc2b9c47ce04a58493dfb443" -dependencies = [ - "bitflags", - "cexpr", - "cfg-if 0.1.10", - "clang-sys", - "clap", - "env_logger", - "lazy_static", - "lazycell", - "log", - "peeking_take_while", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "which", -] - [[package]] name = "bitflags" version = "1.2.1" @@ -242,18 +168,9 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" [[package]] name = "cc" -version = "1.0.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95752358c8f7552394baf48cd82695b345628ad3f170d607de3ca03b8dacca15" - -[[package]] -name = "cexpr" -version = "0.4.0" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" -dependencies = [ - "nom", -] +checksum = "ed67cbde08356238e75fc4656be4749481eeffb09e19f320a25237d5221c985d" [[package]] name = "cfg-if" @@ -280,32 +197,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "clang-sys" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0659001ab56b791be01d4b729c44376edc6718cf389a502e579b77b758f3296c" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "clap" -version = "2.33.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" -dependencies = [ - "ansi_term 0.11.0", - "atty", - "bitflags", - "strsim", - "textwrap", - "unicode-width", - "vec_map", -] - [[package]] name = "cloudabi" version = "0.0.3" @@ -352,16 +243,6 @@ dependencies = [ "subtle 1.0.0", ] -[[package]] -name = "crypto-mac" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" -dependencies = [ - "generic-array 0.14.4", - "subtle 2.3.0", -] - [[package]] name = "curve25519-dalek" version = "2.1.0" @@ -399,47 +280,6 @@ dependencies = [ "syn", ] -[[package]] -name = "desub-core" -version = "0.0.1" -dependencies = [ - "derive_more", - "desub-extras", - "dyn-clone", - "frame-metadata", - "frame-metadatav10", - "frame-metadatav11", - "frame-metadatav8", - "frame-metadatav9", - "hex", - "log", - "onig", - "pallet-democracy", - "pallet-identity", - "pallet-indices", - "parity-scale-codec", - "pretty_env_logger", - "serde", - "serde_json", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-runtime", - "sp-version", - "thiserror", -] - -[[package]] -name = "desub-extras" -version = "0.0.1" -dependencies = [ - "desub-core", - "env_logger", - "log", - "parity-scale-codec", - "serde", - "serde_json", - "thiserror", -] - [[package]] name = "digest" version = "0.8.1" @@ -504,7 +344,7 @@ dependencies = [ "ed25519", "rand", "serde", - "sha2 0.9.2", + "sha2 0.9.1", "zeroize", ] @@ -514,39 +354,6 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" -[[package]] -name = "enumflags2" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0" -dependencies = [ - "enumflags2_derive", -] - -[[package]] -name = "enumflags2_derive" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "env_logger" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - [[package]] name = "environmental" version = "1.1.2" @@ -593,158 +400,21 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "frame-benchmarking" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "frame-support", - "frame-system", - "linregress", - "parity-scale-codec", - "paste 0.1.18", - "sp-api", - "sp-io", - "sp-runtime", - "sp-runtime-interface 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-storage 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", -] - -[[package]] -name = "frame-metadata" -version = "12.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "parity-scale-codec", - "serde", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", -] - -[[package]] -name = "frame-metadatav10" -version = "10.0.0" -source = "git+https://github.com/insipx/substrate-metadata-versions?branch=master#ae8bf3acbc2d790838571df7fa30248fee0fb923" -dependencies = [ - "parity-scale-codec", - "serde", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", -] - [[package]] name = "frame-metadatav11" version = "11.0.0-rc6" -source = "git+https://github.com/insipx/substrate-metadata-versions?branch=master#ae8bf3acbc2d790838571df7fa30248fee0fb923" -dependencies = [ - "parity-scale-codec", - "serde", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", -] - -[[package]] -name = "frame-metadatav8" -version = "2.0.0" -source = "git+https://github.com/insipx/substrate-metadata-versions?branch=master#ae8bf3acbc2d790838571df7fa30248fee0fb923" -dependencies = [ - "parity-scale-codec", - "serde", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", -] - -[[package]] -name = "frame-metadatav9" -version = "2.0.0" -source = "git+https://github.com/insipx/substrate-metadata-versions?branch=master#ae8bf3acbc2d790838571df7fa30248fee0fb923" -dependencies = [ - "parity-scale-codec", - "serde", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", -] - -[[package]] -name = "frame-support" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "bitflags", - "frame-metadata", - "frame-support-procedural", - "impl-trait-for-tuples", - "log", - "once_cell", - "parity-scale-codec", - "paste 0.1.18", - "serde", - "smallvec", - "sp-arithmetic", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-inherents", - "sp-io", - "sp-runtime", - "sp-state-machine", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-tracing 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", -] - -[[package]] -name = "frame-support-procedural" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "frame-support-procedural-tools", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "frame-support-procedural-tools" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "frame-support-procedural-tools-derive", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "frame-support-procedural-tools-derive" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "frame-system" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" dependencies = [ - "frame-support", - "impl-trait-for-tuples", "parity-scale-codec", "serde", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-io", - "sp-runtime", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-version", + "sp-core", + "sp-std", ] [[package]] name = "futures" -version = "0.3.8" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3b0c040a1fe6529d30b3c5944b280c7f0dcb2930d2c3062bca967b602583d0" +checksum = "95314d38584ffbfda215621d723e0a3906f032e03ae5551e650058dac83d4797" dependencies = [ "futures-channel", "futures-core", @@ -757,9 +427,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.8" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b7109687aa4e177ef6fe84553af6280ef2778bdb7783ba44c9dc3399110fe64" +checksum = "0448174b01148032eed37ac4aed28963aaaa8cfa93569a08e5b479bbc6c2c151" dependencies = [ "futures-core", "futures-sink", @@ -767,15 +437,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.8" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "847ce131b72ffb13b6109a221da9ad97a64cbe48feb1028356b836b47b8f1748" +checksum = "18eaa56102984bed2c88ea39026cff3ce3b4c7f508ca970cedf2450ea10d4e46" [[package]] name = "futures-executor" -version = "0.3.8" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4caa2b2b68b880003057c1dd49f1ed937e38f22fcf6c212188a121f08cf40a65" +checksum = "f5f8e0c9258abaea85e78ebdda17ef9666d390e987f006be6080dfe354b708cb" dependencies = [ "futures-core", "futures-task", @@ -785,15 +455,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.8" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611834ce18aaa1bd13c4b374f5d653e1027cf99b6b502584ff8c9a64413b30bb" +checksum = "6e1798854a4727ff944a7b12aa999f58ce7aa81db80d2dfaaf2ba06f065ddd2b" [[package]] name = "futures-macro" -version = "0.3.8" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77408a692f1f97bcc61dc001d752e00643408fbc922e4d634c655df50d595556" +checksum = "e36fccf3fc58563b4a14d265027c627c3b665d7fed489427e88e7cc929559efe" dependencies = [ "proc-macro-hack", "proc-macro2", @@ -803,24 +473,24 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.8" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f878195a49cee50e006b02b93cf7e0a95a38ac7b776b4c4d9cc1207cd20fcb3d" +checksum = "0e3ca3f17d6e8804ae5d3df7a7d35b2b3a6fe89dac84b31872720fc3060a0b11" [[package]] name = "futures-task" -version = "0.3.8" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c554eb5bf48b2426c4771ab68c6b14468b6e76cc90996f528c3338d761a4d0d" +checksum = "96d502af37186c4fef99453df03e374683f8a1eec9dcc1e66b3b82dc8278ce3c" dependencies = [ "once_cell", ] [[package]] name = "futures-util" -version = "0.3.8" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d304cff4a7b99cfb7986f7d43fbe93d175e72e704a8860787cc95e9ffd85cbd2" +checksum = "abcb44342f62e6f3e8ac427b8aa815f724fd705dfad060b18ac7866c15bb8e34" dependencies = [ "futures-channel", "futures-core", @@ -858,15 +528,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "generic-array" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd" -dependencies = [ - "typenum", -] - [[package]] name = "generic-array" version = "0.14.4" @@ -890,15 +551,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce" - -[[package]] -name = "glob" -version = "0.3.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724" [[package]] name = "hash-db" @@ -915,31 +570,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "hashbrown" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25" -dependencies = [ - "ahash", - "autocfg", -] - -[[package]] -name = "hashbrown" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" - -[[package]] -name = "heck" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "hermit-abi" version = "0.1.17" @@ -961,20 +591,10 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" dependencies = [ - "crypto-mac 0.7.0", + "crypto-mac", "digest 0.8.1", ] -[[package]] -name = "hmac" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" -dependencies = [ - "crypto-mac 0.8.0", - "digest 0.9.0", -] - [[package]] name = "hmac-drbg" version = "0.2.0" @@ -983,16 +603,7 @@ checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" dependencies = [ "digest 0.8.1", "generic-array 0.12.3", - "hmac 0.7.1", -] - -[[package]] -name = "humantime" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -dependencies = [ - "quick-error", + "hmac", ] [[package]] @@ -1024,57 +635,20 @@ dependencies = [ "syn", ] -[[package]] -name = "indexmap" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2" -dependencies = [ - "autocfg", - "hashbrown 0.9.1", -] - [[package]] name = "instant" -version = "0.1.9" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" +checksum = "cb1fc4429a33e1f80d41dc9fea4d108a88bec1de8053878898ae448a0b52f613" dependencies = [ "cfg-if 1.0.0", ] [[package]] -name = "integer-sqrt" -version = "0.1.5" +name = "itoa" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" -dependencies = [ - "num-traits", -] - -[[package]] -name = "integration_tests" -version = "0.1.0" -dependencies = [ - "desub-core", - "desub-extras", - "frame-system", - "hex", - "log", - "pallet-balances", - "parity-scale-codec", - "paste 1.0.3", - "pretty_env_logger", - "serde", - "serde_json", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", -] - -[[package]] -name = "itoa" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" +checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" [[package]] name = "keccak" @@ -1088,34 +662,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "libc" version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" -[[package]] -name = "libloading" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9367bdfa836b7e3cf895867f7a570283444da90562980ec2263d6e1569b16bc" -dependencies = [ - "cfg-if 1.0.0", - "winapi", -] - -[[package]] -name = "libm" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" - [[package]] name = "libsecp256k1" version = "0.3.5" @@ -1132,16 +684,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "linregress" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d0ad4b5cc8385a881c561fac3501353d63d2a2b7a357b5064d71815c9a92724" -dependencies = [ - "nalgebra", - "statrs", -] - [[package]] name = "lock_api" version = "0.3.4" @@ -1153,9 +695,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312" +checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c" dependencies = [ "scopeguard", ] @@ -1191,31 +733,11 @@ dependencies = [ "regex-automata", ] -[[package]] -name = "matrixmultiply" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4f7ec66360130972f34830bfad9ef05c6610a43938a467bcc9ab9369ab3478f" -dependencies = [ - "rawpointer", -] - [[package]] name = "memchr" -version = "2.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" - -[[package]] -name = "memory-db" -version = "0.24.1" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f36ddb0b2cdc25d38babba472108798e3477f02be5165f038c5e393e50c57a" -dependencies = [ - "hash-db", - "hashbrown 0.8.2", - "parity-util-mem", -] +checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" [[package]] name = "memory_units" @@ -1245,40 +767,12 @@ dependencies = [ "autocfg", ] -[[package]] -name = "nalgebra" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6b6147c3d50b4f3cdabfe2ecc94a0191fd3d6ad58aefd9664cf396285883486" -dependencies = [ - "approx", - "generic-array 0.13.2", - "matrixmultiply", - "num-complex", - "num-rational", - "num-traits", - "rand", - "rand_distr", - "simba", - "typenum", -] - [[package]] name = "nodrop" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" -[[package]] -name = "nom" -version = "5.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" -dependencies = [ - "memchr", - "version_check", -] - [[package]] name = "num-bigint" version = "0.2.6" @@ -1290,21 +784,11 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-complex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" -dependencies = [ - "autocfg", - "num-traits", -] - [[package]] name = "num-integer" -version = "0.1.44" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" dependencies = [ "autocfg", "num-traits", @@ -1324,12 +808,11 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" dependencies = [ "autocfg", - "libm", ] [[package]] @@ -1344,40 +827,17 @@ dependencies = [ [[package]] name = "object" -version = "0.22.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" +checksum = "37fd5004feb2ce328a52b0b3d01dbf4ffff72583493900ed15f22d4111c51693" [[package]] name = "once_cell" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" -dependencies = [ - "parking_lot 0.11.1", -] - -[[package]] -name = "onig" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4e723fc996fff1aeab8f62205f3e8528bf498bdd5eadb2784d2d31f30077947" -dependencies = [ - "bitflags", - "lazy_static", - "libc", - "onig_sys", -] - -[[package]] -name = "onig_sys" -version = "69.6.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed063c96cf4c0f2e5d09324409d158b38a0a85a7b90fbd68c8cad75c495d5775" +checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad" dependencies = [ - "bindgen", - "cc", - "pkg-config", + "parking_lot 0.11.0", ] [[package]] @@ -1392,67 +852,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" -[[package]] -name = "pallet-balances" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "parity-scale-codec", - "serde", - "sp-runtime", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", -] - -[[package]] -name = "pallet-democracy" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "parity-scale-codec", - "serde", - "sp-io", - "sp-runtime", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", -] - -[[package]] -name = "pallet-identity" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "enumflags2", - "frame-benchmarking", - "frame-support", - "frame-system", - "parity-scale-codec", - "serde", - "sp-io", - "sp-runtime", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", -] - -[[package]] -name = "pallet-indices" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "frame-support", - "frame-system", - "parity-scale-codec", - "serde", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-io", - "sp-keyring", - "sp-runtime", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", -] - [[package]] name = "parity-scale-codec" version = "1.3.5" @@ -1485,10 +884,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "297ff91fa36aec49ce183484b102f6b75b46776822bd81525bfc4cc9b0dd0f5c" dependencies = [ "cfg-if 0.1.10", - "hashbrown 0.8.2", "impl-trait-for-tuples", "parity-util-mem-derive", - "parking_lot 0.10.2", "primitive-types", "winapi", ] @@ -1522,12 +919,12 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.11.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733" dependencies = [ "instant", - "lock_api 0.4.2", + "lock_api 0.4.1", "parking_lot_core 0.8.0", ] @@ -1560,31 +957,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "paste" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880" -dependencies = [ - "paste-impl", - "proc-macro-hack", -] - -[[package]] -name = "paste" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7151b083b0664ed58ed669fcdd92f01c3d2fdbf10af4931a301474950b52bfa9" - -[[package]] -name = "paste-impl" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6" -dependencies = [ - "proc-macro-hack", -] - [[package]] name = "pbkdf2" version = "0.3.0" @@ -1592,38 +964,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" dependencies = [ "byteorder", - "crypto-mac 0.7.0", -] - -[[package]] -name = "pbkdf2" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" -dependencies = [ - "crypto-mac 0.8.0", + "crypto-mac", ] -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - [[package]] name = "pin-project" -version = "1.0.2" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ccc2237c2c489783abd8c4c80e5450fc0e98644555b1364da68cc29aa151ca7" +checksum = "ee41d838744f60d959d7074e3afb6b35c7456d0f61cad38a24e35e6553f73841" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.2" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8e8d2bf0b23038a4424865103a4df472855692821aab4e4f5c3312d461d9e5f" +checksum = "81a4ffa594b66bff340084d4081df649a7dc049ac8d7fc458d8e628bfbbb2f86" dependencies = [ "proc-macro2", "quote", @@ -1632,9 +989,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.0" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b063f57ec186e6140e2b8b6921e5f1bd89c7356dda5b33acc5401203ca6131c" +checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b" [[package]] name = "pin-utils" @@ -1642,33 +999,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkg-config" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" - [[package]] name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - -[[package]] -name = "pretty_env_logger" -version = "0.4.0" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" -dependencies = [ - "env_logger", - "log", -] +checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20" [[package]] name = "primitive-types" -version = "0.7.3" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd39dcacf71411ba488570da7bbc89b717225e46478b30ba99b92db6b149809" +checksum = "c55c21c64d0eaa4d7ed885d959ef2d62d9e488c27c0e02d9aa5ce6c877b7d5f8" dependencies = [ "fixed-hash", "impl-codec", @@ -1687,9 +1028,9 @@ dependencies = [ [[package]] name = "proc-macro-hack" -version = "0.5.19" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" +checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598" [[package]] name = "proc-macro-nested" @@ -1706,12 +1047,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - [[package]] name = "quote" version = "1.0.7" @@ -1760,15 +1095,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rand_distr" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2" -dependencies = [ - "rand", -] - [[package]] name = "rand_hc" version = "0.2.0" @@ -1787,12 +1113,6 @@ dependencies = [ "rand_core", ] -[[package]] -name = "rawpointer" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" - [[package]] name = "redox_syscall" version = "0.1.57" @@ -1801,18 +1121,18 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "ref-cast" -version = "1.0.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17626b2f4bcf35b84bf379072a66e28cfe5c3c6ae58b38e4914bb8891dabece" +checksum = "745c1787167ddae5569661d5ffb8b25ae5fedbf46717eaa92d652221cec72623" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c523ccaed8ac4b0288948849a350b37d3035827413c458b6a40ddb614bb4f72" +checksum = "7d21b475ab879ef0e315ad99067fa25778c3b0377f57f1b00207448dac1a3144" dependencies = [ "proc-macro2", "quote", @@ -1821,9 +1141,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.4.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" +checksum = "8963b85b8ce3074fecffde43b4b0dded83ce2f367dc8d363afc56679f3ee820b" dependencies = [ "aho-corasick", "memchr", @@ -1843,9 +1163,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.21" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" +checksum = "8cab7a364d15cde1e505267766a2d3c4e22a843e1a601f0fa7564c0f82ced11c" [[package]] name = "rustc-demangle" @@ -1919,15 +1239,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "secrecy" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0673d6a6449f5e7d12a1caf424fd9363e2af3a4953023ed455e3c4beef4597c0" -dependencies = [ - "zeroize", -] - [[package]] name = "semver" version = "0.9.0" @@ -1965,11 +1276,10 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.60" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1500e84d27fe482ed1dc791a56eddc2f230046a040fa908c08bda1d9fb615779" +checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" dependencies = [ - "indexmap", "itoa", "ryu", "serde", @@ -1989,12 +1299,12 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.2" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e7aab86fe2149bad8c507606bdb3f4ef5e7b2380eb92350f56122cca72a42a8" +checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1" dependencies = [ "block-buffer 0.9.0", - "cfg-if 1.0.0", + "cfg-if 0.1.10", "cpuid-bool", "digest 0.9.0", "opaque-debug 0.3.0", @@ -2010,30 +1320,12 @@ dependencies = [ "loom", ] -[[package]] -name = "shlex" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" - [[package]] name = "signature" version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29f060a7d147e33490ec10da418795238fd7545bba241504d6b31a409f2e6210" -[[package]] -name = "simba" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb931b1367faadea6b1ab1c306a860ec17aaa5fa39f367d0c744e69d971a1fb2" -dependencies = [ - "approx", - "num-complex", - "num-traits", - "paste 0.1.18", -] - [[package]] name = "slab" version = "0.4.2" @@ -2042,62 +1334,9 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" [[package]] name = "smallvec" -version = "1.5.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7acad6f34eb9e8a259d3283d1e8c1d34d7415943d4895f65cc73813c7396fc85" - -[[package]] -name = "sp-api" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "hash-db", - "parity-scale-codec", - "sp-api-proc-macro", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-runtime", - "sp-state-machine", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-version", - "thiserror", -] - -[[package]] -name = "sp-api-proc-macro" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "blake2-rfc", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "sp-application-crypto" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "parity-scale-codec", - "serde", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-io", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", -] - -[[package]] -name = "sp-arithmetic" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "integer-sqrt", - "num-traits", - "parity-scale-codec", - "serde", - "sp-debug-derive 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", -] +checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252" [[package]] name = "sp-core" @@ -2127,16 +1366,16 @@ dependencies = [ "rand", "regex", "schnorrkel", - "secrecy 0.6.0", + "secrecy", "serde", "sha2 0.8.2", - "sp-debug-derive 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", - "sp-externalities 0.8.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", - "sp-runtime-interface 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", - "sp-storage 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", + "sp-debug-derive", + "sp-externalities", + "sp-runtime-interface", + "sp-std", + "sp-storage", "substrate-bip39", - "tiny-bip39 0.7.3", + "tiny-bip39", "tiny-keccak", "twox-hash", "wasmi", @@ -2144,63 +1383,9 @@ dependencies = [ ] [[package]] -name = "sp-core" +name = "sp-debug-derive" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "base58", - "blake2-rfc", - "byteorder", - "dyn-clonable", - "ed25519-dalek", - "futures", - "hash-db", - "hash256-std-hasher", - "hex", - "impl-serde", - "lazy_static", - "libsecp256k1", - "log", - "merlin", - "num-traits", - "parity-scale-codec", - "parity-util-mem", - "parking_lot 0.10.2", - "primitive-types", - "rand", - "regex", - "schnorrkel", - "secrecy 0.7.0", - "serde", - "sha2 0.8.2", - "sp-debug-derive 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-externalities 0.8.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-runtime-interface 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-storage 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "substrate-bip39", - "thiserror", - "tiny-bip39 0.8.0", - "tiny-keccak", - "twox-hash", - "wasmi", - "zeroize", -] - -[[package]] -name = "sp-debug-derive" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "sp-debug-derive" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" dependencies = [ "proc-macro2", "quote", @@ -2214,111 +1399,8 @@ source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef dependencies = [ "environmental", "parity-scale-codec", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", - "sp-storage 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", -] - -[[package]] -name = "sp-externalities" -version = "0.8.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "environmental", - "parity-scale-codec", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-storage 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", -] - -[[package]] -name = "sp-inherents" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "parity-scale-codec", - "parking_lot 0.10.2", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "thiserror", -] - -[[package]] -name = "sp-io" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "futures", - "hash-db", - "libsecp256k1", - "log", - "parity-scale-codec", - "parking_lot 0.10.2", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-externalities 0.8.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-keystore", - "sp-runtime-interface 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-state-machine", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-tracing 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-trie", - "sp-wasm-interface 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "tracing", - "tracing-core", -] - -[[package]] -name = "sp-keyring" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "lazy_static", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-runtime", - "strum", -] - -[[package]] -name = "sp-keystore" -version = "0.8.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "async-trait", - "derive_more", - "futures", - "merlin", - "parity-scale-codec", - "parking_lot 0.10.2", - "schnorrkel", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-externalities 0.8.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", -] - -[[package]] -name = "sp-panic-handler" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "backtrace", -] - -[[package]] -name = "sp-runtime" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "either", - "hash256-std-hasher", - "impl-trait-for-tuples", - "log", - "parity-scale-codec", - "parity-util-mem", - "paste 0.1.18", - "rand", - "serde", - "sp-application-crypto", - "sp-arithmetic", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-io", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", + "sp-std", + "sp-storage", ] [[package]] @@ -2328,28 +1410,12 @@ source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef dependencies = [ "parity-scale-codec", "primitive-types", - "sp-externalities 0.8.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", - "sp-runtime-interface-proc-macro 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", - "sp-storage 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", - "sp-tracing 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", - "sp-wasm-interface 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", - "static_assertions", -] - -[[package]] -name = "sp-runtime-interface" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "parity-scale-codec", - "primitive-types", - "sp-externalities 0.8.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-runtime-interface-proc-macro 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-storage 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-tracing 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-wasm-interface 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", + "sp-externalities", + "sp-runtime-interface-proc-macro", + "sp-std", + "sp-storage", + "sp-tracing", + "sp-wasm-interface", "static_assertions", ] @@ -2365,50 +1431,11 @@ dependencies = [ "syn", ] -[[package]] -name = "sp-runtime-interface-proc-macro" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "Inflector", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "sp-state-machine" -version = "0.8.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "hash-db", - "log", - "num-traits", - "parity-scale-codec", - "parking_lot 0.10.2", - "rand", - "smallvec", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-externalities 0.8.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-panic-handler", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-trie", - "thiserror", - "trie-db", - "trie-root", -] - [[package]] name = "sp-std" version = "2.0.0" source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -[[package]] -name = "sp-std" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" - [[package]] name = "sp-storage" version = "2.0.0" @@ -2418,21 +1445,8 @@ dependencies = [ "parity-scale-codec", "ref-cast", "serde", - "sp-debug-derive 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", -] - -[[package]] -name = "sp-storage" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "impl-serde", - "parity-scale-codec", - "ref-cast", - "serde", - "sp-debug-derive 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", + "sp-debug-derive", + "sp-std", ] [[package]] @@ -2442,51 +1456,12 @@ source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef dependencies = [ "log", "parity-scale-codec", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", + "sp-std", "tracing", "tracing-core", "tracing-subscriber", ] -[[package]] -name = "sp-tracing" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "log", - "parity-scale-codec", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "tracing", - "tracing-core", - "tracing-subscriber", -] - -[[package]] -name = "sp-trie" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "hash-db", - "memory-db", - "parity-scale-codec", - "sp-core 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", - "trie-db", - "trie-root", -] - -[[package]] -name = "sp-version" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "impl-serde", - "parity-scale-codec", - "serde", - "sp-runtime", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", -] - [[package]] name = "sp-wasm-interface" version = "2.0.0" @@ -2494,18 +1469,7 @@ source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2)", - "wasmi", -] - -[[package]] -name = "sp-wasm-interface" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3#a364e27d6e3971d756d28435efc468d95add52d3" -dependencies = [ - "impl-trait-for-tuples", - "parity-scale-codec", - "sp-std 2.0.0 (git+https://github.com/paritytech/substrate?rev=a364e27d6e3971d756d28435efc468d95add52d3)", + "sp-std", "wasmi", ] @@ -2515,50 +1479,14 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "statrs" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cce16f6de653e88beca7bd13780d08e09d4489dbca1f9210e041bc4852481382" -dependencies = [ - "rand", -] - -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "strum" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6138f8f88a16d90134763314e3fc76fa3ed6a7db4725d6acf9a3ef95a3188d22" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0054a7df764039a6cd8592b9de84be4bec368ff081d203a7d5371cbfa8e65c81" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "substrate-bip39" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bed6646a0159b9935b5d045611560eeef842b78d7adc3ba36f5ca325a13a0236" dependencies = [ - "hmac 0.7.1", - "pbkdf2 0.3.0", + "hmac", + "pbkdf2", "schnorrkel", "sha2 0.8.2", "zeroize", @@ -2578,9 +1506,9 @@ checksum = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd" [[package]] name = "syn" -version = "1.0.53" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8833e20724c24de12bbaba5ad230ea61c3eafb05b881c7c9d3cfe8638b187e68" +checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac" dependencies = [ "proc-macro2", "quote", @@ -2599,44 +1527,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "termcolor" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "thiserror" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "thread_local" version = "1.0.1" @@ -2664,33 +1554,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0165e045cc2ae1660270ca65e1676dbaab60feb0f91b10f7d0665e9b47e31f2" dependencies = [ "failure", - "hmac 0.7.1", + "hmac", "once_cell", - "pbkdf2 0.3.0", + "pbkdf2", "rand", "rustc-hash", "sha2 0.8.2", "unicode-normalization", ] -[[package]] -name = "tiny-bip39" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9e44c4759bae7f1032e286a7ef990bd9ed23fe831b7eeba0beb97484c2e59b8" -dependencies = [ - "anyhow", - "hmac 0.8.1", - "once_cell", - "pbkdf2 0.4.0", - "rand", - "rustc-hash", - "sha2 0.9.2", - "thiserror", - "unicode-normalization", - "zeroize", -] - [[package]] name = "tiny-keccak" version = "2.0.2" @@ -2702,18 +1574,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf8dbc19eb42fba10e8feaaec282fb50e2c14b2726d6301dbfeed0f73306a6f" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117" [[package]] name = "toml" @@ -2726,11 +1589,11 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.22" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f47026cdc4080c07e49b37087de021820269d996f581aac150ef9e5583eefe3" +checksum = "b0987850db3733619253fe60e17cb59b82d37c7e6c0236bb81e4d6b87c879f27" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 0.1.10", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -2779,11 +1642,11 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.2.15" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1fa8f0c8f4c594e4fc9debc1990deab13238077271ba84dd853d54902ee3401" +checksum = "2810660b9d5b18895d140caba6401765749a6a162e5d0736cfc44ea50db9d79d" dependencies = [ - "ansi_term 0.12.1", + "ansi_term", "chrono", "lazy_static", "matchers", @@ -2799,28 +1662,6 @@ dependencies = [ "tracing-serde", ] -[[package]] -name = "trie-db" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e55f7ace33d6237e14137e386f4e1672e2a5c6bbc97fef9f438581a143971f0" -dependencies = [ - "hash-db", - "hashbrown 0.8.2", - "log", - "rustc-hex", - "smallvec", -] - -[[package]] -name = "trie-root" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "652931506d2c1244d7217a70b99f56718a7b4161b37f04e7cd868072a99f68cd" -dependencies = [ - "hash-db", -] - [[package]] name = "twox-hash" version = "1.6.0" @@ -2852,37 +1693,19 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.16" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13e63ab62dbe32aeee58d1c5408d35c36c392bba5d9d3142287219721afe606" +checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-segmentation" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" - -[[package]] -name = "unicode-width" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" - [[package]] name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version_check" version = "0.9.2" @@ -2924,15 +1747,6 @@ dependencies = [ "parity-wasm", ] -[[package]] -name = "which" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" -dependencies = [ - "libc", -] - [[package]] name = "winapi" version = "0.3.9" @@ -2949,15 +1763,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/substrate-metadata-versions/metadatav11/Cargo.toml b/substrate-metadata-versions/metadatav11/Cargo.toml new file mode 100644 index 00000000..4884156e --- /dev/null +++ b/substrate-metadata-versions/metadatav11/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "frame-metadatav11" +version = "11.0.0-rc6" +authors = ["Parity Technologies "] +edition = "2018" +license = "Apache-2.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "Decodable variant of the RuntimeMetadata." +readme = "README.md" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +sp-std = { default-features = false, git = "https://github.com/paritytech/substrate" , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } +sp-core = { default-features = false, git = "https://github.com/paritytech/substrate" , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } + +[features] +default = ["std"] +std = [ + "codec/std", + "sp-std/std", + "sp-core/std", + "serde", +] diff --git a/substrate-metadata-versions/metadatav11/src/lib.rs b/substrate-metadata-versions/metadatav11/src/lib.rs new file mode 100644 index 00000000..c0eeb76b --- /dev/null +++ b/substrate-metadata-versions/metadatav11/src/lib.rs @@ -0,0 +1,425 @@ +// This file is part of Substrate. + +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Decodable variant of the RuntimeMetadata. +//! +//! This really doesn't belong here, but is necessary for the moment. In the future +//! it should be removed entirely to an external module for shimming on to the +//! codec-encoded metadata. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(feature = "std")] +use serde::Serialize; +#[cfg(feature = "std")] +use codec::{Decode, Input, Error}; +use codec::{Encode, Output}; +use sp_std::vec::Vec; +use sp_core::RuntimeDebug; + +#[cfg(feature = "std")] +type StringBuf = String; + +/// Current prefix of metadata +pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness + +/// On `no_std` we do not support `Decode` and thus `StringBuf` is just `&'static str`. +/// So, if someone tries to decode this stuff on `no_std`, they will get a compilation error. +#[cfg(not(feature = "std"))] +type StringBuf = &'static str; + +/// A type that decodes to a different type than it encodes. +/// The user needs to make sure that both types use the same encoding. +/// +/// For example a `&'static [ &'static str ]` can be decoded to a `Vec`. +#[derive(Clone)] +pub enum DecodeDifferent where B: 'static, O: 'static { + Encode(B), + Decoded(O), +} + +impl Encode for DecodeDifferent where B: Encode + 'static, O: Encode + 'static { + fn encode_to(&self, dest: &mut W) { + match self { + DecodeDifferent::Encode(b) => b.encode_to(dest), + DecodeDifferent::Decoded(o) => o.encode_to(dest), + } + } +} + +impl codec::EncodeLike for DecodeDifferent where B: Encode + 'static, O: Encode + 'static {} + +#[cfg(feature = "std")] +impl Decode for DecodeDifferent where B: 'static, O: Decode + 'static { + fn decode(input: &mut I) -> Result { + ::decode(input).map(|val| { + DecodeDifferent::Decoded(val) + }) + } +} + +impl PartialEq for DecodeDifferent +where + B: Encode + Eq + PartialEq + 'static, + O: Encode + Eq + PartialEq + 'static, +{ + fn eq(&self, other: &Self) -> bool { + self.encode() == other.encode() + } +} + +impl Eq for DecodeDifferent + where B: Encode + Eq + PartialEq + 'static, O: Encode + Eq + PartialEq + 'static +{} + +impl sp_std::fmt::Debug for DecodeDifferent + where + B: sp_std::fmt::Debug + Eq + 'static, + O: sp_std::fmt::Debug + Eq + 'static, +{ + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + match self { + DecodeDifferent::Encode(b) => b.fmt(f), + DecodeDifferent::Decoded(o) => o.fmt(f), + } + } +} + +#[cfg(feature = "std")] +impl serde::Serialize for DecodeDifferent + where + B: serde::Serialize + 'static, + O: serde::Serialize + 'static, +{ + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + match self { + DecodeDifferent::Encode(b) => b.serialize(serializer), + DecodeDifferent::Decoded(o) => o.serialize(serializer), + } + } +} + +pub type DecodeDifferentArray = DecodeDifferent<&'static [B], Vec>; + +type DecodeDifferentStr = DecodeDifferent<&'static str, StringBuf>; + +/// All the metadata about a function. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct FunctionMetadata { + pub name: DecodeDifferentStr, + pub arguments: DecodeDifferentArray, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about a function argument. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct FunctionArgumentMetadata { + pub name: DecodeDifferentStr, + pub ty: DecodeDifferentStr, +} + +/// Newtype wrapper for support encoding functions (actual the result of the function). +#[derive(Clone, Eq)] +pub struct FnEncode(pub fn() -> E) where E: Encode + 'static; + +impl Encode for FnEncode { + fn encode_to(&self, dest: &mut W) { + self.0().encode_to(dest); + } +} + +impl codec::EncodeLike for FnEncode {} + +impl PartialEq for FnEncode { + fn eq(&self, other: &Self) -> bool { + self.0().eq(&other.0()) + } +} + +impl sp_std::fmt::Debug for FnEncode { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + self.0().fmt(f) + } +} + +#[cfg(feature = "std")] +impl serde::Serialize for FnEncode { + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + self.0().serialize(serializer) + } +} + +/// All the metadata about an outer event. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct OuterEventMetadata { + pub name: DecodeDifferentStr, + pub events: DecodeDifferentArray< + (&'static str, FnEncode<&'static [EventMetadata]>), + (StringBuf, Vec) + >, +} + +/// All the metadata about an event. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct EventMetadata { + pub name: DecodeDifferentStr, + pub arguments: DecodeDifferentArray<&'static str, StringBuf>, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about one storage entry. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct StorageEntryMetadata { + pub name: DecodeDifferentStr, + pub modifier: StorageEntryModifier, + pub ty: StorageEntryType, + pub default: ByteGetter, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about one module constant. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct ModuleConstantMetadata { + pub name: DecodeDifferentStr, + pub ty: DecodeDifferentStr, + pub value: ByteGetter, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about a module error. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct ErrorMetadata { + pub name: DecodeDifferentStr, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about errors in a module. +pub trait ModuleErrorMetadata { + fn metadata() -> &'static [ErrorMetadata]; +} + +impl ModuleErrorMetadata for &'static str { + fn metadata() -> &'static [ErrorMetadata] { + &[] + } +} + +/// A technical trait to store lazy initiated vec value as static dyn pointer. +pub trait DefaultByte: Send + Sync { + fn default_byte(&self) -> Vec; +} + +/// Wrapper over dyn pointer for accessing a cached once byte value. +#[derive(Clone)] +pub struct DefaultByteGetter(pub &'static dyn DefaultByte); + +/// Decode different for static lazy initiated byte value. +pub type ByteGetter = DecodeDifferent>; + +impl Encode for DefaultByteGetter { + fn encode_to(&self, dest: &mut W) { + self.0.default_byte().encode_to(dest) + } +} + +impl codec::EncodeLike for DefaultByteGetter {} + +impl PartialEq for DefaultByteGetter { + fn eq(&self, other: &DefaultByteGetter) -> bool { + let left = self.0.default_byte(); + let right = other.0.default_byte(); + left.eq(&right) + } +} + +impl Eq for DefaultByteGetter { } + +#[cfg(feature = "std")] +impl serde::Serialize for DefaultByteGetter { + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + self.0.default_byte().serialize(serializer) + } +} + +impl sp_std::fmt::Debug for DefaultByteGetter { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + self.0.default_byte().fmt(f) + } +} + +/// Hasher used by storage maps +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub enum StorageHasher { + Blake2_128, + Blake2_256, + Blake2_128Concat, + Twox128, + Twox256, + Twox64Concat, + Identity, +} + +/// A storage entry type. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub enum StorageEntryType { + Plain(DecodeDifferentStr), + Map { + hasher: StorageHasher, + key: DecodeDifferentStr, + value: DecodeDifferentStr, + // is_linked flag previously, unused now to keep backwards compat + unused: bool, + }, + DoubleMap { + hasher: StorageHasher, + key1: DecodeDifferentStr, + key2: DecodeDifferentStr, + value: DecodeDifferentStr, + key2_hasher: StorageHasher, + }, +} + +/// A storage entry modifier. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub enum StorageEntryModifier { + Optional, + Default, +} + +/// All metadata of the storage. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct StorageMetadata { + /// The common prefix used by all storage entries. + pub prefix: DecodeDifferent<&'static str, StringBuf>, + pub entries: DecodeDifferent<&'static [StorageEntryMetadata], Vec>, +} + +/// Metadata prefixed by a u32 for reserved usage +#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct RuntimeMetadataPrefixed(pub u32, pub RuntimeMetadata); + +/// Metadata of the extrinsic used by the runtime. +#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct ExtrinsicMetadata { + /// Extrinsic version. + pub version: u8, + /// The signed extensions in the order they appear in the extrinsic. + pub signed_extensions: Vec, +} + +/// The metadata of a runtime. +/// The version ID encoded/decoded through +/// the enum nature of `RuntimeMetadata`. +#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub enum RuntimeMetadata { + /// Unused; enum filler. + V0(RuntimeMetadataDeprecated), + /// Version 1 for runtime metadata. No longer used. + V1(RuntimeMetadataDeprecated), + /// Version 2 for runtime metadata. No longer used. + V2(RuntimeMetadataDeprecated), + /// Version 3 for runtime metadata. No longer used. + V3(RuntimeMetadataDeprecated), + /// Version 4 for runtime metadata. No longer used. + V4(RuntimeMetadataDeprecated), + /// Version 5 for runtime metadata. No longer used. + V5(RuntimeMetadataDeprecated), + /// Version 6 for runtime metadata. No longer used. + V6(RuntimeMetadataDeprecated), + /// Version 7 for runtime metadata. No longer used. + V7(RuntimeMetadataDeprecated), + /// Version 8 for runtime metadata. No longer used. + V8(RuntimeMetadataDeprecated), + /// Version 9 for runtime metadata. No longer used. + V9(RuntimeMetadataDeprecated), + /// Version 10 for runtime metadata. No longer used. + V10(RuntimeMetadataDeprecated), + /// Version 11 for runtime metadata. + V11(RuntimeMetadataV11), +} + +/// Enum that should fail. +#[derive(Eq, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize))] +pub enum RuntimeMetadataDeprecated { } + +impl Encode for RuntimeMetadataDeprecated { + fn encode_to(&self, _dest: &mut W) {} +} + +impl codec::EncodeLike for RuntimeMetadataDeprecated {} + +#[cfg(feature = "std")] +impl Decode for RuntimeMetadataDeprecated { + fn decode(_input: &mut I) -> Result { + Err("Decoding is not supported".into()) + } +} + +/// The metadata of a runtime. +#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct RuntimeMetadataV11 { + /// Metadata of all the modules. + pub modules: DecodeDifferentArray, + /// Metadata of the extrinsic. + pub extrinsic: ExtrinsicMetadata, +} + +/// The latest version of the metadata. +pub type RuntimeMetadataLastVersion = RuntimeMetadataV11; + +/// All metadata about an runtime module. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct ModuleMetadata { + pub name: DecodeDifferentStr, + pub storage: Option, StorageMetadata>>, + pub calls: ODFnA, + pub event: ODFnA, + pub constants: DFnA, + pub errors: DFnA, +} + +type ODFnA = Option>; +type DFnA = DecodeDifferent, Vec>; + +impl Into for RuntimeMetadataPrefixed { + fn into(self) -> sp_core::OpaqueMetadata { + sp_core::OpaqueMetadata::new(self.encode()) + } +} + +impl Into for RuntimeMetadataLastVersion { + fn into(self) -> RuntimeMetadataPrefixed { + RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V11(self)) + } +} diff --git a/substrate-metadata-versions/metadatav8/Cargo.lock b/substrate-metadata-versions/metadatav8/Cargo.lock new file mode 100644 index 00000000..0a4e8aae --- /dev/null +++ b/substrate-metadata-versions/metadatav8/Cargo.lock @@ -0,0 +1,1803 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "addr2line" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", +] + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "backtrace" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01" +dependencies = [ + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base58" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitvec" +version = "0.17.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" +dependencies = [ + "either", + "radium", +] + +[[package]] +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +dependencies = [ + "arrayvec 0.4.12", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array 0.12.4", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array 0.14.4", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "byte-slice-cast" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cc" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "winapi", +] + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cpufeatures" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-mac" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +dependencies = [ + "generic-array 0.12.4", + "subtle 1.0.0", +] + +[[package]] +name = "curve25519-dalek" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b85542f99a2dfa2a1b8e192662741c9859a846b296bef1c92ef9b58b5a216" +dependencies = [ + "byteorder", + "digest 0.8.1", + "rand_core 0.5.1", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "derive_more" +version = "0.99.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.4", +] + +[[package]] +name = "dyn-clonable" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4" +dependencies = [ + "dyn-clonable-impl", + "dyn-clone", +] + +[[package]] +name = "dyn-clonable-impl" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dyn-clone" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" + +[[package]] +name = "ed25519" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4620d40f6d2601794401d6dd95a5cf69b6c157852539470eeda433a99b3c0efc" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519", + "rand 0.7.3", + "serde", + "sha2 0.9.5", + "zeroize", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "environmental" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b91989ae21441195d7d9b9993a2f9295c7e1a8c96255d8b729accddc124797" + +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "fixed-hash" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11498d382790b7a8f2fd211780bec78619bba81cdad3a283997c0c41f836759c" +dependencies = [ + "byteorder", + "rand 0.7.3", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "frame-metadatav8" +version = "2.0.0" +dependencies = [ + "parity-scale-codec", + "serde", + "sp-core", + "sp-std", +] + +[[package]] +name = "futures" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" + +[[package]] +name = "futures-executor" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582" + +[[package]] +name = "futures-macro" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57" +dependencies = [ + "autocfg", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" + +[[package]] +name = "futures-task" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2" + +[[package]] +name = "futures-util" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78" +dependencies = [ + "autocfg", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "gimli" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" + +[[package]] +name = "hash-db" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" + +[[package]] +name = "hash256-std-hasher" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" +dependencies = [ + "crunchy", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" +dependencies = [ + "crypto-mac", + "digest 0.8.1", +] + +[[package]] +name = "hmac-drbg" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" +dependencies = [ + "digest 0.8.1", + "generic-array 0.12.4", + "hmac", +] + +[[package]] +name = "impl-codec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-serde" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b47ca4d2b6931707a55fce5cf66aff80e2178c8b63bbb4ecb5695cbc870ddf6f" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "instant" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "itoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" + +[[package]] +name = "keccak" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" + +[[package]] +name = "libsecp256k1" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" +dependencies = [ + "arrayref", + "crunchy", + "digest 0.8.1", + "hmac-drbg", + "rand 0.7.3", + "sha2 0.8.2", + "subtle 2.4.1", + "typenum", +] + +[[package]] +name = "lock_api" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "lock_api" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "matchers" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memory_units" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" + +[[package]] +name = "merlin" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e261cf0f8b3c42ded9f7d2bb59dea03aa52bc8a1cbc7482f9fc3fd1229d3b42" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2766204889d09937d00bfbb7fec56bb2a199e2ade963cab19185d8a6104c7c" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +dependencies = [ + "parking_lot 0.11.1", +] + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "parity-scale-codec" +version = "1.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b26b16c7687c3075982af47719e481815df30bc544f7a6690763a25ca16e9d" +dependencies = [ + "arrayvec 0.5.2", + "bitvec", + "byte-slice-cast", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41512944b1faff334a5f1b9447611bf4ef40638ccb6328173dacefb338e878c" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "parity-util-mem" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297ff91fa36aec49ce183484b102f6b75b46776822bd81525bfc4cc9b0dd0f5c" +dependencies = [ + "cfg-if 0.1.10", + "impl-trait-for-tuples", + "parity-util-mem-derive", + "primitive-types", + "winapi", +] + +[[package]] +name = "parity-util-mem-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" +dependencies = [ + "proc-macro2", + "syn", + "synstructure", +] + +[[package]] +name = "parity-wasm" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" + +[[package]] +name = "parking_lot" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" +dependencies = [ + "lock_api 0.3.4", + "parking_lot_core 0.7.2", +] + +[[package]] +name = "parking_lot" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +dependencies = [ + "instant", + "lock_api 0.4.4", + "parking_lot_core 0.8.3", +] + +[[package]] +name = "parking_lot_core" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" +dependencies = [ + "cfg-if 0.1.10", + "cloudabi", + "libc", + "redox_syscall 0.1.57", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall 0.2.10", + "smallvec", + "winapi", +] + +[[package]] +name = "pbkdf2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" +dependencies = [ + "byteorder", + "crypto-mac", +] + +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "primitive-types" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd39dcacf71411ba488570da7bbc89b717225e46478b30ba99b92db6b149809" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-serde", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro-nested" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" + +[[package]] +name = "proc-macro2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.3", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "ref-cast" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300f2a835d808734ee295d45007adacb9ebb29dd3ae2424acfa17930cae541da" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c38e3aecd2b21cb3959637b883bb3714bc7e43f0268b9a29d3743ee3e55cdd2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "rustc-demangle" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "schnorrkel" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "curve25519-dalek 2.1.3", + "getrandom 0.1.16", + "merlin", + "rand 0.7.3", + "rand_core 0.5.1", + "sha2 0.8.2", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "secrecy" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9182278ed645df3477a9c27bfee0621c621aa16f6972635f7f795dae3d81070f" +dependencies = [ + "zeroize", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "serde" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +dependencies = [ + "block-buffer 0.7.3", + "digest 0.8.1", + "fake-simd", + "opaque-debug 0.2.3", +] + +[[package]] +name = "sha2" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "sharded-slab" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740223c51853f3145fe7c90360d2d4232f2b62e3449489c207eccde818979982" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signature" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335" + +[[package]] +name = "slab" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" + +[[package]] +name = "smallvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" + +[[package]] +name = "sp-core" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "base58", + "blake2-rfc", + "byteorder", + "derive_more", + "dyn-clonable", + "ed25519-dalek", + "futures", + "hash-db", + "hash256-std-hasher", + "hex", + "impl-serde", + "lazy_static", + "libsecp256k1", + "log", + "merlin", + "num-traits", + "parity-scale-codec", + "parity-util-mem", + "parking_lot 0.10.2", + "primitive-types", + "rand 0.7.3", + "regex", + "schnorrkel", + "secrecy", + "serde", + "sha2 0.8.2", + "sp-debug-derive", + "sp-externalities", + "sp-runtime-interface", + "sp-std", + "sp-storage", + "substrate-bip39", + "tiny-bip39", + "tiny-keccak", + "twox-hash", + "wasmi", + "zeroize", +] + +[[package]] +name = "sp-debug-derive" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-externalities" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "environmental", + "parity-scale-codec", + "sp-std", + "sp-storage", +] + +[[package]] +name = "sp-runtime-interface" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "parity-scale-codec", + "primitive-types", + "sp-externalities", + "sp-runtime-interface-proc-macro", + "sp-std", + "sp-storage", + "sp-tracing", + "sp-wasm-interface", + "static_assertions", +] + +[[package]] +name = "sp-runtime-interface-proc-macro" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "Inflector", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-std" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" + +[[package]] +name = "sp-storage" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "impl-serde", + "parity-scale-codec", + "ref-cast", + "serde", + "sp-debug-derive", + "sp-std", +] + +[[package]] +name = "sp-tracing" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "log", + "parity-scale-codec", + "sp-std", + "tracing", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "sp-wasm-interface" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "impl-trait-for-tuples", + "parity-scale-codec", + "sp-std", + "wasmi", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "substrate-bip39" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bed6646a0159b9935b5d045611560eeef842b78d7adc3ba36f5ca325a13a0236" +dependencies = [ + "hmac", + "pbkdf2", + "schnorrkel", + "sha2 0.8.2", + "zeroize", +] + +[[package]] +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "474aaa926faa1603c40b7885a9eaea29b444d1cb2850cb7c0e37bb1a4182f4fa" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "thread_local" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tiny-bip39" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0165e045cc2ae1660270ca65e1676dbaab60feb0f91b10f7d0665e9b47e31f2" +dependencies = [ + "failure", + "hmac", + "once_cell", + "pbkdf2", + "rand 0.7.3", + "rustc-hash", + "sha2 0.8.2", + "unicode-normalization", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +dependencies = [ + "cfg-if 1.0.0", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ca517f43f0fb96e0c3072ed5c275fe5eece87e8cb52f4a77b69226d3b1c9df8" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tracing-log" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cbe87a2fa7e35900ce5de20220a582a9483a7063811defce79d7cbd59d4cfe" +dependencies = [ + "ansi_term", + "chrono", + "lazy_static", + "matchers", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "twox-hash" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f559b464de2e2bdabcac6a210d12e9b5a5973c251e102c44c585c71d51bd78e" +dependencies = [ + "cfg-if 1.0.0", + "rand 0.8.4", + "static_assertions", +] + +[[package]] +name = "typenum" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" + +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + +[[package]] +name = "uint" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9db035e67dfaf7edd9aebfe8676afcd63eed53c8a4044fed514c8cccf1835177" +dependencies = [ + "byteorder", + "crunchy", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasmi" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf617d864d25af3587aa745529f7aaa541066c876d57e050c0d0c85c61c92aff" +dependencies = [ + "libc", + "memory_units", + "num-rational", + "num-traits", + "parity-wasm", + "wasmi-validation", +] + +[[package]] +name = "wasmi-validation" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea78c597064ba73596099281e2f4cfc019075122a65cdda3205af94f0b264d93" +dependencies = [ + "parity-wasm", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "zeroize" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "377db0846015f7ae377174787dd452e1c5f5a9050bc6f954911d01f116daa0cd" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] diff --git a/substrate-metadata-versions/metadatav8/Cargo.toml b/substrate-metadata-versions/metadatav8/Cargo.toml new file mode 100644 index 00000000..97d020e9 --- /dev/null +++ b/substrate-metadata-versions/metadatav8/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "frame-metadatav8" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1", default-features = false, features = ["derive"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +rstd = { package = "sp-std", git = "https://github.com/paritytech/substrate", default-features = false , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } +primitives = { package = "sp-core", git = "https://github.com/paritytech/substrate", default-features = false , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } + + + +[features] +default = ["std"] +std = [ + "codec/std", + "rstd/std", + "primitives/std", + "serde", +] + diff --git a/substrate-metadata-versions/metadatav8/src/lib.rs b/substrate-metadata-versions/metadatav8/src/lib.rs new file mode 100644 index 00000000..244d1175 --- /dev/null +++ b/substrate-metadata-versions/metadatav8/src/lib.rs @@ -0,0 +1,407 @@ +// Copyright 2018-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Decodable variant of the RuntimeMetadata. +//! +//! This really doesn't belong here, but is necessary for the moment. In the future +//! it should be removed entirely to an external module for shimming on to the +//! codec-encoded metadata. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(feature = "std")] +use serde::Serialize; +#[cfg(feature = "std")] +use codec::{Decode, Input, Error}; +use codec::{Encode, Output}; +use rstd::vec::Vec; + +#[cfg(feature = "std")] +type StringBuf = String; + +/// Curent prefix of metadata +pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness + +/// On `no_std` we do not support `Decode` and thus `StringBuf` is just `&'static str`. +/// So, if someone tries to decode this stuff on `no_std`, they will get a compilation error. +#[cfg(not(feature = "std"))] +type StringBuf = &'static str; + +/// A type that decodes to a different type than it encodes. +/// The user needs to make sure that both types use the same encoding. +/// +/// For example a `&'static [ &'static str ]` can be decoded to a `Vec`. +#[derive(Clone)] +pub enum DecodeDifferent where B: 'static, O: 'static { + Encode(B), + Decoded(O), +} + +impl Encode for DecodeDifferent where B: Encode + 'static, O: Encode + 'static { + fn encode_to(&self, dest: &mut W) { + match self { + DecodeDifferent::Encode(b) => b.encode_to(dest), + DecodeDifferent::Decoded(o) => o.encode_to(dest), + } + } +} + +impl codec::EncodeLike for DecodeDifferent where B: Encode + 'static, O: Encode + 'static {} + +#[cfg(feature = "std")] +impl Decode for DecodeDifferent where B: 'static, O: Decode + 'static { + fn decode(input: &mut I) -> Result { + ::decode(input).map(|val| { + DecodeDifferent::Decoded(val) + }) + } +} + +impl PartialEq for DecodeDifferent +where + B: Encode + Eq + PartialEq + 'static, + O: Encode + Eq + PartialEq + 'static, +{ + fn eq(&self, other: &Self) -> bool { + self.encode() == other.encode() + } +} + +impl Eq for DecodeDifferent + where B: Encode + Eq + PartialEq + 'static, O: Encode + Eq + PartialEq + 'static +{} + +#[cfg(feature = "std")] +impl std::fmt::Debug for DecodeDifferent + where + B: std::fmt::Debug + Eq + 'static, + O: std::fmt::Debug + Eq + 'static, +{ + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + DecodeDifferent::Encode(b) => b.fmt(f), + DecodeDifferent::Decoded(o) => o.fmt(f), + } + } +} + +#[cfg(feature = "std")] +impl serde::Serialize for DecodeDifferent + where + B: serde::Serialize + 'static, + O: serde::Serialize + 'static, +{ + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + match self { + DecodeDifferent::Encode(b) => b.serialize(serializer), + DecodeDifferent::Decoded(o) => o.serialize(serializer), + } + } +} + +pub type DecodeDifferentArray = DecodeDifferent<&'static [B], Vec>; + +#[cfg(feature = "std")] +type DecodeDifferentStr = DecodeDifferent<&'static str, StringBuf>; +#[cfg(not(feature = "std"))] +type DecodeDifferentStr = DecodeDifferent<&'static str, StringBuf>; + +/// All the metadata about a function. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub struct FunctionMetadata { + pub name: DecodeDifferentStr, + pub arguments: DecodeDifferentArray, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about a function argument. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub struct FunctionArgumentMetadata { + pub name: DecodeDifferentStr, + pub ty: DecodeDifferentStr, +} + +/// Newtype wrapper for support encoding functions (actual the result of the function). +#[derive(Clone, Eq)] +pub struct FnEncode(pub fn() -> E) where E: Encode + 'static; + +impl Encode for FnEncode { + fn encode_to(&self, dest: &mut W) { + self.0().encode_to(dest); + } +} + +impl codec::EncodeLike for FnEncode {} + +impl PartialEq for FnEncode { + fn eq(&self, other: &Self) -> bool { + self.0().eq(&other.0()) + } +} + +#[cfg(feature = "std")] +impl std::fmt::Debug for FnEncode { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + self.0().fmt(f) + } +} + +#[cfg(feature = "std")] +impl serde::Serialize for FnEncode { + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + self.0().serialize(serializer) + } +} + +/// All the metadata about an outer event. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub struct OuterEventMetadata { + pub name: DecodeDifferentStr, + pub events: DecodeDifferentArray< + (&'static str, FnEncode<&'static [EventMetadata]>), + (StringBuf, Vec) + >, +} + +/// All the metadata about an event. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub struct EventMetadata { + pub name: DecodeDifferentStr, + pub arguments: DecodeDifferentArray<&'static str, StringBuf>, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about one storage entry. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub struct StorageEntryMetadata { + pub name: DecodeDifferentStr, + pub modifier: StorageEntryModifier, + pub ty: StorageEntryType, + pub default: ByteGetter, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about one module constant. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub struct ModuleConstantMetadata { + pub name: DecodeDifferentStr, + pub ty: DecodeDifferentStr, + pub value: ByteGetter, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about a module error. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub struct ErrorMetadata { + pub name: DecodeDifferentStr, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about errors in a module. +pub trait ModuleErrorMetadata { + fn metadata() -> &'static [ErrorMetadata]; +} + +impl ModuleErrorMetadata for &'static str { + fn metadata() -> &'static [ErrorMetadata] { + &[] + } +} + +/// A technical trait to store lazy initiated vec value as static dyn pointer. +pub trait DefaultByte: Send + Sync { + fn default_byte(&self) -> Vec; +} + +/// Wrapper over dyn pointer for accessing a cached once byte value. +#[derive(Clone)] +pub struct DefaultByteGetter(pub &'static dyn DefaultByte); + +/// Decode different for static lazy initiated byte value. +pub type ByteGetter = DecodeDifferent>; + +impl Encode for DefaultByteGetter { + fn encode_to(&self, dest: &mut W) { + self.0.default_byte().encode_to(dest) + } +} + +impl codec::EncodeLike for DefaultByteGetter {} + +impl PartialEq for DefaultByteGetter { + fn eq(&self, other: &DefaultByteGetter) -> bool { + let left = self.0.default_byte(); + let right = other.0.default_byte(); + left.eq(&right) + } +} + +impl Eq for DefaultByteGetter { } + +#[cfg(feature = "std")] +impl serde::Serialize for DefaultByteGetter { + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + self.0.default_byte().serialize(serializer) + } +} + +#[cfg(feature = "std")] +impl std::fmt::Debug for DefaultByteGetter { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + self.0.default_byte().fmt(f) + } +} + +/// Hasher used by storage maps +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub enum StorageHasher { + Blake2_128, + Blake2_256, + Twox128, + Twox256, + Twox64Concat, +} + +/// A storage entry type. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub enum StorageEntryType { + Plain(DecodeDifferentStr), + Map { + hasher: StorageHasher, + key: DecodeDifferentStr, + value: DecodeDifferentStr, + is_linked: bool, + }, + DoubleMap { + hasher: StorageHasher, + key1: DecodeDifferentStr, + key2: DecodeDifferentStr, + value: DecodeDifferentStr, + key2_hasher: StorageHasher, + }, +} + +/// A storage entry modifier. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub enum StorageEntryModifier { + Optional, + Default, +} + +/// All metadata of the storage. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub struct StorageMetadata { + /// The common prefix used by all storage entries. + pub prefix: DecodeDifferent<&'static str, StringBuf>, + pub entries: DecodeDifferent<&'static [StorageEntryMetadata], Vec>, +} + +#[derive(Eq, Encode, PartialEq)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +/// Metadata prefixed by a u32 for reserved usage +pub struct RuntimeMetadataPrefixed(pub u32, pub RuntimeMetadata); + +/// The metadata of a runtime. +/// The version ID encoded/decoded through +/// the enum nature of `RuntimeMetadata`. +#[derive(Eq, Encode, PartialEq)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub enum RuntimeMetadata { + /// Unused; enum filler. + V0(RuntimeMetadataDeprecated), + /// Version 1 for runtime metadata. No longer used. + V1(RuntimeMetadataDeprecated), + /// Version 2 for runtime metadata. No longer used. + V2(RuntimeMetadataDeprecated), + /// Version 3 for runtime metadata. No longer used. + V3(RuntimeMetadataDeprecated), + /// Version 4 for runtime metadata. No longer used. + V4(RuntimeMetadataDeprecated), + /// Version 5 for runtime metadata. No longer used. + V5(RuntimeMetadataDeprecated), + /// Version 6 for runtime metadata. No longer used. + V6(RuntimeMetadataDeprecated), + /// Version 7 for runtime metadata. No longer used. + V7(RuntimeMetadataDeprecated), + /// Version 8 for runtime metadata. + V8(RuntimeMetadataV8), +} + +/// Enum that should fail. +#[derive(Eq, PartialEq)] +#[cfg_attr(feature = "std", derive(Debug, Serialize))] +pub enum RuntimeMetadataDeprecated { } + +impl Encode for RuntimeMetadataDeprecated { + fn encode_to(&self, _dest: &mut W) {} +} + +impl codec::EncodeLike for RuntimeMetadataDeprecated {} + +#[cfg(feature = "std")] +impl Decode for RuntimeMetadataDeprecated { + fn decode(_input: &mut I) -> Result { + Err("Decoding is not supported".into()) + } +} + +/// The metadata of a runtime. +#[derive(Eq, Encode, PartialEq)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub struct RuntimeMetadataV8 { + pub modules: DecodeDifferentArray, +} + +/// The latest version of the metadata. +pub type RuntimeMetadataLastVersion = RuntimeMetadataV8; + +/// All metadata about an runtime module. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub struct ModuleMetadata { + pub name: DecodeDifferentStr, + pub storage: Option, StorageMetadata>>, + pub calls: ODFnA, + pub event: ODFnA, + pub constants: DFnA, + pub errors: DFnA, +} + +type ODFnA = Option>; +type DFnA = DecodeDifferent, Vec>; + +impl Into for RuntimeMetadataPrefixed { + fn into(self) -> primitives::OpaqueMetadata { + primitives::OpaqueMetadata::new(self.encode()) + } +} + +impl Into for RuntimeMetadataLastVersion { + fn into(self) -> RuntimeMetadataPrefixed { + RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V8(self)) + } +} diff --git a/substrate-metadata-versions/metadatav9/Cargo.lock b/substrate-metadata-versions/metadatav9/Cargo.lock new file mode 100644 index 00000000..9ad33a87 --- /dev/null +++ b/substrate-metadata-versions/metadatav9/Cargo.lock @@ -0,0 +1,1803 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "addr2line" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", +] + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "backtrace" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01" +dependencies = [ + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base58" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitvec" +version = "0.17.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" +dependencies = [ + "either", + "radium", +] + +[[package]] +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +dependencies = [ + "arrayvec 0.4.12", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array 0.12.4", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array 0.14.4", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "byte-slice-cast" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cc" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "winapi", +] + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cpufeatures" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-mac" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +dependencies = [ + "generic-array 0.12.4", + "subtle 1.0.0", +] + +[[package]] +name = "curve25519-dalek" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b85542f99a2dfa2a1b8e192662741c9859a846b296bef1c92ef9b58b5a216" +dependencies = [ + "byteorder", + "digest 0.8.1", + "rand_core 0.5.1", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "derive_more" +version = "0.99.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.4", +] + +[[package]] +name = "dyn-clonable" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4" +dependencies = [ + "dyn-clonable-impl", + "dyn-clone", +] + +[[package]] +name = "dyn-clonable-impl" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dyn-clone" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" + +[[package]] +name = "ed25519" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4620d40f6d2601794401d6dd95a5cf69b6c157852539470eeda433a99b3c0efc" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519", + "rand 0.7.3", + "serde", + "sha2 0.9.5", + "zeroize", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "environmental" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b91989ae21441195d7d9b9993a2f9295c7e1a8c96255d8b729accddc124797" + +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "fixed-hash" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11498d382790b7a8f2fd211780bec78619bba81cdad3a283997c0c41f836759c" +dependencies = [ + "byteorder", + "rand 0.7.3", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "frame-metadatav9" +version = "2.0.0" +dependencies = [ + "parity-scale-codec", + "serde", + "sp-core", + "sp-std", +] + +[[package]] +name = "futures" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" + +[[package]] +name = "futures-executor" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582" + +[[package]] +name = "futures-macro" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57" +dependencies = [ + "autocfg", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" + +[[package]] +name = "futures-task" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2" + +[[package]] +name = "futures-util" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78" +dependencies = [ + "autocfg", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "gimli" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" + +[[package]] +name = "hash-db" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" + +[[package]] +name = "hash256-std-hasher" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" +dependencies = [ + "crunchy", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" +dependencies = [ + "crypto-mac", + "digest 0.8.1", +] + +[[package]] +name = "hmac-drbg" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" +dependencies = [ + "digest 0.8.1", + "generic-array 0.12.4", + "hmac", +] + +[[package]] +name = "impl-codec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-serde" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b47ca4d2b6931707a55fce5cf66aff80e2178c8b63bbb4ecb5695cbc870ddf6f" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "instant" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "itoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" + +[[package]] +name = "keccak" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" + +[[package]] +name = "libsecp256k1" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" +dependencies = [ + "arrayref", + "crunchy", + "digest 0.8.1", + "hmac-drbg", + "rand 0.7.3", + "sha2 0.8.2", + "subtle 2.4.1", + "typenum", +] + +[[package]] +name = "lock_api" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "lock_api" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "matchers" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memory_units" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" + +[[package]] +name = "merlin" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e261cf0f8b3c42ded9f7d2bb59dea03aa52bc8a1cbc7482f9fc3fd1229d3b42" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2766204889d09937d00bfbb7fec56bb2a199e2ade963cab19185d8a6104c7c" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +dependencies = [ + "parking_lot 0.11.1", +] + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "parity-scale-codec" +version = "1.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b26b16c7687c3075982af47719e481815df30bc544f7a6690763a25ca16e9d" +dependencies = [ + "arrayvec 0.5.2", + "bitvec", + "byte-slice-cast", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41512944b1faff334a5f1b9447611bf4ef40638ccb6328173dacefb338e878c" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "parity-util-mem" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297ff91fa36aec49ce183484b102f6b75b46776822bd81525bfc4cc9b0dd0f5c" +dependencies = [ + "cfg-if 0.1.10", + "impl-trait-for-tuples", + "parity-util-mem-derive", + "primitive-types", + "winapi", +] + +[[package]] +name = "parity-util-mem-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" +dependencies = [ + "proc-macro2", + "syn", + "synstructure", +] + +[[package]] +name = "parity-wasm" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" + +[[package]] +name = "parking_lot" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" +dependencies = [ + "lock_api 0.3.4", + "parking_lot_core 0.7.2", +] + +[[package]] +name = "parking_lot" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +dependencies = [ + "instant", + "lock_api 0.4.4", + "parking_lot_core 0.8.3", +] + +[[package]] +name = "parking_lot_core" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" +dependencies = [ + "cfg-if 0.1.10", + "cloudabi", + "libc", + "redox_syscall 0.1.57", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall 0.2.10", + "smallvec", + "winapi", +] + +[[package]] +name = "pbkdf2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" +dependencies = [ + "byteorder", + "crypto-mac", +] + +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "primitive-types" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd39dcacf71411ba488570da7bbc89b717225e46478b30ba99b92db6b149809" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-serde", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro-nested" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" + +[[package]] +name = "proc-macro2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.3", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "ref-cast" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300f2a835d808734ee295d45007adacb9ebb29dd3ae2424acfa17930cae541da" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c38e3aecd2b21cb3959637b883bb3714bc7e43f0268b9a29d3743ee3e55cdd2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "rustc-demangle" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "schnorrkel" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "curve25519-dalek 2.1.3", + "getrandom 0.1.16", + "merlin", + "rand 0.7.3", + "rand_core 0.5.1", + "sha2 0.8.2", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "secrecy" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9182278ed645df3477a9c27bfee0621c621aa16f6972635f7f795dae3d81070f" +dependencies = [ + "zeroize", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "serde" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +dependencies = [ + "block-buffer 0.7.3", + "digest 0.8.1", + "fake-simd", + "opaque-debug 0.2.3", +] + +[[package]] +name = "sha2" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "sharded-slab" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740223c51853f3145fe7c90360d2d4232f2b62e3449489c207eccde818979982" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signature" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335" + +[[package]] +name = "slab" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" + +[[package]] +name = "smallvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" + +[[package]] +name = "sp-core" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "base58", + "blake2-rfc", + "byteorder", + "derive_more", + "dyn-clonable", + "ed25519-dalek", + "futures", + "hash-db", + "hash256-std-hasher", + "hex", + "impl-serde", + "lazy_static", + "libsecp256k1", + "log", + "merlin", + "num-traits", + "parity-scale-codec", + "parity-util-mem", + "parking_lot 0.10.2", + "primitive-types", + "rand 0.7.3", + "regex", + "schnorrkel", + "secrecy", + "serde", + "sha2 0.8.2", + "sp-debug-derive", + "sp-externalities", + "sp-runtime-interface", + "sp-std", + "sp-storage", + "substrate-bip39", + "tiny-bip39", + "tiny-keccak", + "twox-hash", + "wasmi", + "zeroize", +] + +[[package]] +name = "sp-debug-derive" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-externalities" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "environmental", + "parity-scale-codec", + "sp-std", + "sp-storage", +] + +[[package]] +name = "sp-runtime-interface" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "parity-scale-codec", + "primitive-types", + "sp-externalities", + "sp-runtime-interface-proc-macro", + "sp-std", + "sp-storage", + "sp-tracing", + "sp-wasm-interface", + "static_assertions", +] + +[[package]] +name = "sp-runtime-interface-proc-macro" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "Inflector", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-std" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" + +[[package]] +name = "sp-storage" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "impl-serde", + "parity-scale-codec", + "ref-cast", + "serde", + "sp-debug-derive", + "sp-std", +] + +[[package]] +name = "sp-tracing" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "log", + "parity-scale-codec", + "sp-std", + "tracing", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "sp-wasm-interface" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "impl-trait-for-tuples", + "parity-scale-codec", + "sp-std", + "wasmi", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "substrate-bip39" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bed6646a0159b9935b5d045611560eeef842b78d7adc3ba36f5ca325a13a0236" +dependencies = [ + "hmac", + "pbkdf2", + "schnorrkel", + "sha2 0.8.2", + "zeroize", +] + +[[package]] +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "474aaa926faa1603c40b7885a9eaea29b444d1cb2850cb7c0e37bb1a4182f4fa" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "thread_local" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tiny-bip39" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0165e045cc2ae1660270ca65e1676dbaab60feb0f91b10f7d0665e9b47e31f2" +dependencies = [ + "failure", + "hmac", + "once_cell", + "pbkdf2", + "rand 0.7.3", + "rustc-hash", + "sha2 0.8.2", + "unicode-normalization", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +dependencies = [ + "cfg-if 1.0.0", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ca517f43f0fb96e0c3072ed5c275fe5eece87e8cb52f4a77b69226d3b1c9df8" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tracing-log" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cbe87a2fa7e35900ce5de20220a582a9483a7063811defce79d7cbd59d4cfe" +dependencies = [ + "ansi_term", + "chrono", + "lazy_static", + "matchers", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "twox-hash" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f559b464de2e2bdabcac6a210d12e9b5a5973c251e102c44c585c71d51bd78e" +dependencies = [ + "cfg-if 1.0.0", + "rand 0.8.4", + "static_assertions", +] + +[[package]] +name = "typenum" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" + +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + +[[package]] +name = "uint" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9db035e67dfaf7edd9aebfe8676afcd63eed53c8a4044fed514c8cccf1835177" +dependencies = [ + "byteorder", + "crunchy", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasmi" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf617d864d25af3587aa745529f7aaa541066c876d57e050c0d0c85c61c92aff" +dependencies = [ + "libc", + "memory_units", + "num-rational", + "num-traits", + "parity-wasm", + "wasmi-validation", +] + +[[package]] +name = "wasmi-validation" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea78c597064ba73596099281e2f4cfc019075122a65cdda3205af94f0b264d93" +dependencies = [ + "parity-wasm", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "zeroize" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "377db0846015f7ae377174787dd452e1c5f5a9050bc6f954911d01f116daa0cd" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] diff --git a/substrate-metadata-versions/metadatav9/Cargo.toml b/substrate-metadata-versions/metadatav9/Cargo.toml new file mode 100644 index 00000000..6f864429 --- /dev/null +++ b/substrate-metadata-versions/metadatav9/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "frame-metadatav9" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1", default-features = false, features = ["derive"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +rstd = { package = "sp-std", git = "https://github.com/paritytech/substrate", default-features = false , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } +primitives = { package = "sp-core", git = "https://github.com/paritytech/substrate", default-features = false , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } + +[features] +default = ["std"] +std = [ + "codec/std", + "rstd/std", + "primitives/std", + "serde", +] diff --git a/substrate-metadata-versions/metadatav9/src/lib.rs b/substrate-metadata-versions/metadatav9/src/lib.rs new file mode 100644 index 00000000..b89079fa --- /dev/null +++ b/substrate-metadata-versions/metadatav9/src/lib.rs @@ -0,0 +1,405 @@ +// Copyright 2018-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Decodable variant of the RuntimeMetadata. +//! +//! This really doesn't belong here, but is necessary for the moment. In the future +//! it should be removed entirely to an external module for shimming on to the +//! codec-encoded metadata. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(feature = "std")] +use serde::Serialize; +#[cfg(feature = "std")] +use codec::{Decode, Input, Error}; +use codec::{Encode, Output}; +use rstd::vec::Vec; +use primitives::RuntimeDebug; + +#[cfg(feature = "std")] +type StringBuf = String; + +/// Curent prefix of metadata +pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness + +/// On `no_std` we do not support `Decode` and thus `StringBuf` is just `&'static str`. +/// So, if someone tries to decode this stuff on `no_std`, they will get a compilation error. +#[cfg(not(feature = "std"))] +type StringBuf = &'static str; + +/// A type that decodes to a different type than it encodes. +/// The user needs to make sure that both types use the same encoding. +/// +/// For example a `&'static [ &'static str ]` can be decoded to a `Vec`. +#[derive(Clone)] +pub enum DecodeDifferent where B: 'static, O: 'static { + Encode(B), + Decoded(O), +} + +impl Encode for DecodeDifferent where B: Encode + 'static, O: Encode + 'static { + fn encode_to(&self, dest: &mut W) { + match self { + DecodeDifferent::Encode(b) => b.encode_to(dest), + DecodeDifferent::Decoded(o) => o.encode_to(dest), + } + } +} + +impl codec::EncodeLike for DecodeDifferent where B: Encode + 'static, O: Encode + 'static {} + +#[cfg(feature = "std")] +impl Decode for DecodeDifferent where B: 'static, O: Decode + 'static { + fn decode(input: &mut I) -> Result { + ::decode(input).map(|val| { + DecodeDifferent::Decoded(val) + }) + } +} + +impl PartialEq for DecodeDifferent +where + B: Encode + Eq + PartialEq + 'static, + O: Encode + Eq + PartialEq + 'static, +{ + fn eq(&self, other: &Self) -> bool { + self.encode() == other.encode() + } +} + +impl Eq for DecodeDifferent + where B: Encode + Eq + PartialEq + 'static, O: Encode + Eq + PartialEq + 'static +{} + +impl rstd::fmt::Debug for DecodeDifferent + where + B: rstd::fmt::Debug + Eq + 'static, + O: rstd::fmt::Debug + Eq + 'static, +{ + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + match self { + DecodeDifferent::Encode(b) => b.fmt(f), + DecodeDifferent::Decoded(o) => o.fmt(f), + } + } +} + +#[cfg(feature = "std")] +impl serde::Serialize for DecodeDifferent + where + B: serde::Serialize + 'static, + O: serde::Serialize + 'static, +{ + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + match self { + DecodeDifferent::Encode(b) => b.serialize(serializer), + DecodeDifferent::Decoded(o) => o.serialize(serializer), + } + } +} + +pub type DecodeDifferentArray = DecodeDifferent<&'static [B], Vec>; + +type DecodeDifferentStr = DecodeDifferent<&'static str, StringBuf>; + +/// All the metadata about a function. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct FunctionMetadata { + pub name: DecodeDifferentStr, + pub arguments: DecodeDifferentArray, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about a function argument. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct FunctionArgumentMetadata { + pub name: DecodeDifferentStr, + pub ty: DecodeDifferentStr, +} + +/// Newtype wrapper for support encoding functions (actual the result of the function). +#[derive(Clone, Eq)] +pub struct FnEncode(pub fn() -> E) where E: Encode + 'static; + +impl Encode for FnEncode { + fn encode_to(&self, dest: &mut W) { + self.0().encode_to(dest); + } +} + +impl codec::EncodeLike for FnEncode {} + +impl PartialEq for FnEncode { + fn eq(&self, other: &Self) -> bool { + self.0().eq(&other.0()) + } +} + +impl rstd::fmt::Debug for FnEncode { + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + self.0().fmt(f) + } +} + +#[cfg(feature = "std")] +impl serde::Serialize for FnEncode { + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + self.0().serialize(serializer) + } +} + +/// All the metadata about an outer event. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct OuterEventMetadata { + pub name: DecodeDifferentStr, + pub events: DecodeDifferentArray< + (&'static str, FnEncode<&'static [EventMetadata]>), + (StringBuf, Vec) + >, +} + +/// All the metadata about an event. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct EventMetadata { + pub name: DecodeDifferentStr, + pub arguments: DecodeDifferentArray<&'static str, StringBuf>, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about one storage entry. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct StorageEntryMetadata { + pub name: DecodeDifferentStr, + pub modifier: StorageEntryModifier, + pub ty: StorageEntryType, + pub default: ByteGetter, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about one module constant. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct ModuleConstantMetadata { + pub name: DecodeDifferentStr, + pub ty: DecodeDifferentStr, + pub value: ByteGetter, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about a module error. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct ErrorMetadata { + pub name: DecodeDifferentStr, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about errors in a module. +pub trait ModuleErrorMetadata { + fn metadata() -> &'static [ErrorMetadata]; +} + +impl ModuleErrorMetadata for &'static str { + fn metadata() -> &'static [ErrorMetadata] { + &[] + } +} + +/// A technical trait to store lazy initiated vec value as static dyn pointer. +pub trait DefaultByte: Send + Sync { + fn default_byte(&self) -> Vec; +} + +/// Wrapper over dyn pointer for accessing a cached once byte value. +#[derive(Clone)] +pub struct DefaultByteGetter(pub &'static dyn DefaultByte); + +/// Decode different for static lazy initiated byte value. +pub type ByteGetter = DecodeDifferent>; + +impl Encode for DefaultByteGetter { + fn encode_to(&self, dest: &mut W) { + self.0.default_byte().encode_to(dest) + } +} + +impl codec::EncodeLike for DefaultByteGetter {} + +impl PartialEq for DefaultByteGetter { + fn eq(&self, other: &DefaultByteGetter) -> bool { + let left = self.0.default_byte(); + let right = other.0.default_byte(); + left.eq(&right) + } +} + +impl Eq for DefaultByteGetter { } + +#[cfg(feature = "std")] +impl serde::Serialize for DefaultByteGetter { + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + self.0.default_byte().serialize(serializer) + } +} + +impl rstd::fmt::Debug for DefaultByteGetter { + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + self.0.default_byte().fmt(f) + } +} + +/// Hasher used by storage maps +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub enum StorageHasher { + Blake2_128, + Blake2_256, + Blake2_128Concat, + Twox128, + Twox256, + Twox64Concat, +} + +/// A storage entry type. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub enum StorageEntryType { + Plain(DecodeDifferentStr), + Map { + hasher: StorageHasher, + key: DecodeDifferentStr, + value: DecodeDifferentStr, + is_linked: bool, + }, + DoubleMap { + hasher: StorageHasher, + key1: DecodeDifferentStr, + key2: DecodeDifferentStr, + value: DecodeDifferentStr, + key2_hasher: StorageHasher, + }, +} + +/// A storage entry modifier. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub enum StorageEntryModifier { + Optional, + Default, +} + +/// All metadata of the storage. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct StorageMetadata { + /// The common prefix used by all storage entries. + pub prefix: DecodeDifferent<&'static str, StringBuf>, + pub entries: DecodeDifferent<&'static [StorageEntryMetadata], Vec>, +} + +#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +/// Metadata prefixed by a u32 for reserved usage +pub struct RuntimeMetadataPrefixed(pub u32, pub RuntimeMetadata); + +/// The metadata of a runtime. +/// The version ID encoded/decoded through +/// the enum nature of `RuntimeMetadata`. +#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub enum RuntimeMetadata { + /// Unused; enum filler. + V0(RuntimeMetadataDeprecated), + /// Version 1 for runtime metadata. No longer used. + V1(RuntimeMetadataDeprecated), + /// Version 2 for runtime metadata. No longer used. + V2(RuntimeMetadataDeprecated), + /// Version 3 for runtime metadata. No longer used. + V3(RuntimeMetadataDeprecated), + /// Version 4 for runtime metadata. No longer used. + V4(RuntimeMetadataDeprecated), + /// Version 5 for runtime metadata. No longer used. + V5(RuntimeMetadataDeprecated), + /// Version 6 for runtime metadata. No longer used. + V6(RuntimeMetadataDeprecated), + /// Version 7 for runtime metadata. No longer used. + V7(RuntimeMetadataDeprecated), + /// Version 8 for runtime metadata. No longer used. + V8(RuntimeMetadataDeprecated), + /// Version 9 for runtime metadata. + V9(RuntimeMetadataV9), +} + +/// Enum that should fail. +#[derive(Eq, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize))] +pub enum RuntimeMetadataDeprecated { } + +impl Encode for RuntimeMetadataDeprecated { + fn encode_to(&self, _dest: &mut W) {} +} + +impl codec::EncodeLike for RuntimeMetadataDeprecated {} + +#[cfg(feature = "std")] +impl Decode for RuntimeMetadataDeprecated { + fn decode(_input: &mut I) -> Result { + Err("Decoding is not supported".into()) + } +} + +/// The metadata of a runtime. +#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct RuntimeMetadataV9 { + pub modules: DecodeDifferentArray, +} + +/// The latest version of the metadata. +pub type RuntimeMetadataLastVersion = RuntimeMetadataV9; + +/// All metadata about an runtime module. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct ModuleMetadata { + pub name: DecodeDifferentStr, + pub storage: Option, StorageMetadata>>, + pub calls: ODFnA, + pub event: ODFnA, + pub constants: DFnA, + pub errors: DFnA, +} + +type ODFnA = Option>; +type DFnA = DecodeDifferent, Vec>; + +impl Into for RuntimeMetadataPrefixed { + fn into(self) -> primitives::OpaqueMetadata { + primitives::OpaqueMetadata::new(self.encode()) + } +} + +impl Into for RuntimeMetadataLastVersion { + fn into(self) -> RuntimeMetadataPrefixed { + RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V9(self)) + } +} From b7e6be3ce35c25dfc4de67229d40e941a3afb143 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Fri, 20 Aug 2021 19:11:38 -0400 Subject: [PATCH 02/13] add local sp-core and legacy frame-metadata versions directly to desub --- Cargo.lock | 3740 +++++++++++++++++ Cargo.toml | 5 + core/Cargo.toml | 8 +- .../metadatav10/Cargo.toml | 2 +- .../metadatav11/Cargo.toml | 2 +- .../metadatav8/Cargo.toml | 2 +- .../metadatav9/Cargo.toml | 2 +- .../sp_core_versions/README.md | 7 + .../sp_core_versions/core-7314a/Cargo.toml | 126 + .../core-7314a/src/changes_trie.rs | 306 ++ .../sp_core_versions/core-7314a/src/crypto.rs | 1263 ++++++ .../sp_core_versions/core-7314a/src/ecdsa.rs | 717 ++++ .../core-7314a/src/ed25519.rs | 711 ++++ .../sp_core_versions/core-7314a/src/hash.rs | 82 + .../sp_core_versions/core-7314a/src/hasher.rs | 58 + .../core-7314a/src/hashing.rs | 156 + .../core-7314a/src/hexdisplay.rs | 104 + .../sp_core_versions/core-7314a/src/lib.rs | 390 ++ .../core-7314a/src/offchain/mod.rs | 775 ++++ .../core-7314a/src/offchain/storage.rs | 297 ++ .../core-7314a/src/offchain/testing.rs | 418 ++ .../core-7314a/src/sandbox.rs | 128 + .../core-7314a/src/sr25519.rs | 889 ++++ .../core-7314a/src/testing.rs | 464 ++ .../sp_core_versions/core-7314a/src/traits.rs | 388 ++ .../core-7314a/src/u32_trait.rs | 244 ++ .../sp_core_versions/core-7314a/src/uint.rs | 100 + .../sp_core_versions/core-7314a/src/vrf.rs | 99 + 28 files changed, 11475 insertions(+), 8 deletions(-) create mode 100644 Cargo.lock create mode 100644 substrate-metadata-versions/sp_core_versions/README.md create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/Cargo.toml create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/changes_trie.rs create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/crypto.rs create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/ecdsa.rs create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/ed25519.rs create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/hash.rs create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/hasher.rs create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/hashing.rs create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/hexdisplay.rs create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/lib.rs create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/mod.rs create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/storage.rs create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/testing.rs create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/sandbox.rs create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/sr25519.rs create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/testing.rs create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/traits.rs create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/u32_trait.rs create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/uint.rs create mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/vrf.rs diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..97a2d0d6 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,3740 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "addr2line" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98" +dependencies = [ + "getrandom 0.2.3", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" + +[[package]] +name = "approx" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "072df7202e63b127ab55acfe16ce97013d5b97bf160489336d3f1840fd78e99e" +dependencies = [ + "num-traits", +] + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", +] + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "arrayvec" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4dc07131ffa69b8072d35f5007352af944213cde02545e2103680baed38fcd" + +[[package]] +name = "async-trait" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "backtrace" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01" +dependencies = [ + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base58" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" + +[[package]] +name = "bindgen" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da379dbebc0b76ef63ca68d8fc6e71c0f13e59432e0987e508c1820e6ab5239" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "clap", + "env_logger 0.8.4", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "which", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitvec" +version = "0.17.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" +dependencies = [ + "either", + "radium 0.3.0", +] + +[[package]] +name = "bitvec" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" +dependencies = [ + "funty", + "radium 0.6.2", + "tap", + "wyz", +] + +[[package]] +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +dependencies = [ + "arrayvec 0.4.12", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array 0.12.4", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array 0.14.4", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "bstr" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279" +dependencies = [ + "lazy_static", + "memchr", + "regex-automata", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" + +[[package]] +name = "byte-slice-cast" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" + +[[package]] +name = "byte-slice-cast" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65c1bf4a04a88c54f589125563643d773f3254b5c38571395e2b591c693bbc81" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cast" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" +dependencies = [ + "rustc_version 0.4.0", +] + +[[package]] +name = "cc" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" +dependencies = [ + "jobserver", +] + +[[package]] +name = "cexpr" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "winapi", +] + +[[package]] +name = "clang-sys" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "853eda514c284c2287f4bf20ae614f8781f40a81d32ecda6e91449304dfe077c" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "ansi_term 0.11.0", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cpufeatures" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" +dependencies = [ + "libc", +] + +[[package]] +name = "criterion" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10" +dependencies = [ + "atty", + "cast", + "clap", + "criterion-plot", + "csv", + "itertools", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_cbor", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +dependencies = [ + "cfg-if 1.0.0", + "lazy_static", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-mac" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +dependencies = [ + "generic-array 0.12.4", + "subtle 1.0.0", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array 0.14.4", + "subtle 2.4.1", +] + +[[package]] +name = "csv" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" +dependencies = [ + "bstr", + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +dependencies = [ + "memchr", +] + +[[package]] +name = "ctor" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e98e2ad1a782e33928b96fc3948e7c355e5af34ba4de7670fe8bac2a3b2006d" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "curve25519-dalek" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b85542f99a2dfa2a1b8e192662741c9859a846b296bef1c92ef9b58b5a216" +dependencies = [ + "byteorder", + "digest 0.8.1", + "rand_core 0.5.1", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "derive_more" +version = "0.99.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version 0.3.3", + "syn", +] + +[[package]] +name = "desub-core" +version = "0.0.1" +dependencies = [ + "derive_more", + "desub-extras", + "dyn-clone", + "frame-metadata 14.0.0-rc.2", + "frame-metadatav10", + "frame-metadatav11", + "frame-metadatav8", + "frame-metadatav9", + "hex", + "log", + "onig", + "pallet-democracy", + "pallet-identity", + "pallet-indices", + "parity-scale-codec 2.2.0", + "pretty_env_logger", + "serde", + "serde_json", + "sp-core 4.0.0-dev", + "sp-runtime", + "sp-version", + "thiserror", +] + +[[package]] +name = "desub-extras" +version = "0.0.1" +dependencies = [ + "desub-core", + "env_logger 0.7.1", + "log", + "parity-scale-codec 1.3.7", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "difference" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.4", +] + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "dyn-clonable" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4" +dependencies = [ + "dyn-clonable-impl", + "dyn-clone", +] + +[[package]] +name = "dyn-clonable-impl" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dyn-clone" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" + +[[package]] +name = "ed25519" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4620d40f6d2601794401d6dd95a5cf69b6c157852539470eeda433a99b3c0efc" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519", + "rand 0.7.3", + "serde", + "sha2 0.9.5", + "zeroize", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "enumflags2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0" +dependencies = [ + "enumflags2_derive", +] + +[[package]] +name = "enumflags2_derive" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "atty", + "humantime 1.3.0", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "env_logger" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" +dependencies = [ + "atty", + "humantime 2.1.0", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "environmental" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b91989ae21441195d7d9b9993a2f9295c7e1a8c96255d8b729accddc124797" + +[[package]] +name = "erased-serde" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3de9ad4541d99dc22b59134e7ff8dc3d6c988c89ecd7324bf10a8362b07a2afa" +dependencies = [ + "serde", +] + +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "fixed-hash" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11498d382790b7a8f2fd211780bec78619bba81cdad3a283997c0c41f836759c" +dependencies = [ + "byteorder", + "rand 0.7.3", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "byteorder", + "rand 0.8.4", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "frame-benchmarking" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "frame-support", + "frame-system", + "linregress", + "log", + "parity-scale-codec 2.2.0", + "paste", + "sp-api", + "sp-io", + "sp-runtime", + "sp-runtime-interface 4.0.0-dev", + "sp-std 4.0.0-dev", + "sp-storage 4.0.0-dev", +] + +[[package]] +name = "frame-metadata" +version = "14.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "parity-scale-codec 2.2.0", + "serde", + "sp-core 4.0.0-dev", + "sp-std 4.0.0-dev", +] + +[[package]] +name = "frame-metadata" +version = "14.0.0-rc.2" +source = "git+https://github.com/paritytech/frame-metadata#2c6499d9758632b5161f111b4320201640cf2af6" +dependencies = [ + "cfg-if 1.0.0", + "parity-scale-codec 2.2.0", + "scale-info", + "serde", +] + +[[package]] +name = "frame-metadatav10" +version = "10.0.0" +dependencies = [ + "parity-scale-codec 1.3.7", + "serde", + "sp-core 2.0.0", + "sp-std 2.0.0", +] + +[[package]] +name = "frame-metadatav11" +version = "11.0.0-rc6" +dependencies = [ + "parity-scale-codec 1.3.7", + "serde", + "sp-core 2.0.0", + "sp-std 2.0.0", +] + +[[package]] +name = "frame-metadatav8" +version = "2.0.0" +dependencies = [ + "parity-scale-codec 1.3.7", + "serde", + "sp-core 2.0.0", + "sp-std 2.0.0", +] + +[[package]] +name = "frame-metadatav9" +version = "2.0.0" +dependencies = [ + "parity-scale-codec 1.3.7", + "serde", + "sp-core 2.0.0", + "sp-std 2.0.0", +] + +[[package]] +name = "frame-support" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "bitflags", + "frame-metadata 14.0.0-dev", + "frame-support-procedural", + "impl-trait-for-tuples 0.2.1", + "log", + "once_cell", + "parity-scale-codec 2.2.0", + "paste", + "serde", + "smallvec", + "sp-arithmetic", + "sp-core 4.0.0-dev", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-state-machine", + "sp-std 4.0.0-dev", + "sp-tracing 4.0.0-dev", +] + +[[package]] +name = "frame-support-procedural" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "Inflector", + "frame-support-procedural-tools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "frame-support-procedural-tools" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "frame-support-procedural-tools-derive", + "proc-macro-crate 1.0.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "frame-support-procedural-tools-derive" +version = "3.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "frame-system" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "frame-support", + "impl-trait-for-tuples 0.2.1", + "log", + "parity-scale-codec 2.2.0", + "serde", + "sp-core 4.0.0-dev", + "sp-io", + "sp-runtime", + "sp-std 4.0.0-dev", + "sp-version", +] + +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + +[[package]] +name = "futures" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" + +[[package]] +name = "futures-executor" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582" + +[[package]] +name = "futures-macro" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57" +dependencies = [ + "autocfg", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" + +[[package]] +name = "futures-task" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2" + +[[package]] +name = "futures-util" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78" +dependencies = [ + "autocfg", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "gimli" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "half" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" + +[[package]] +name = "hash-db" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" + +[[package]] +name = "hash256-std-hasher" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" +dependencies = [ + "crunchy", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21e4590e13640f19f249fe3e4eca5113bc4289f2497710378190e7f4bd96f45b" + +[[package]] +name = "hmac" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" +dependencies = [ + "crypto-mac 0.7.0", + "digest 0.8.1", +] + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac 0.8.0", + "digest 0.9.0", +] + +[[package]] +name = "hmac-drbg" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" +dependencies = [ + "digest 0.8.1", + "generic-array 0.12.4", + "hmac 0.7.1", +] + +[[package]] +name = "humantime" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "impl-codec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" +dependencies = [ + "parity-scale-codec 1.3.7", +] + +[[package]] +name = "impl-codec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "161ebdfec3c8e3b52bf61c4f3550a1eea4f9579d10dc1b936f3171ebdcd6c443" +dependencies = [ + "parity-scale-codec 2.2.0", +] + +[[package]] +name = "impl-serde" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b47ca4d2b6931707a55fce5cf66aff80e2178c8b63bbb4ecb5695cbc870ddf6f" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5dacb10c5b3bb92d46ba347505a9041e676bb20ad220101326bffb0c93031ee" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "indexmap" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "integer-sqrt" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" +dependencies = [ + "num-traits", +] + +[[package]] +name = "integration_tests" +version = "0.1.0" +dependencies = [ + "desub-core", + "desub-extras", + "frame-system", + "hex", + "log", + "pallet-balances", + "parity-scale-codec 1.3.7", + "paste", + "pretty_env_logger", + "serde", + "serde_json", + "sp-core 4.0.0-dev", +] + +[[package]] +name = "itertools" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" + +[[package]] +name = "jobserver" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "keccak" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" + +[[package]] +name = "libloading" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a" +dependencies = [ + "cfg-if 1.0.0", + "winapi", +] + +[[package]] +name = "libm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" + +[[package]] +name = "libsecp256k1" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" +dependencies = [ + "arrayref", + "crunchy", + "digest 0.8.1", + "hmac-drbg", + "rand 0.7.3", + "sha2 0.8.2", + "subtle 2.4.1", + "typenum", +] + +[[package]] +name = "linregress" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6e407dadb4ca4b31bc69c27aff00e7ca4534fdcee855159b039a7cebb5f395" +dependencies = [ + "nalgebra", + "statrs", +] + +[[package]] +name = "lock_api" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "lock_api" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "matchers" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matrixmultiply" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a8a15b776d9dfaecd44b03c5828c2199cddff5247215858aac14624f8d6b741" +dependencies = [ + "rawpointer", +] + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memoffset" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memory-db" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de006e09d04fc301a5f7e817b75aa49801c4479a8af753764416b085337ddcc5" +dependencies = [ + "hash-db", + "hashbrown", + "parity-util-mem", +] + +[[package]] +name = "memory_units" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" + +[[package]] +name = "merlin" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e261cf0f8b3c42ded9f7d2bb59dea03aa52bc8a1cbc7482f9fc3fd1229d3b42" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "nalgebra" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "462fffe4002f4f2e1f6a9dcf12cc1a6fc0e15989014efc02a941d3e0f5dc2120" +dependencies = [ + "approx", + "matrixmultiply", + "nalgebra-macros", + "num-complex", + "num-rational 0.4.0", + "num-traits", + "rand 0.8.4", + "rand_distr", + "simba", + "typenum", +] + +[[package]] +name = "nalgebra-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01fcc0b8149b4632adc89ac3b7b31a12fb6099a0317a4eb2ebff574ef7de7218" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "nom" +version = "5.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" +dependencies = [ + "memchr", + "version_check", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2766204889d09937d00bfbb7fec56bb2a199e2ade963cab19185d8a6104c7c" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +dependencies = [ + "parking_lot 0.11.1", +] + +[[package]] +name = "onig" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e723fc996fff1aeab8f62205f3e8528bf498bdd5eadb2784d2d31f30077947" +dependencies = [ + "bitflags", + "lazy_static", + "libc", + "onig_sys", +] + +[[package]] +name = "onig_sys" +version = "69.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fd9442a09e4fbd08d196ddf419b2c79a43c3a46c800320cc841d45c2449a240" +dependencies = [ + "bindgen", + "cc", + "pkg-config", +] + +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "output_vt100" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9" +dependencies = [ + "winapi", +] + +[[package]] +name = "pallet-balances" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec 2.2.0", + "sp-runtime", + "sp-std 4.0.0-dev", +] + +[[package]] +name = "pallet-democracy" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec 2.2.0", + "serde", + "sp-io", + "sp-runtime", + "sp-std 4.0.0-dev", +] + +[[package]] +name = "pallet-identity" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "enumflags2", + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec 2.2.0", + "sp-io", + "sp-runtime", + "sp-std 4.0.0-dev", +] + +[[package]] +name = "pallet-indices" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec 2.2.0", + "sp-core 4.0.0-dev", + "sp-io", + "sp-keyring", + "sp-runtime", + "sp-std 4.0.0-dev", +] + +[[package]] +name = "parity-scale-codec" +version = "1.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b26b16c7687c3075982af47719e481815df30bc544f7a6690763a25ca16e9d" +dependencies = [ + "arrayvec 0.5.2", + "bitvec 0.17.4", + "byte-slice-cast 0.3.5", + "parity-scale-codec-derive 1.2.3", + "serde", +] + +[[package]] +name = "parity-scale-codec" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8975095a2a03bbbdc70a74ab11a4f76a6d0b84680d87c68d722531b0ac28e8a9" +dependencies = [ + "arrayvec 0.7.1", + "bitvec 0.20.4", + "byte-slice-cast 1.0.0", + "impl-trait-for-tuples 0.2.1", + "parity-scale-codec-derive 2.2.0", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41512944b1faff334a5f1b9447611bf4ef40638ccb6328173dacefb338e878c" +dependencies = [ + "proc-macro-crate 0.1.5", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40dbbfef7f0a1143c5b06e0d76a6278e25dac0bc1af4be51a0fbb73f07e7ad09" +dependencies = [ + "proc-macro-crate 1.0.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "parity-util-mem" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ad6f1acec69b95caf435bbd158d486e5a0a44fcf51531e84922c59ff09e8457" +dependencies = [ + "cfg-if 1.0.0", + "hashbrown", + "impl-trait-for-tuples 0.2.1", + "parity-util-mem-derive", + "parking_lot 0.11.1", + "primitive-types 0.10.1", + "winapi", +] + +[[package]] +name = "parity-util-mem-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" +dependencies = [ + "proc-macro2", + "syn", + "synstructure", +] + +[[package]] +name = "parity-wasm" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" + +[[package]] +name = "parity-wasm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" + +[[package]] +name = "parking_lot" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" +dependencies = [ + "lock_api 0.3.4", + "parking_lot_core 0.7.2", +] + +[[package]] +name = "parking_lot" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +dependencies = [ + "instant", + "lock_api 0.4.4", + "parking_lot_core 0.8.3", +] + +[[package]] +name = "parking_lot_core" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" +dependencies = [ + "cfg-if 0.1.10", + "cloudabi", + "libc", + "redox_syscall 0.1.57", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall 0.2.10", + "smallvec", + "winapi", +] + +[[package]] +name = "paste" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58" + +[[package]] +name = "pbkdf2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" +dependencies = [ + "byteorder", + "crypto-mac 0.7.0", +] + +[[package]] +name = "pbkdf2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" +dependencies = [ + "crypto-mac 0.8.0", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + +[[package]] +name = "plotters" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c" + +[[package]] +name = "plotters-svg" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "pretty_assertions" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" +dependencies = [ + "ansi_term 0.11.0", + "ctor", + "difference", + "output_vt100", +] + +[[package]] +name = "pretty_env_logger" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" +dependencies = [ + "env_logger 0.7.1", + "log", +] + +[[package]] +name = "primitive-types" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd39dcacf71411ba488570da7bbc89b717225e46478b30ba99b92db6b149809" +dependencies = [ + "fixed-hash 0.6.1", + "impl-codec 0.4.2", + "impl-serde", + "uint 0.8.5", +] + +[[package]] +name = "primitive-types" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" +dependencies = [ + "fixed-hash 0.7.0", + "impl-codec 0.5.1", + "impl-serde", + "uint 0.9.1", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fdbd1df62156fbc5945f4762632564d7d038153091c3fcf1067f6aef7cff92" +dependencies = [ + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro-nested" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" + +[[package]] +name = "proc-macro2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" + +[[package]] +name = "radium" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.3", +] + +[[package]] +name = "rand_distr" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051b398806e42b9cd04ad9ec8f81e355d0a382c543ac6672c62f5a5b452ef142" +dependencies = [ + "num-traits", + "rand 0.8.4", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "ref-cast" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300f2a835d808734ee295d45007adacb9ebb29dd3ae2424acfa17930cae541da" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c38e3aecd2b21cb3959637b883bb3714bc7e43f0268b9a29d3743ee3e55cdd2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "rustc-demangle" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.4", +] + +[[package]] +name = "ruzstd" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cada0ef59efa6a5f4dc5e491f93d9f31e3fc7758df421ff1de8a706338e1100" +dependencies = [ + "byteorder", + "twox-hash", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scale-info" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2e62ff266e136db561a007c84569985805f84a1d5a08278e52c36aacb6e061b" +dependencies = [ + "bitvec 0.20.4", + "cfg-if 1.0.0", + "derive_more", + "parity-scale-codec 2.2.0", + "scale-info-derive", + "serde", +] + +[[package]] +name = "scale-info-derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b648fa291891a4c80187a25532f6a7d96b82c70353e30b868b14632b8fe043d6" +dependencies = [ + "proc-macro-crate 1.0.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "schnorrkel" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "curve25519-dalek 2.1.3", + "getrandom 0.1.16", + "merlin", + "rand 0.7.3", + "rand_core 0.5.1", + "sha2 0.8.2", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "secrecy" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9182278ed645df3477a9c27bfee0621c621aa16f6972635f7f795dae3d81070f" +dependencies = [ + "zeroize", +] + +[[package]] +name = "secrecy" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0673d6a6449f5e7d12a1caf424fd9363e2af3a4953023ed455e3c4beef4597c0" +dependencies = [ + "zeroize", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "serde" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +dependencies = [ + "block-buffer 0.7.3", + "digest 0.8.1", + "fake-simd", + "opaque-debug 0.2.3", +] + +[[package]] +name = "sha2" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "sharded-slab" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740223c51853f3145fe7c90360d2d4232f2b62e3449489c207eccde818979982" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" + +[[package]] +name = "signature" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335" + +[[package]] +name = "simba" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e82063457853d00243beda9952e910b82593e4b07ae9f721b9278a99a0d3d5c" +dependencies = [ + "approx", + "num-complex", + "num-traits", + "paste", +] + +[[package]] +name = "slab" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" + +[[package]] +name = "slog" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06" +dependencies = [ + "erased-serde", +] + +[[package]] +name = "smallvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" + +[[package]] +name = "sp-api" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "hash-db", + "log", + "parity-scale-codec 2.2.0", + "sp-api-proc-macro", + "sp-core 4.0.0-dev", + "sp-runtime", + "sp-state-machine", + "sp-std 4.0.0-dev", + "sp-version", + "thiserror", +] + +[[package]] +name = "sp-api-proc-macro" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "blake2-rfc", + "proc-macro-crate 1.0.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-application-crypto" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "parity-scale-codec 2.2.0", + "serde", + "sp-core 4.0.0-dev", + "sp-io", + "sp-std 4.0.0-dev", +] + +[[package]] +name = "sp-arithmetic" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "integer-sqrt", + "num-traits", + "parity-scale-codec 2.2.0", + "serde", + "sp-debug-derive 3.0.0", + "sp-std 4.0.0-dev", + "static_assertions", +] + +[[package]] +name = "sp-core" +version = "2.0.0" +dependencies = [ + "base58", + "blake2-rfc", + "byteorder", + "criterion", + "derive_more", + "dyn-clonable", + "ed25519-dalek", + "futures", + "hash-db", + "hash256-std-hasher", + "hex", + "hex-literal", + "impl-serde", + "lazy_static", + "libsecp256k1", + "log", + "merlin", + "num-traits", + "parity-scale-codec 1.3.7", + "parity-util-mem", + "parking_lot 0.10.2", + "pretty_assertions", + "primitive-types 0.7.3", + "rand 0.7.3", + "rand_chacha 0.2.2", + "regex", + "schnorrkel", + "secrecy 0.6.0", + "serde", + "serde_json", + "sha2 0.8.2", + "sp-debug-derive 2.0.0", + "sp-externalities 0.8.0", + "sp-runtime-interface 2.0.0", + "sp-serializer", + "sp-std 2.0.0", + "sp-storage 2.0.0", + "substrate-bip39", + "tiny-bip39 0.7.3", + "tiny-keccak", + "twox-hash", + "wasmi 0.6.2", + "zeroize", +] + +[[package]] +name = "sp-core" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "base58", + "blake2-rfc", + "byteorder", + "dyn-clonable", + "ed25519-dalek", + "futures", + "hash-db", + "hash256-std-hasher", + "hex", + "impl-serde", + "lazy_static", + "libsecp256k1", + "log", + "merlin", + "num-traits", + "parity-scale-codec 2.2.0", + "parity-util-mem", + "parking_lot 0.11.1", + "primitive-types 0.10.1", + "rand 0.7.3", + "regex", + "schnorrkel", + "secrecy 0.7.0", + "serde", + "sha2 0.9.5", + "sp-debug-derive 3.0.0", + "sp-externalities 0.10.0-dev", + "sp-runtime-interface 4.0.0-dev", + "sp-std 4.0.0-dev", + "sp-storage 4.0.0-dev", + "substrate-bip39", + "thiserror", + "tiny-bip39 0.8.0", + "tiny-keccak", + "twox-hash", + "wasmi 0.9.0", + "zeroize", +] + +[[package]] +name = "sp-debug-derive" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-debug-derive" +version = "3.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-externalities" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "environmental", + "parity-scale-codec 1.3.7", + "sp-std 2.0.0", + "sp-storage 2.0.0", +] + +[[package]] +name = "sp-externalities" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "environmental", + "parity-scale-codec 2.2.0", + "sp-std 4.0.0-dev", + "sp-storage 4.0.0-dev", +] + +[[package]] +name = "sp-inherents" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "async-trait", + "impl-trait-for-tuples 0.2.1", + "parity-scale-codec 2.2.0", + "sp-core 4.0.0-dev", + "sp-runtime", + "sp-std 4.0.0-dev", + "thiserror", +] + +[[package]] +name = "sp-io" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "futures", + "hash-db", + "libsecp256k1", + "log", + "parity-scale-codec 2.2.0", + "parking_lot 0.11.1", + "sp-core 4.0.0-dev", + "sp-externalities 0.10.0-dev", + "sp-keystore", + "sp-maybe-compressed-blob", + "sp-runtime-interface 4.0.0-dev", + "sp-state-machine", + "sp-std 4.0.0-dev", + "sp-tracing 4.0.0-dev", + "sp-trie", + "sp-wasm-interface 4.0.0-dev", + "tracing", + "tracing-core", +] + +[[package]] +name = "sp-keyring" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "lazy_static", + "sp-core 4.0.0-dev", + "sp-runtime", + "strum", +] + +[[package]] +name = "sp-keystore" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "async-trait", + "derive_more", + "futures", + "merlin", + "parity-scale-codec 2.2.0", + "parking_lot 0.11.1", + "schnorrkel", + "sp-core 4.0.0-dev", + "sp-externalities 0.10.0-dev", +] + +[[package]] +name = "sp-maybe-compressed-blob" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "ruzstd", + "zstd", +] + +[[package]] +name = "sp-panic-handler" +version = "3.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "backtrace", +] + +[[package]] +name = "sp-runtime" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "either", + "hash256-std-hasher", + "impl-trait-for-tuples 0.2.1", + "log", + "parity-scale-codec 2.2.0", + "parity-util-mem", + "paste", + "rand 0.7.3", + "serde", + "sp-application-crypto", + "sp-arithmetic", + "sp-core 4.0.0-dev", + "sp-io", + "sp-std 4.0.0-dev", +] + +[[package]] +name = "sp-runtime-interface" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "parity-scale-codec 1.3.7", + "primitive-types 0.7.3", + "sp-externalities 0.8.0", + "sp-runtime-interface-proc-macro 2.0.0", + "sp-std 2.0.0", + "sp-storage 2.0.0", + "sp-tracing 2.0.0", + "sp-wasm-interface 2.0.0", + "static_assertions", +] + +[[package]] +name = "sp-runtime-interface" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "impl-trait-for-tuples 0.2.1", + "parity-scale-codec 2.2.0", + "primitive-types 0.10.1", + "sp-externalities 0.10.0-dev", + "sp-runtime-interface-proc-macro 4.0.0-dev", + "sp-std 4.0.0-dev", + "sp-storage 4.0.0-dev", + "sp-tracing 4.0.0-dev", + "sp-wasm-interface 4.0.0-dev", + "static_assertions", +] + +[[package]] +name = "sp-runtime-interface-proc-macro" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "Inflector", + "proc-macro-crate 0.1.5", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-runtime-interface-proc-macro" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "Inflector", + "proc-macro-crate 1.0.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-serializer" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "sp-staking" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "parity-scale-codec 2.2.0", + "sp-runtime", + "sp-std 4.0.0-dev", +] + +[[package]] +name = "sp-state-machine" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "hash-db", + "log", + "num-traits", + "parity-scale-codec 2.2.0", + "parking_lot 0.11.1", + "rand 0.7.3", + "smallvec", + "sp-core 4.0.0-dev", + "sp-externalities 0.10.0-dev", + "sp-panic-handler", + "sp-std 4.0.0-dev", + "sp-trie", + "thiserror", + "tracing", + "trie-db", + "trie-root", +] + +[[package]] +name = "sp-std" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" + +[[package]] +name = "sp-std" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" + +[[package]] +name = "sp-storage" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "impl-serde", + "parity-scale-codec 1.3.7", + "ref-cast", + "serde", + "sp-debug-derive 2.0.0", + "sp-std 2.0.0", +] + +[[package]] +name = "sp-storage" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "impl-serde", + "parity-scale-codec 2.2.0", + "ref-cast", + "serde", + "sp-debug-derive 3.0.0", + "sp-std 4.0.0-dev", +] + +[[package]] +name = "sp-tracing" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "log", + "parity-scale-codec 1.3.7", + "sp-std 2.0.0", + "tracing", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "sp-tracing" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "erased-serde", + "log", + "parity-scale-codec 2.2.0", + "parking_lot 0.10.2", + "serde", + "serde_json", + "slog", + "sp-std 4.0.0-dev", + "tracing", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "sp-trie" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "hash-db", + "memory-db", + "parity-scale-codec 2.2.0", + "sp-core 4.0.0-dev", + "sp-std 4.0.0-dev", + "trie-db", + "trie-root", +] + +[[package]] +name = "sp-version" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "impl-serde", + "parity-scale-codec 2.2.0", + "parity-wasm 0.42.2", + "serde", + "sp-runtime", + "sp-std 4.0.0-dev", + "sp-version-proc-macro", + "thiserror", +] + +[[package]] +name = "sp-version-proc-macro" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "parity-scale-codec 2.2.0", + "proc-macro-crate 1.0.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-wasm-interface" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "impl-trait-for-tuples 0.1.3", + "parity-scale-codec 1.3.7", + "sp-std 2.0.0", + "wasmi 0.6.2", +] + +[[package]] +name = "sp-wasm-interface" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "impl-trait-for-tuples 0.2.1", + "parity-scale-codec 2.2.0", + "sp-std 4.0.0-dev", + "wasmi 0.9.0", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "statrs" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05bdbb8e4e78216a85785a85d3ec3183144f98d0097b9281802c019bb07a6f05" +dependencies = [ + "approx", + "lazy_static", + "nalgebra", + "num-traits", + "rand 0.8.4", +] + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "strum" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7318c509b5ba57f18533982607f24070a55d353e90d4cae30c467cdb2ad5ac5c" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee8bc6b87a5112aeeab1f4a9f7ab634fe6cbefc4850006df31267f4cfb9e3149" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "substrate-bip39" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bed6646a0159b9935b5d045611560eeef842b78d7adc3ba36f5ca325a13a0236" +dependencies = [ + "hmac 0.7.1", + "pbkdf2 0.3.0", + "schnorrkel", + "sha2 0.8.2", + "zeroize", +] + +[[package]] +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "474aaa926faa1603c40b7885a9eaea29b444d1cb2850cb7c0e37bb1a4182f4fa" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tiny-bip39" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0165e045cc2ae1660270ca65e1676dbaab60feb0f91b10f7d0665e9b47e31f2" +dependencies = [ + "failure", + "hmac 0.7.1", + "once_cell", + "pbkdf2 0.3.0", + "rand 0.7.3", + "rustc-hash", + "sha2 0.8.2", + "unicode-normalization", +] + +[[package]] +name = "tiny-bip39" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9e44c4759bae7f1032e286a7ef990bd9ed23fe831b7eeba0beb97484c2e59b8" +dependencies = [ + "anyhow", + "hmac 0.8.1", + "once_cell", + "pbkdf2 0.4.0", + "rand 0.7.3", + "rustc-hash", + "sha2 0.9.5", + "thiserror", + "unicode-normalization", + "zeroize", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "tinyvec" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +dependencies = [ + "cfg-if 1.0.0", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ca517f43f0fb96e0c3072ed5c275fe5eece87e8cb52f4a77b69226d3b1c9df8" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tracing-log" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cbe87a2fa7e35900ce5de20220a582a9483a7063811defce79d7cbd59d4cfe" +dependencies = [ + "ansi_term 0.12.1", + "chrono", + "lazy_static", + "matchers", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "trie-db" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eac131e334e81b6b3be07399482042838adcd7957aa0010231d0813e39e02fa" +dependencies = [ + "hash-db", + "hashbrown", + "log", + "rustc-hex", + "smallvec", +] + +[[package]] +name = "trie-root" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "652931506d2c1244d7217a70b99f56718a7b4161b37f04e7cd868072a99f68cd" +dependencies = [ + "hash-db", +] + +[[package]] +name = "twox-hash" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f559b464de2e2bdabcac6a210d12e9b5a5973c251e102c44c585c71d51bd78e" +dependencies = [ + "cfg-if 1.0.0", + "rand 0.8.4", + "static_assertions", +] + +[[package]] +name = "typenum" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" + +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + +[[package]] +name = "uint" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9db035e67dfaf7edd9aebfe8676afcd63eed53c8a4044fed514c8cccf1835177" +dependencies = [ + "byteorder", + "crunchy", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "uint" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6470ab50f482bde894a037a57064480a246dbfdd5960bd65a44824693f08da5f" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasm-bindgen" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29" + +[[package]] +name = "wasmi" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf617d864d25af3587aa745529f7aaa541066c876d57e050c0d0c85c61c92aff" +dependencies = [ + "libc", + "memory_units", + "num-rational 0.2.4", + "num-traits", + "parity-wasm 0.41.0", + "wasmi-validation 0.3.0", +] + +[[package]] +name = "wasmi" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ee05bba3d1d994652079893941a2ef9324d2b58a63c31b40678fb7eddd7a5a" +dependencies = [ + "downcast-rs", + "libc", + "memory_units", + "num-rational 0.2.4", + "num-traits", + "parity-wasm 0.42.2", + "wasmi-validation 0.4.0", +] + +[[package]] +name = "wasmi-validation" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea78c597064ba73596099281e2f4cfc019075122a65cdda3205af94f0b264d93" +dependencies = [ + "parity-wasm 0.41.0", +] + +[[package]] +name = "wasmi-validation" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb8e860796d8be48efef530b60eebf84e74a88bce107374fffb0da97d504b8" +dependencies = [ + "parity-wasm 0.42.2", +] + +[[package]] +name = "web-sys" +version = "0.3.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "which" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" +dependencies = [ + "libc", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + +[[package]] +name = "zeroize" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "377db0846015f7ae377174787dd452e1c5f5a9050bc6f954911d01f116daa0cd" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zstd" +version = "0.6.1+zstd.1.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de55e77f798f205d8561b8fe2ef57abfb6e0ff2abe7fd3c089e119cdb5631a3" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "3.0.1+zstd.1.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1387cabcd938127b30ce78c4bf00b30387dddf704e3f0881dbc4ff62b5566f8c" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "1.4.20+zstd.1.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd5b733d7cf2d9447e2c3e76a5589b4f5e5ae065c22a2bc0b023cbc331b6c8e" +dependencies = [ + "cc", + "libc", +] diff --git a/Cargo.toml b/Cargo.toml index 89d58e6b..d8979db0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,11 @@ members = [ "core", "extras", "integration_tests", + "substrate-metadata-versions/metadatav8", + "substrate-metadata-versions/metadatav9", + "substrate-metadata-versions/metadatav10", + "substrate-metadata-versions/metadatav11", + "substrate-metadata-versions/sp_core_versions/core-7314a" ] [patch.crates-io] diff --git a/core/Cargo.toml b/core/Cargo.toml index ed2297ae..66c4688b 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -25,10 +25,10 @@ primitives = { package = "sp-core", git = "https://github.com/paritytech/substr runtime-primitives = { package = "sp-runtime", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } frame-metadata = { package = "frame-metadata", git = "https://github.com/paritytech/frame-metadata", features = ["v12", "v13", "v14"] } -runtime-metadata11 = { git = "https://github.com/insipx/substrate-metadata-versions", package = "frame-metadatav11", branch = "master" } -runtime-metadata10 = { git = "https://github.com/insipx/substrate-metadata-versions", package = "frame-metadatav10", branch = "master" } -runtime-metadata09 = { git = "https://github.com/insipx/substrate-metadata-versions", package = "frame-metadatav9", branch = "master" } -runtime-metadata08 = { git = "https://github.com/insipx/substrate-metadata-versions", package = "frame-metadatav8", branch = "master" } +runtime-metadata11 = { path = "../substrate-metadata-versions/metadatav11", package = "frame-metadatav11" } +runtime-metadata10 = { path = "../substrate-metadata-versions/metadatav10", package = "frame-metadatav10" } +runtime-metadata09 = { path = "../substrate-metadata-versions/metadatav9", package = "frame-metadatav9" } +runtime-metadata08 = { path = "../substrate-metadata-versions/metadatav8", package = "frame-metadatav8" } [dev-dependencies] pretty_env_logger = "0.4" diff --git a/substrate-metadata-versions/metadatav10/Cargo.toml b/substrate-metadata-versions/metadatav10/Cargo.toml index 00094381..0537de40 100644 --- a/substrate-metadata-versions/metadatav10/Cargo.toml +++ b/substrate-metadata-versions/metadatav10/Cargo.toml @@ -9,7 +9,7 @@ license = "GPL-3.0" codec = { package = "parity-scale-codec", version = "1", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-std = { version = "2.0.0-rc6", default-features = false, git = "https://github.com/paritytech/substrate" , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } -sp-core = { version = "2.0.0-rc6", default-features = false, git = "https://github.com/paritytech/substrate" , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } +sp-core = { path = "../sp_core_versions/core-7314a/" } [features] default = ["std"] diff --git a/substrate-metadata-versions/metadatav11/Cargo.toml b/substrate-metadata-versions/metadatav11/Cargo.toml index 4884156e..469f3dd4 100644 --- a/substrate-metadata-versions/metadatav11/Cargo.toml +++ b/substrate-metadata-versions/metadatav11/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-std = { default-features = false, git = "https://github.com/paritytech/substrate" , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } -sp-core = { default-features = false, git = "https://github.com/paritytech/substrate" , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } +sp-core = { path = "../sp_core_versions/core-7314a/" } [features] default = ["std"] diff --git a/substrate-metadata-versions/metadatav8/Cargo.toml b/substrate-metadata-versions/metadatav8/Cargo.toml index 97d020e9..8bb24b03 100644 --- a/substrate-metadata-versions/metadatav8/Cargo.toml +++ b/substrate-metadata-versions/metadatav8/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" codec = { package = "parity-scale-codec", version = "1", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } rstd = { package = "sp-std", git = "https://github.com/paritytech/substrate", default-features = false , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } -primitives = { package = "sp-core", git = "https://github.com/paritytech/substrate", default-features = false , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } +primitives = { path = "../sp_core_versions/core-7314a/", package = "sp-core" } diff --git a/substrate-metadata-versions/metadatav9/Cargo.toml b/substrate-metadata-versions/metadatav9/Cargo.toml index 6f864429..d9d2745e 100644 --- a/substrate-metadata-versions/metadatav9/Cargo.toml +++ b/substrate-metadata-versions/metadatav9/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" codec = { package = "parity-scale-codec", version = "1", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } rstd = { package = "sp-std", git = "https://github.com/paritytech/substrate", default-features = false , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } -primitives = { package = "sp-core", git = "https://github.com/paritytech/substrate", default-features = false , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } +primitives = { path = "../sp_core_versions/core-7314a/", package = "sp-core" } [features] default = ["std"] diff --git a/substrate-metadata-versions/sp_core_versions/README.md b/substrate-metadata-versions/sp_core_versions/README.md new file mode 100644 index 00000000..9a94786a --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/README.md @@ -0,0 +1,7 @@ +# Locally-Patched `sp-core` packages. + +Usually, a dependency needs to be updated (generally parity-util mem). Dependencies which diverge +from the original package are topped with a comment of the format: +`# PATCHED.insipx.2021Aug20 from `version = "0.7.0"` + - this is mostly to easily & quickly rg patched dependencies + diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/Cargo.toml b/substrate-metadata-versions/sp_core_versions/core-7314a/Cargo.toml new file mode 100644 index 00000000..1ef45795 --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/Cargo.toml @@ -0,0 +1,126 @@ +[package] +name = "sp-core" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" +license = "Apache-2.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "Shareable Substrate types." +documentation = "https://docs.rs/sp-core" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +derive_more = "0.99.2" +sp-std = { version = "2.0.0", default-features = false, git = "https://github.com/paritytech/substrate", rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } +log = { version = "0.4.8", default-features = false } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +byteorder = { version = "1.3.2", default-features = false } +primitive-types = { version = "0.7.0", default-features = false, features = ["codec"] } +impl-serde = { version = "0.3.0", optional = true } +wasmi = { version = "0.6.2", optional = true } +hash-db = { version = "0.15.2", default-features = false } +hash256-std-hasher = { version = "0.15.2", default-features = false } +base58 = { version = "0.1.0", optional = true } +rand = { version = "0.7.3", optional = true, features = ["small_rng"] } +substrate-bip39 = { version = "0.4.2", optional = true } +tiny-bip39 = { version = "0.7", optional = true } +regex = { version = "1.3.1", optional = true } +num-traits = { version = "0.2.8", default-features = false } +zeroize = { version = "1.0.0", default-features = false } +secrecy = { version = "0.6.0", default-features = false } +lazy_static = { version = "1.4.0", default-features = false, optional = true } +parking_lot = { version = "0.10.0", optional = true } +sp-debug-derive = { version = "2.0.0", git = "https://github.com/paritytech/substrate", rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } +sp-externalities = { version = "0.8.0", optional = true, git = "https://github.com/paritytech/substrate", rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } +sp-storage = { version = "2.0.0", default-features = false, git = "https://github.com/paritytech/substrate", rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } +# PATCHED.insipx.2021Aug20 from `version = "0.7.0"` +parity-util-mem = { version = "0.10.0", default-features = false, features = ["primitive-types"] } +futures = { version = "0.3.1", optional = true } +dyn-clonable = { version = "0.9.0", optional = true } + +# full crypto +ed25519-dalek = { version = "1.0.0-pre.4", default-features = false, features = ["u64_backend", "alloc"], optional = true } +blake2-rfc = { version = "0.2.18", default-features = false, optional = true } +tiny-keccak = { version = "2.0.1", features = ["keccak"], optional = true } +schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated", "u64_backend"], default-features = false, optional = true } +sha2 = { version = "0.8.0", default-features = false, optional = true } +hex = { version = "0.4", default-features = false, optional = true } +twox-hash = { version = "1.5.0", default-features = false, optional = true } +libsecp256k1 = { version = "0.3.2", default-features = false, features = ["hmac"], optional = true } +merlin = { version = "2.0", default-features = false, optional = true } + +sp-runtime-interface = { version = "2.0.0", default-features = false, git = "https://github.com/paritytech/substrate", rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } + +[dev-dependencies] +sp-serializer = { version = "2.0.0", git = "https://github.com/paritytech/substrate", rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } +pretty_assertions = "0.6.1" +hex-literal = "0.3.1" +rand = "0.7.2" +criterion = "0.3.3" +serde_json = "1.0" +rand_chacha = "0.2.2" + +[features] +default = ["std"] +std = [ + "full_crypto", + "log/std", + "wasmi", + "lazy_static", + "parking_lot", + "primitive-types/std", + "primitive-types/serde", + "primitive-types/byteorder", + "primitive-types/rustc-hex", + "impl-serde", + "codec/std", + "hash256-std-hasher/std", + "hash-db/std", + "sp-std/std", + "serde", + "twox-hash/std", + "blake2-rfc/std", + "ed25519-dalek/std", + "hex/std", + "base58", + "substrate-bip39", + "tiny-bip39", + "serde", + "byteorder/std", + "rand", + "sha2/std", + "schnorrkel/std", + "regex", + "num-traits/std", + "tiny-keccak", + "sp-debug-derive/std", + "sp-externalities", + "sp-storage/std", + "sp-runtime-interface/std", + "zeroize/alloc", + "secrecy/alloc", + "futures", + "futures/thread-pool", + "libsecp256k1/std", + "dyn-clonable", +] + +# This feature enables all crypto primitives for `no_std` builds like microcontrollers +# or Intel SGX. +# For the regular wasm runtime builds this should not be used. +full_crypto = [ + "ed25519-dalek", + "blake2-rfc", + "tiny-keccak", + "schnorrkel", + "hex", + "sha2", + "twox-hash", + "libsecp256k1", + "sp-runtime-interface/disable_target_static_assertions", + "merlin", +] diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/changes_trie.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/changes_trie.rs new file mode 100644 index 00000000..1d88242e --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/changes_trie.rs @@ -0,0 +1,306 @@ +// This file is part of Substrate. + +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Substrate changes trie configuration. + +#[cfg(any(feature = "std", test))] +use serde::{Serialize, Deserialize}; +use codec::{Encode, Decode}; +use num_traits::Zero; + +/// Substrate changes trie configuration. +#[cfg_attr(any(feature = "std", test), derive(Serialize, Deserialize, parity_util_mem::MallocSizeOf))] +#[derive(Debug, Clone, PartialEq, Eq, Default, Encode, Decode)] +pub struct ChangesTrieConfiguration { + /// Interval (in blocks) at which level1-digests are created. Digests are not + /// created when this is less or equal to 1. + pub digest_interval: u32, + /// Maximal number of digest levels in hierarchy. 0 means that digests are not + /// created at all (even level1 digests). 1 means only level1-digests are created. + /// 2 means that every digest_interval^2 there will be a level2-digest, and so on. + /// Please ensure that maximum digest interval (i.e. digest_interval^digest_levels) + /// is within `u32` limits. Otherwise you'll never see digests covering such intervals + /// && maximal digests interval will be truncated to the last interval that fits + /// `u32` limits. + pub digest_levels: u32, +} + +/// Substrate changes trie configuration range. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ChangesTrieConfigurationRange { + /// Zero block of configuration. + pub zero: (Number, Hash), + /// Last block of configuration (if configuration has been deactivated at some point). + pub end: Option<(Number, Hash)>, + /// The configuration itself. None if changes tries were disabled in this range. + pub config: Option, +} + +impl ChangesTrieConfiguration { + /// Create new configuration given digest interval and levels. + pub fn new(digest_interval: u32, digest_levels: u32) -> Self { + Self { digest_interval, digest_levels } + } + + /// Is digest build enabled? + pub fn is_digest_build_enabled(&self) -> bool { + self.digest_interval > 1 && self.digest_levels > 0 + } + + /// Do we need to build digest at given block? + pub fn is_digest_build_required_at_block( + &self, + zero: Number, + block: Number, + ) -> bool + where + Number: From + PartialEq + + ::sp_std::ops::Rem + ::sp_std::ops::Sub + + ::sp_std::cmp::PartialOrd + Zero, + { + block > zero + && self.is_digest_build_enabled() + && ((block - zero) % self.digest_interval.into()).is_zero() + } + + /// Returns max digest interval. One if digests are not created at all. + pub fn max_digest_interval(&self) -> u32 { + if !self.is_digest_build_enabled() { + return 1; + } + + // we'll get >1 loop iteration only when bad configuration parameters are selected + let mut current_level = self.digest_levels; + loop { + if let Some(max_digest_interval) = self.digest_interval.checked_pow(current_level) { + return max_digest_interval; + } + + current_level = current_level - 1; + } + } + + /// Returns max level digest block number that has been created at block <= passed block number. + /// + /// Returns None if digests are not created at all. + pub fn prev_max_level_digest_block( + &self, + zero: Number, + block: Number, + ) -> Option + where + Number: Clone + From + PartialOrd + PartialEq + + ::sp_std::ops::Add + ::sp_std::ops::Sub + + ::sp_std::ops::Div + ::sp_std::ops::Mul + Zero, + { + if block <= zero { + return None; + } + + let (next_begin, next_end) = self.next_max_level_digest_range(zero.clone(), block.clone())?; + + // if 'next' digest includes our block, then it is a also a previous digest + if next_end == block { + return Some(block); + } + + // if previous digest ends at zero block, then there are no previous digest + let prev_end = next_begin - 1.into(); + if prev_end == zero { + None + } else { + Some(prev_end) + } + } + + /// Returns max level digest blocks range (inclusive) which includes passed block. + /// + /// Returns None if digests are not created at all. + /// It will return the first max-level digest if block is <= zero. + pub fn next_max_level_digest_range( + &self, + zero: Number, + mut block: Number, + ) -> Option<(Number, Number)> + where + Number: Clone + From + PartialOrd + PartialEq + + ::sp_std::ops::Add + ::sp_std::ops::Sub + + ::sp_std::ops::Div + ::sp_std::ops::Mul, + { + if !self.is_digest_build_enabled() { + return None; + } + + if block <= zero { + block = zero.clone() + 1.into(); + } + + let max_digest_interval: Number = self.max_digest_interval().into(); + let max_digests_since_zero = (block.clone() - zero.clone()) / max_digest_interval.clone(); + if max_digests_since_zero == 0.into() { + return Some((zero.clone() + 1.into(), zero + max_digest_interval)); + } + let last_max_digest_block = zero + max_digests_since_zero * max_digest_interval.clone(); + Some(if block == last_max_digest_block { + (block.clone() - max_digest_interval + 1.into(), block) + } else { + (last_max_digest_block.clone() + 1.into(), last_max_digest_block + max_digest_interval) + }) + } + + /// Returns Some if digest must be built at given block number. + /// The tuple is: + /// ( + /// digest level + /// digest interval (in blocks) + /// step between blocks we're interested in when digest is built + /// ) + pub fn digest_level_at_block(&self, zero: Number, block: Number) -> Option<(u32, u32, u32)> + where + Number: Clone + From + PartialEq + + ::sp_std::ops::Rem + ::sp_std::ops::Sub + + ::sp_std::cmp::PartialOrd + Zero, + { + if !self.is_digest_build_required_at_block(zero.clone(), block.clone()) { + return None; + } + + let relative_block = block - zero; + let mut digest_interval = self.digest_interval; + let mut current_level = 1u32; + let mut digest_step = 1u32; + while current_level < self.digest_levels { + let new_digest_interval = match digest_interval.checked_mul(self.digest_interval) { + Some(new_digest_interval) if (relative_block.clone() % new_digest_interval.into()).is_zero() + => new_digest_interval, + _ => break, + }; + + digest_step = digest_interval; + digest_interval = new_digest_interval; + current_level = current_level + 1; + } + + Some(( + current_level, + digest_interval, + digest_step, + )) + } +} + +#[cfg(test)] +mod tests { + use super::ChangesTrieConfiguration; + + fn config(interval: u32, levels: u32) -> ChangesTrieConfiguration { + ChangesTrieConfiguration { + digest_interval: interval, + digest_levels: levels, + } + } + + #[test] + fn is_digest_build_enabled_works() { + assert!(!config(0, 100).is_digest_build_enabled()); + assert!(!config(1, 100).is_digest_build_enabled()); + assert!(config(2, 100).is_digest_build_enabled()); + assert!(!config(100, 0).is_digest_build_enabled()); + assert!(config(100, 1).is_digest_build_enabled()); + } + + #[test] + fn is_digest_build_required_at_block_works() { + fn test_with_zero(zero: u64) { + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 0u64)); + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 1u64)); + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 2u64)); + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 4u64)); + assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 8u64)); + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 9u64)); + assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 64u64)); + assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 64u64)); + assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 512u64)); + assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 4096u64)); + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 4103u64)); + assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 4104u64)); + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 4108u64)); + } + + test_with_zero(0); + test_with_zero(8); + test_with_zero(17); + } + + #[test] + fn digest_level_at_block_works() { + fn test_with_zero(zero: u64) { + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 0u64), None); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 7u64), None); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 63u64), None); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 8u64), Some((1, 8, 1))); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 64u64), Some((2, 64, 8))); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 512u64), Some((3, 512, 64))); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 4096u64), Some((4, 4096, 512))); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 4112u64), Some((1, 8, 1))); + } + + test_with_zero(0); + test_with_zero(8); + test_with_zero(17); + } + + #[test] + fn max_digest_interval_works() { + assert_eq!(config(0, 0).max_digest_interval(), 1); + assert_eq!(config(2, 2).max_digest_interval(), 4); + assert_eq!(config(8, 4).max_digest_interval(), 4096); + assert_eq!(config(::std::u32::MAX, 1024).max_digest_interval(), ::std::u32::MAX); + } + + #[test] + fn next_max_level_digest_range_works() { + assert_eq!(config(0, 0).next_max_level_digest_range(0u64, 16), None); + assert_eq!(config(1, 1).next_max_level_digest_range(0u64, 16), None); + assert_eq!(config(2, 1).next_max_level_digest_range(0u64, 16), Some((15, 16))); + assert_eq!(config(4, 1).next_max_level_digest_range(0u64, 16), Some((13, 16))); + assert_eq!(config(32, 1).next_max_level_digest_range(0u64, 16), Some((1, 32))); + assert_eq!(config(2, 3).next_max_level_digest_range(0u64, 10), Some((9, 16))); + assert_eq!(config(2, 3).next_max_level_digest_range(0u64, 8), Some((1, 8))); + assert_eq!(config(2, 1).next_max_level_digest_range(1u64, 1), Some((2, 3))); + assert_eq!(config(2, 2).next_max_level_digest_range(7u64, 9), Some((8, 11))); + + assert_eq!(config(2, 2).next_max_level_digest_range(7u64, 5), Some((8, 11))); + } + + #[test] + fn prev_max_level_digest_block_works() { + assert_eq!(config(0, 0).prev_max_level_digest_block(0u64, 16), None); + assert_eq!(config(1, 1).prev_max_level_digest_block(0u64, 16), None); + assert_eq!(config(2, 1).prev_max_level_digest_block(0u64, 16), Some(16)); + assert_eq!(config(4, 1).prev_max_level_digest_block(0u64, 16), Some(16)); + assert_eq!(config(4, 2).prev_max_level_digest_block(0u64, 16), Some(16)); + assert_eq!(config(4, 2).prev_max_level_digest_block(0u64, 17), Some(16)); + assert_eq!(config(4, 2).prev_max_level_digest_block(0u64, 33), Some(32)); + assert_eq!(config(32, 1).prev_max_level_digest_block(0u64, 16), None); + assert_eq!(config(2, 3).prev_max_level_digest_block(0u64, 10), Some(8)); + assert_eq!(config(2, 3).prev_max_level_digest_block(0u64, 8), Some(8)); + assert_eq!(config(2, 2).prev_max_level_digest_block(7u64, 8), None); + + assert_eq!(config(2, 2).prev_max_level_digest_block(7u64, 5), None); + } +} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/crypto.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/crypto.rs new file mode 100644 index 00000000..c0a85cb2 --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/crypto.rs @@ -0,0 +1,1263 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// tag::description[] +//! Cryptographic utilities. +// end::description[] + +use crate::{sr25519, ed25519}; +use sp_std::hash::Hash; +use sp_std::vec::Vec; +use sp_std::str; +#[cfg(feature = "std")] +use sp_std::convert::TryInto; +use sp_std::convert::TryFrom; +#[cfg(feature = "std")] +use parking_lot::Mutex; +#[cfg(feature = "std")] +use rand::{RngCore, rngs::OsRng}; +use codec::{Encode, Decode}; +#[cfg(feature = "std")] +use regex::Regex; +#[cfg(feature = "std")] +use base58::{FromBase58, ToBase58}; +#[cfg(feature = "std")] +use crate::hexdisplay::HexDisplay; +#[doc(hidden)] +pub use sp_std::ops::Deref; +use sp_runtime_interface::pass_by::PassByInner; +/// Trait to zeroize a memory buffer. +pub use zeroize::Zeroize; +/// Trait for accessing reference to `SecretString`. +pub use secrecy::ExposeSecret; +/// A store for sensitive data. +#[cfg(feature = "std")] +pub use secrecy::SecretString; + +/// The root phrase for our publicly known keys. +pub const DEV_PHRASE: &str = "bottom drive obey lake curtain smoke basket hold race lonely fit walk"; + +/// The address of the associated root phrase for our publicly known keys. +pub const DEV_ADDRESS: &str = "5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqRzV"; + +/// The infallible type. +#[derive(crate::RuntimeDebug)] +pub enum Infallible {} + +/// The length of the junction identifier. Note that this is also referred to as the +/// `CHAIN_CODE_LENGTH` in the context of Schnorrkel. +#[cfg(feature = "full_crypto")] +pub const JUNCTION_ID_LEN: usize = 32; + +/// Similar to `From`, except that the onus is on the part of the caller to ensure +/// that data passed in makes sense. Basically, you're not guaranteed to get anything +/// sensible out. +pub trait UncheckedFrom { + /// Convert from an instance of `T` to Self. This is not guaranteed to be + /// whatever counts as a valid instance of `T` and it's up to the caller to + /// ensure that it makes sense. + fn unchecked_from(t: T) -> Self; +} + +/// The counterpart to `UncheckedFrom`. +pub trait UncheckedInto { + /// The counterpart to `unchecked_from`. + fn unchecked_into(self) -> T; +} + +impl> UncheckedInto for S { + fn unchecked_into(self) -> T { + T::unchecked_from(self) + } +} + +/// An error with the interpretation of a secret. +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg(feature = "full_crypto")] +pub enum SecretStringError { + /// The overall format was invalid (e.g. the seed phrase contained symbols). + InvalidFormat, + /// The seed phrase provided is not a valid BIP39 phrase. + InvalidPhrase, + /// The supplied password was invalid. + InvalidPassword, + /// The seed is invalid (bad content). + InvalidSeed, + /// The seed has an invalid length. + InvalidSeedLength, + /// The derivation path was invalid (e.g. contains soft junctions when they are not supported). + InvalidPath, +} + +/// A since derivation junction description. It is the single parameter used when creating +/// a new secret key from an existing secret key and, in the case of `SoftRaw` and `SoftIndex` +/// a new public key from an existing public key. +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Encode, Decode)] +#[cfg(feature = "full_crypto")] +pub enum DeriveJunction { + /// Soft (vanilla) derivation. Public keys have a correspondent derivation. + Soft([u8; JUNCTION_ID_LEN]), + /// Hard ("hardened") derivation. Public keys do not have a correspondent derivation. + Hard([u8; JUNCTION_ID_LEN]), +} + +#[cfg(feature = "full_crypto")] +impl DeriveJunction { + /// Consume self to return a soft derive junction with the same chain code. + pub fn soften(self) -> Self { DeriveJunction::Soft(self.unwrap_inner()) } + + /// Consume self to return a hard derive junction with the same chain code. + pub fn harden(self) -> Self { DeriveJunction::Hard(self.unwrap_inner()) } + + /// Create a new soft (vanilla) DeriveJunction from a given, encodable, value. + /// + /// If you need a hard junction, use `hard()`. + pub fn soft(index: T) -> Self { + let mut cc: [u8; JUNCTION_ID_LEN] = Default::default(); + index.using_encoded(|data| if data.len() > JUNCTION_ID_LEN { + let hash_result = blake2_rfc::blake2b::blake2b(JUNCTION_ID_LEN, &[], data); + let hash = hash_result.as_bytes(); + cc.copy_from_slice(hash); + } else { + cc[0..data.len()].copy_from_slice(data); + }); + DeriveJunction::Soft(cc) + } + + /// Create a new hard (hardened) DeriveJunction from a given, encodable, value. + /// + /// If you need a soft junction, use `soft()`. + pub fn hard(index: T) -> Self { + Self::soft(index).harden() + } + + /// Consume self to return the chain code. + pub fn unwrap_inner(self) -> [u8; JUNCTION_ID_LEN] { + match self { + DeriveJunction::Hard(c) | DeriveJunction::Soft(c) => c, + } + } + + /// Get a reference to the inner junction id. + pub fn inner(&self) -> &[u8; JUNCTION_ID_LEN] { + match self { + DeriveJunction::Hard(ref c) | DeriveJunction::Soft(ref c) => c, + } + } + + /// Return `true` if the junction is soft. + pub fn is_soft(&self) -> bool { + match *self { + DeriveJunction::Soft(_) => true, + _ => false, + } + } + + /// Return `true` if the junction is hard. + pub fn is_hard(&self) -> bool { + match *self { + DeriveJunction::Hard(_) => true, + _ => false, + } + } +} + +#[cfg(feature = "full_crypto")] +impl> From for DeriveJunction { + fn from(j: T) -> DeriveJunction { + let j = j.as_ref(); + let (code, hard) = if j.starts_with('/') { + (&j[1..], true) + } else { + (j, false) + }; + + let res = if let Ok(n) = str::parse::(code) { + // number + DeriveJunction::soft(n) + } else { + // something else + DeriveJunction::soft(code) + }; + + if hard { + res.harden() + } else { + res + } + } +} + +/// An error type for SS58 decoding. +#[cfg(feature = "full_crypto")] +#[derive(Clone, Copy, Eq, PartialEq, Debug)] +pub enum PublicError { + /// Bad alphabet. + BadBase58, + /// Bad length. + BadLength, + /// Unknown version. + UnknownVersion, + /// Invalid checksum. + InvalidChecksum, + /// Invalid format. + InvalidFormat, + /// Invalid derivation path. + InvalidPath, +} + +/// Key that can be encoded to/from SS58. +#[cfg(feature = "full_crypto")] +pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default { + /// Some if the string is a properly encoded SS58Check address. + #[cfg(feature = "std")] + fn from_ss58check(s: &str) -> Result { + Self::from_ss58check_with_version(s) + .and_then(|(r, v)| match v { + v if !v.is_custom() => Ok(r), + v if v == *DEFAULT_VERSION.lock() => Ok(r), + _ => Err(PublicError::UnknownVersion), + }) + } + /// Some if the string is a properly encoded SS58Check address. + #[cfg(feature = "std")] + fn from_ss58check_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> { + let mut res = Self::default(); + let len = res.as_mut().len(); + let d = s.from_base58().map_err(|_| PublicError::BadBase58)?; // failure here would be invalid encoding. + if d.len() != len + 3 { + // Invalid length. + return Err(PublicError::BadLength); + } + let ver = d[0].try_into().map_err(|_: ()| PublicError::UnknownVersion)?; + + if d[len + 1..len + 3] != ss58hash(&d[0..len + 1]).as_bytes()[0..2] { + // Invalid checksum. + return Err(PublicError::InvalidChecksum); + } + res.as_mut().copy_from_slice(&d[1..len + 1]); + Ok((res, ver)) + } + /// Some if the string is a properly encoded SS58Check address, optionally with + /// a derivation path following. + #[cfg(feature = "std")] + fn from_string(s: &str) -> Result { + Self::from_string_with_version(s) + .and_then(|(r, v)| match v { + v if !v.is_custom() => Ok(r), + v if v == *DEFAULT_VERSION.lock() => Ok(r), + _ => Err(PublicError::UnknownVersion), + }) + } + + /// Return the ss58-check string for this key. + #[cfg(feature = "std")] + fn to_ss58check_with_version(&self, version: Ss58AddressFormat) -> String { + let mut v = vec![version.into()]; + v.extend(self.as_ref()); + let r = ss58hash(&v); + v.extend(&r.as_bytes()[0..2]); + v.to_base58() + } + + /// Return the ss58-check string for this key. + #[cfg(feature = "std")] + fn to_ss58check(&self) -> String { self.to_ss58check_with_version(*DEFAULT_VERSION.lock()) } + + /// Some if the string is a properly encoded SS58Check address, optionally with + /// a derivation path following. + #[cfg(feature = "std")] + fn from_string_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> { + Self::from_ss58check_with_version(s) + } +} + +/// Derivable key trait. +pub trait Derive: Sized { + /// Derive a child key from a series of given junctions. + /// + /// Will be `None` for public keys if there are any hard junctions in there. + #[cfg(feature = "std")] + fn derive>(&self, _path: Iter) -> Option { + None + } +} + +#[cfg(feature = "std")] +const PREFIX: &[u8] = b"SS58PRE"; + +#[cfg(feature = "std")] +fn ss58hash(data: &[u8]) -> blake2_rfc::blake2b::Blake2bResult { + let mut context = blake2_rfc::blake2b::Blake2b::new(64); + context.update(PREFIX); + context.update(data); + context.finalize() +} + +#[cfg(feature = "std")] +lazy_static::lazy_static! { + static ref DEFAULT_VERSION: Mutex + = Mutex::new(Ss58AddressFormat::SubstrateAccount); +} + +#[cfg(feature = "full_crypto")] +macro_rules! ss58_address_format { + ( $( $identifier:tt => ($number:expr, $name:expr, $desc:tt) )* ) => ( + /// A known address (sub)format/network ID for SS58. + #[derive(Copy, Clone, PartialEq, Eq, crate::RuntimeDebug)] + pub enum Ss58AddressFormat { + $(#[doc = $desc] $identifier),*, + /// Use a manually provided numeric value. + Custom(u8), + } + + #[cfg(feature = "std")] + impl std::fmt::Display for Ss58AddressFormat { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + $( + Ss58AddressFormat::$identifier => write!(f, "{}", $name), + )* + Ss58AddressFormat::Custom(x) => write!(f, "{}", x), + } + + } + } + + static ALL_SS58_ADDRESS_FORMATS: [Ss58AddressFormat; 0 $(+ { let _ = $number; 1})*] = [ + $(Ss58AddressFormat::$identifier),*, + ]; + + impl Ss58AddressFormat { + /// names of all address formats + pub fn all_names() -> &'static [&'static str] { + &[ + $($name),*, + ] + } + /// All known address formats. + pub fn all() -> &'static [Ss58AddressFormat] { + &ALL_SS58_ADDRESS_FORMATS + } + + /// Whether the address is custom. + pub fn is_custom(&self) -> bool { + match self { + Self::Custom(_) => true, + _ => false, + } + } + } + + impl From for u8 { + fn from(x: Ss58AddressFormat) -> u8 { + match x { + $(Ss58AddressFormat::$identifier => $number),*, + Ss58AddressFormat::Custom(n) => n, + } + } + } + + impl TryFrom for Ss58AddressFormat { + type Error = (); + + fn try_from(x: u8) -> Result { + match x { + $($number => Ok(Ss58AddressFormat::$identifier)),*, + _ => { + #[cfg(feature = "std")] + match Ss58AddressFormat::default() { + Ss58AddressFormat::Custom(n) if n == x => Ok(Ss58AddressFormat::Custom(x)), + _ => Err(()), + } + + #[cfg(not(feature = "std"))] + Err(()) + }, + } + } + } + + /// Error encountered while parsing `Ss58AddressFormat` from &'_ str + /// unit struct for now. + #[derive(Copy, Clone, PartialEq, Eq, crate::RuntimeDebug)] + pub struct ParseError; + + impl<'a> TryFrom<&'a str> for Ss58AddressFormat { + type Error = ParseError; + + fn try_from(x: &'a str) -> Result { + match x { + $($name => Ok(Ss58AddressFormat::$identifier)),*, + a => a.parse::().map(Ss58AddressFormat::Custom).map_err(|_| ParseError), + } + } + } + + #[cfg(feature = "std")] + impl std::str::FromStr for Ss58AddressFormat { + type Err = ParseError; + + fn from_str(data: &str) -> Result { + Self::try_from(data) + } + } + + #[cfg(feature = "std")] + impl std::fmt::Display for ParseError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "failed to parse network value as u8") + } + } + + #[cfg(feature = "std")] + impl Default for Ss58AddressFormat { + fn default() -> Self { + *DEFAULT_VERSION.lock() + } + } + + #[cfg(feature = "std")] + impl From for String { + fn from(x: Ss58AddressFormat) -> String { + x.to_string() + } + } + ) +} + +#[cfg(feature = "full_crypto")] +ss58_address_format!( + PolkadotAccount => + (0, "polkadot", "Polkadot Relay-chain, standard account (*25519).") + Reserved1 => + (1, "reserved1", "Reserved for future use (1).") + KusamaAccount => + (2, "kusama", "Kusama Relay-chain, standard account (*25519).") + Reserved3 => + (3, "reserved3", "Reserved for future use (3).") + KatalChainAccount => + (4, "katalchain", "Katal Chain, standard account (*25519).") + PlasmAccount => + (5, "plasm", "Plasm Network, standard account (*25519).") + BifrostAccount => + (6, "bifrost", "Bifrost mainnet, direct checksum, standard account (*25519).") + EdgewareAccount => + (7, "edgeware", "Edgeware mainnet, standard account (*25519).") + KaruraAccount => + (8, "karura", "Acala Karura canary network, standard account (*25519).") + ReynoldsAccount => + (9, "reynolds", "Laminar Reynolds canary network, standard account (*25519).") + AcalaAccount => + (10, "acala", "Acala mainnet, standard account (*25519).") + LaminarAccount => + (11, "laminar", "Laminar mainnet, standard account (*25519).") + PolymathAccount => + (12, "polymath", "Polymath network, standard account (*25519).") + SubstraTeeAccount => + (13, "substratee", "Any SubstraTEE off-chain network private account (*25519).") + KulupuAccount => + (16, "kulupu", "Kulupu mainnet, standard account (*25519).") + DarkAccount => + (17, "dark", "Dark mainnet, standard account (*25519).") + DarwiniaAccount => + (18, "darwinia", "Darwinia Chain mainnet, standard account (*25519).") + GeekAccount => + (19, "geek", "GeekCash mainnet, standard account (*25519).") + StafiAccount => + (20, "stafi", "Stafi mainnet, standard account (*25519).") + DockTestAccount => + (21, "dock-testnet", "Dock testnet, standard account (*25519).") + DockMainAccount => + (22, "dock-mainnet", "Dock mainnet, standard account (*25519).") + ShiftNrg => + (23, "shift", "ShiftNrg mainnet, standard account (*25519).") + SubsocialAccount => + (28, "subsocial", "Subsocial network, standard account (*25519).") + PhalaAccount => + (30, "phala", "Phala Network, standard account (*25519).") + RobonomicsAccount => + (32, "robonomics", "Any Robonomics network standard account (*25519).") + DataHighwayAccount => + (33, "datahighway", "DataHighway mainnet, standard account (*25519).") + CentrifugeAccount => + (36, "centrifuge", "Centrifuge Chain mainnet, standard account (*25519).") + SubstrateAccount => + (42, "substrate", "Any Substrate network, standard account (*25519).") + Reserved43 => + (43, "reserved43", "Reserved for future use (43).") + ChainXAccount => + (44, "chainx", "ChainX mainnet, standard account (*25519).") + Reserved46 => + (46, "reserved46", "Reserved for future use (46).") + Reserved47 => + (47, "reserved47", "Reserved for future use (47).") + // Note: 48 and above are reserved. +); + +/// Set the default "version" (actually, this is a bit of a misnomer and the version byte is +/// typically used not just to encode format/version but also network identity) that is used for +/// encoding and decoding SS58 addresses. If an unknown version is provided then it fails. +/// +/// See `ss58_address_format!` for all current known "versions". +#[cfg(feature = "std")] +pub fn set_default_ss58_version(version: Ss58AddressFormat) { + *DEFAULT_VERSION.lock() = version +} + +#[cfg(feature = "std")] +impl + AsRef<[u8]> + Default + Derive> Ss58Codec for T { + fn from_string(s: &str) -> Result { + let re = Regex::new(r"^(?P[\w\d ]+)?(?P(//?[^/]+)*)$") + .expect("constructed from known-good static value; qed"); + let cap = re.captures(s).ok_or(PublicError::InvalidFormat)?; + let re_junction = Regex::new(r"/(/?[^/]+)") + .expect("constructed from known-good static value; qed"); + let s = cap.name("ss58") + .map(|r| r.as_str()) + .unwrap_or(DEV_ADDRESS); + let addr = if s.starts_with("0x") { + let d = hex::decode(&s[2..]).map_err(|_| PublicError::InvalidFormat)?; + let mut r = Self::default(); + if d.len() == r.as_ref().len() { + r.as_mut().copy_from_slice(&d); + r + } else { + Err(PublicError::BadLength)? + } + } else { + Self::from_ss58check(s)? + }; + if cap["path"].is_empty() { + Ok(addr) + } else { + let path = re_junction.captures_iter(&cap["path"]) + .map(|f| DeriveJunction::from(&f[1])); + addr.derive(path) + .ok_or(PublicError::InvalidPath) + } + } + + fn from_string_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> { + let re = Regex::new(r"^(?P[\w\d ]+)?(?P(//?[^/]+)*)$") + .expect("constructed from known-good static value; qed"); + let cap = re.captures(s).ok_or(PublicError::InvalidFormat)?; + let re_junction = Regex::new(r"/(/?[^/]+)") + .expect("constructed from known-good static value; qed"); + let (addr, v) = Self::from_ss58check_with_version( + cap.name("ss58") + .map(|r| r.as_str()) + .unwrap_or(DEV_ADDRESS) + )?; + if cap["path"].is_empty() { + Ok((addr, v)) + } else { + let path = re_junction.captures_iter(&cap["path"]) + .map(|f| DeriveJunction::from(&f[1])); + addr.derive(path) + .ok_or(PublicError::InvalidPath) + .map(|a| (a, v)) + } + } +} + +/// Trait suitable for typical cryptographic PKI key public type. +pub trait Public: + AsRef<[u8]> + AsMut<[u8]> + Default + Derive + CryptoType + PartialEq + Eq + Clone + Send + Sync +{ + /// A new instance from the given slice. + /// + /// NOTE: No checking goes on to ensure this is a real public key. Only use it if + /// you are certain that the array actually is a pubkey. GIGO! + fn from_slice(data: &[u8]) -> Self; + + /// Return a `Vec` filled with raw data. + fn to_raw_vec(&self) -> Vec { self.as_slice().to_vec() } + + /// Return a slice filled with raw data. + fn as_slice(&self) -> &[u8] { self.as_ref() } + /// Return `CryptoTypePublicPair` from public key. + fn to_public_crypto_pair(&self) -> CryptoTypePublicPair; +} + +/// An opaque 32-byte cryptographic identifier. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Default, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Hash))] +pub struct AccountId32([u8; 32]); + +impl UncheckedFrom for AccountId32 { + fn unchecked_from(h: crate::hash::H256) -> Self { + AccountId32(h.into()) + } +} + +#[cfg(feature = "std")] +impl Ss58Codec for AccountId32 {} + +impl AsRef<[u8]> for AccountId32 { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl AsMut<[u8]> for AccountId32 { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0[..] + } +} + +impl AsRef<[u8; 32]> for AccountId32 { + fn as_ref(&self) -> &[u8; 32] { + &self.0 + } +} + +impl AsMut<[u8; 32]> for AccountId32 { + fn as_mut(&mut self) -> &mut [u8; 32] { + &mut self.0 + } +} + +impl From<[u8; 32]> for AccountId32 { + fn from(x: [u8; 32]) -> AccountId32 { + AccountId32(x) + } +} + +impl<'a> sp_std::convert::TryFrom<&'a [u8]> for AccountId32 { + type Error = (); + fn try_from(x: &'a [u8]) -> Result { + if x.len() == 32 { + let mut r = AccountId32::default(); + r.0.copy_from_slice(x); + Ok(r) + } else { + Err(()) + } + } +} + +impl From for [u8; 32] { + fn from(x: AccountId32) -> [u8; 32] { + x.0 + } +} + +impl From for AccountId32 { + fn from(k: sr25519::Public) -> Self { + k.0.into() + } +} + +impl From for AccountId32 { + fn from(k: ed25519::Public) -> Self { + k.0.into() + } +} + +#[cfg(feature = "std")] +impl std::fmt::Display for AccountId32 { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_ss58check()) + } +} + +impl sp_std::fmt::Debug for AccountId32 { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + let s = self.to_ss58check(); + write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } +} + +#[cfg(feature = "std")] +impl serde::Serialize for AccountId32 { + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + serializer.serialize_str(&self.to_ss58check()) + } +} + +#[cfg(feature = "std")] +impl<'de> serde::Deserialize<'de> for AccountId32 { + fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { + Ss58Codec::from_ss58check(&String::deserialize(deserializer)?) + .map_err(|e| serde::de::Error::custom(format!("{:?}", e))) + } +} + +#[cfg(feature = "std")] +impl sp_std::str::FromStr for AccountId32 { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + let hex_or_ss58_without_prefix = s.trim_start_matches("0x"); + if hex_or_ss58_without_prefix.len() == 64 { + let mut bytes = [0u8; 32]; + hex::decode_to_slice(hex_or_ss58_without_prefix, &mut bytes) + .map_err(|_| "invalid hex address.") + .map(|_| Self::from(bytes)) + } else { + Self::from_ss58check(s).map_err(|_| "invalid ss58 address.") + } + } +} + +#[cfg(feature = "std")] +pub use self::dummy::*; + +#[cfg(feature = "std")] +mod dummy { + use super::*; + + /// Dummy cryptography. Doesn't do anything. + #[derive(Clone, Hash, Default, Eq, PartialEq)] + pub struct Dummy; + + impl AsRef<[u8]> for Dummy { + fn as_ref(&self) -> &[u8] { &b""[..] } + } + + impl AsMut<[u8]> for Dummy { + fn as_mut(&mut self) -> &mut[u8] { + unsafe { + #[allow(mutable_transmutes)] + sp_std::mem::transmute::<_, &'static mut [u8]>(&b""[..]) + } + } + } + + impl CryptoType for Dummy { + type Pair = Dummy; + } + + impl Derive for Dummy {} + + impl Public for Dummy { + fn from_slice(_: &[u8]) -> Self { Self } + #[cfg(feature = "std")] + fn to_raw_vec(&self) -> Vec { vec![] } + fn as_slice(&self) -> &[u8] { b"" } + fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { + CryptoTypePublicPair( + CryptoTypeId(*b"dumm"), Public::to_raw_vec(self) + ) + } + } + + impl Pair for Dummy { + type Public = Dummy; + type Seed = Dummy; + type Signature = Dummy; + type DeriveError = (); + #[cfg(feature = "std")] + fn generate_with_phrase(_: Option<&str>) -> (Self, String, Self::Seed) { Default::default() } + #[cfg(feature = "std")] + fn from_phrase(_: &str, _: Option<&str>) + -> Result<(Self, Self::Seed), SecretStringError> + { + Ok(Default::default()) + } + fn derive< + Iter: Iterator, + >(&self, _: Iter, _: Option) -> Result<(Self, Option), Self::DeriveError> { Ok((Self, None)) } + fn from_seed(_: &Self::Seed) -> Self { Self } + fn from_seed_slice(_: &[u8]) -> Result { Ok(Self) } + fn sign(&self, _: &[u8]) -> Self::Signature { Self } + fn verify>(_: &Self::Signature, _: M, _: &Self::Public) -> bool { true } + fn verify_weak, M: AsRef<[u8]>>(_: &[u8], _: M, _: P) -> bool { true } + fn public(&self) -> Self::Public { Self } + fn to_raw_vec(&self) -> Vec { vec![] } + } +} + +/// Trait suitable for typical cryptographic PKI key pair type. +/// +/// For now it just specifies how to create a key from a phrase and derivation path. +#[cfg(feature = "full_crypto")] +pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static { + /// The type which is used to encode a public key. + type Public: Public + Hash; + + /// The type used to (minimally) encode the data required to securely create + /// a new key pair. + type Seed: Default + AsRef<[u8]> + AsMut<[u8]> + Clone; + + /// The type used to represent a signature. Can be created from a key pair and a message + /// and verified with the message and a public key. + type Signature: AsRef<[u8]>; + + /// Error returned from the `derive` function. + type DeriveError; + + /// Generate new secure (random) key pair. + /// + /// This is only for ephemeral keys really, since you won't have access to the secret key + /// for storage. If you want a persistent key pair, use `generate_with_phrase` instead. + #[cfg(feature = "std")] + fn generate() -> (Self, Self::Seed) { + let mut seed = Self::Seed::default(); + OsRng.fill_bytes(seed.as_mut()); + (Self::from_seed(&seed), seed) + } + + /// Generate new secure (random) key pair and provide the recovery phrase. + /// + /// You can recover the same key later with `from_phrase`. + /// + /// This is generally slower than `generate()`, so prefer that unless you need to persist + /// the key from the current session. + #[cfg(feature = "std")] + fn generate_with_phrase(password: Option<&str>) -> (Self, String, Self::Seed); + + /// Returns the KeyPair from the English BIP39 seed `phrase`, or `None` if it's invalid. + #[cfg(feature = "std")] + fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Self, Self::Seed), SecretStringError>; + + /// Derive a child key from a series of given junctions. + fn derive>(&self, + path: Iter, + seed: Option, + ) -> Result<(Self, Option), Self::DeriveError>; + + /// Generate new key pair from the provided `seed`. + /// + /// @WARNING: THIS WILL ONLY BE SECURE IF THE `seed` IS SECURE. If it can be guessed + /// by an attacker then they can also derive your key. + fn from_seed(seed: &Self::Seed) -> Self; + + /// Make a new key pair from secret seed material. The slice must be the correct size or + /// it will return `None`. + /// + /// @WARNING: THIS WILL ONLY BE SECURE IF THE `seed` IS SECURE. If it can be guessed + /// by an attacker then they can also derive your key. + fn from_seed_slice(seed: &[u8]) -> Result; + + /// Sign a message. + fn sign(&self, message: &[u8]) -> Self::Signature; + + /// Verify a signature on a message. Returns true if the signature is good. + fn verify>(sig: &Self::Signature, message: M, pubkey: &Self::Public) -> bool; + + /// Verify a signature on a message. Returns true if the signature is good. + fn verify_weak, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool; + + /// Get the public key. + fn public(&self) -> Self::Public; + + /// Interprets the string `s` in order to generate a key Pair. Returns both the pair and an optional seed, in the + /// case that the pair can be expressed as a direct derivation from a seed (some cases, such as Sr25519 derivations + /// with path components, cannot). + /// + /// This takes a helper function to do the key generation from a phrase, password and + /// junction iterator. + /// + /// - If `s` is a possibly `0x` prefixed 64-digit hex string, then it will be interpreted + /// directly as a `MiniSecretKey` (aka "seed" in `subkey`). + /// - If `s` is a valid BIP-39 key phrase of 12, 15, 18, 21 or 24 words, then the key will + /// be derived from it. In this case: + /// - the phrase may be followed by one or more items delimited by `/` characters. + /// - the path may be followed by `///`, in which case everything after the `///` is treated + /// as a password. + /// - If `s` begins with a `/` character it is prefixed with the Substrate public `DEV_PHRASE` and + /// interpreted as above. + /// + /// In this case they are interpreted as HDKD junctions; purely numeric items are interpreted as + /// integers, non-numeric items as strings. Junctions prefixed with `/` are interpreted as soft + /// junctions, and with `//` as hard junctions. + /// + /// There is no correspondence mapping between SURI strings and the keys they represent. + /// Two different non-identical strings can actually lead to the same secret being derived. + /// Notably, integer junction indices may be legally prefixed with arbitrary number of zeros. + /// Similarly an empty password (ending the SURI with `///`) is perfectly valid and will generally + /// be equivalent to no password at all. + /// + /// `None` is returned if no matches are found. + #[cfg(feature = "std")] + fn from_string_with_seed(s: &str, password_override: Option<&str>) + -> Result<(Self, Option), SecretStringError> + { + let re = Regex::new(r"^(?P[\d\w ]+)?(?P(//?[^/]+)*)(///(?P.*))?$") + .expect("constructed from known-good static value; qed"); + let cap = re.captures(s).ok_or(SecretStringError::InvalidFormat)?; + + let re_junction = Regex::new(r"/(/?[^/]+)") + .expect("constructed from known-good static value; qed"); + let path = re_junction.captures_iter(&cap["path"]) + .map(|f| DeriveJunction::from(&f[1])); + + let phrase = cap.name("phrase").map(|r| r.as_str()).unwrap_or(DEV_PHRASE); + let password = password_override.or_else(|| cap.name("password").map(|m| m.as_str())); + + let (root, seed) = if phrase.starts_with("0x") { + hex::decode(&phrase[2..]).ok() + .and_then(|seed_vec| { + let mut seed = Self::Seed::default(); + if seed.as_ref().len() == seed_vec.len() { + seed.as_mut().copy_from_slice(&seed_vec); + Some((Self::from_seed(&seed), seed)) + } else { + None + } + }) + .ok_or(SecretStringError::InvalidSeed)? + } else { + Self::from_phrase(phrase, password) + .map_err(|_| SecretStringError::InvalidPhrase)? + }; + root.derive(path, Some(seed)).map_err(|_| SecretStringError::InvalidPath) + } + + /// Interprets the string `s` in order to generate a key pair. + /// + /// See [`from_string_with_seed`](Pair::from_string_with_seed) for more extensive documentation. + #[cfg(feature = "std")] + fn from_string(s: &str, password_override: Option<&str>) -> Result { + Self::from_string_with_seed(s, password_override).map(|x| x.0) + } + + /// Return a vec filled with raw data. + fn to_raw_vec(&self) -> Vec; +} + +/// One type is wrapped by another. +pub trait IsWrappedBy: From + Into { + /// Get a reference to the inner from the outer. + fn from_ref(outer: &Outer) -> &Self; + /// Get a mutable reference to the inner from the outer. + fn from_mut(outer: &mut Outer) -> &mut Self; +} + +/// Opposite of `IsWrappedBy` - denotes a type which is a simple wrapper around another type. +pub trait Wraps: Sized { + /// The inner type it is wrapping. + type Inner: IsWrappedBy; +} + +impl IsWrappedBy for T where + Outer: AsRef + AsMut + From, + T: From, +{ + /// Get a reference to the inner from the outer. + fn from_ref(outer: &Outer) -> &Self { outer.as_ref() } + + /// Get a mutable reference to the inner from the outer. + fn from_mut(outer: &mut Outer) -> &mut Self { outer.as_mut() } +} + +impl UncheckedFrom for Outer where + Outer: Wraps, + Inner: IsWrappedBy + UncheckedFrom, +{ + fn unchecked_from(t: T) -> Self { + let inner: Inner = t.unchecked_into(); + inner.into() + } +} + +/// Type which has a particular kind of crypto associated with it. +pub trait CryptoType { + /// The pair key type of this crypto. + #[cfg(feature = "full_crypto")] + type Pair: Pair; +} + +/// An identifier for a type of cryptographic key. +/// +/// To avoid clashes with other modules when distributing your module publicly, register your +/// `KeyTypeId` on the list here by making a PR. +/// +/// Values whose first character is `_` are reserved for private use and won't conflict with any +/// public modules. +#[derive( + Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode, PassByInner, + crate::RuntimeDebug +)] +pub struct KeyTypeId(pub [u8; 4]); + +impl From for KeyTypeId { + fn from(x: u32) -> Self { + Self(x.to_le_bytes()) + } +} + +impl From for u32 { + fn from(x: KeyTypeId) -> Self { + u32::from_le_bytes(x.0) + } +} + +impl<'a> TryFrom<&'a str> for KeyTypeId { + type Error = (); + fn try_from(x: &'a str) -> Result { + let b = x.as_bytes(); + if b.len() != 4 { + return Err(()); + } + let mut res = KeyTypeId::default(); + res.0.copy_from_slice(&b[0..4]); + Ok(res) + } +} + +/// An identifier for a specific cryptographic algorithm used by a key pair +#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode)] +pub struct CryptoTypeId(pub [u8; 4]); + +/// A type alias of CryptoTypeId & a public key +#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode)] +pub struct CryptoTypePublicPair(pub CryptoTypeId, pub Vec); + +#[cfg(feature = "std")] +impl sp_std::fmt::Display for CryptoTypePublicPair { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + let id = match str::from_utf8(&(self.0).0[..]) { + Ok(id) => id.to_string(), + Err(_) => { + format!("{:#?}", self.0) + } + }; + write!(f, "{}-{}", id, HexDisplay::from(&self.1)) + } +} + +/// Known key types; this also functions as a global registry of key types for projects wishing to +/// avoid collisions with each other. +/// +/// It's not universal in the sense that *all* key types need to be mentioned here, it's just a +/// handy place to put common key types. +pub mod key_types { + use super::KeyTypeId; + + /// Key type for Babe module, built-in. Identified as `babe`. + pub const BABE: KeyTypeId = KeyTypeId(*b"babe"); + /// Key type for Grandpa module, built-in. Identified as `gran`. + pub const GRANDPA: KeyTypeId = KeyTypeId(*b"gran"); + /// Key type for controlling an account in a Substrate runtime, built-in. Identified as `acco`. + pub const ACCOUNT: KeyTypeId = KeyTypeId(*b"acco"); + /// Key type for Aura module, built-in. Identified as `aura`. + pub const AURA: KeyTypeId = KeyTypeId(*b"aura"); + /// Key type for ImOnline module, built-in. Identified as `imon`. + pub const IM_ONLINE: KeyTypeId = KeyTypeId(*b"imon"); + /// Key type for AuthorityDiscovery module, built-in. Identified as `audi`. + pub const AUTHORITY_DISCOVERY: KeyTypeId = KeyTypeId(*b"audi"); + /// Key type for staking, built-in. Identified as `stak`. + pub const STAKING: KeyTypeId = KeyTypeId(*b"stak"); + /// Key type for equivocation reporting, built-in. Identified as `fish`. + pub const REPORTING: KeyTypeId = KeyTypeId(*b"fish"); + /// A key type ID useful for tests. + pub const DUMMY: KeyTypeId = KeyTypeId(*b"dumy"); +} + +#[cfg(test)] +mod tests { + use crate::DeriveJunction; + use hex_literal::hex; + use super::*; + + #[derive(Clone, Eq, PartialEq, Debug)] + enum TestPair { + Generated, + GeneratedWithPhrase, + GeneratedFromPhrase{phrase: String, password: Option}, + Standard{phrase: String, password: Option, path: Vec}, + Seed(Vec), + } + impl Default for TestPair { + fn default() -> Self { + TestPair::Generated + } + } + impl CryptoType for TestPair { + type Pair = Self; + } + + #[derive(Clone, PartialEq, Eq, Hash, Default)] + struct TestPublic; + impl AsRef<[u8]> for TestPublic { + fn as_ref(&self) -> &[u8] { + &[] + } + } + impl AsMut<[u8]> for TestPublic { + fn as_mut(&mut self) -> &mut [u8] { + &mut [] + } + } + impl CryptoType for TestPublic { + type Pair = TestPair; + } + impl Derive for TestPublic {} + impl Public for TestPublic { + fn from_slice(_bytes: &[u8]) -> Self { + Self + } + fn as_slice(&self) -> &[u8] { + &[] + } + fn to_raw_vec(&self) -> Vec { + vec![] + } + fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { + CryptoTypePublicPair( + CryptoTypeId(*b"dumm"), self.to_raw_vec(), + ) + } + } + impl Pair for TestPair { + type Public = TestPublic; + type Seed = [u8; 8]; + type Signature = [u8; 0]; + type DeriveError = (); + + fn generate() -> (Self, ::Seed) { (TestPair::Generated, [0u8; 8]) } + fn generate_with_phrase(_password: Option<&str>) -> (Self, String, ::Seed) { + (TestPair::GeneratedWithPhrase, "".into(), [0u8; 8]) + } + fn from_phrase(phrase: &str, password: Option<&str>) + -> Result<(Self, ::Seed), SecretStringError> + { + Ok((TestPair::GeneratedFromPhrase { + phrase: phrase.to_owned(), + password: password.map(Into::into) + }, [0u8; 8])) + } + fn derive>(&self, path_iter: Iter, _: Option<[u8; 8]>) + -> Result<(Self, Option<[u8; 8]>), Self::DeriveError> + { + Ok((match self.clone() { + TestPair::Standard {phrase, password, path} => + TestPair::Standard { phrase, password, path: path.into_iter().chain(path_iter).collect() }, + TestPair::GeneratedFromPhrase {phrase, password} => + TestPair::Standard { phrase, password, path: path_iter.collect() }, + x => if path_iter.count() == 0 { x } else { return Err(()) }, + }, None)) + } + fn from_seed(_seed: &::Seed) -> Self { TestPair::Seed(_seed.as_ref().to_owned()) } + fn sign(&self, _message: &[u8]) -> Self::Signature { [] } + fn verify>(_: &Self::Signature, _: M, _: &Self::Public) -> bool { true } + fn verify_weak, M: AsRef<[u8]>>( + _sig: &[u8], + _message: M, + _pubkey: P + ) -> bool { true } + fn public(&self) -> Self::Public { TestPublic } + fn from_seed_slice(seed: &[u8]) + -> Result + { + Ok(TestPair::Seed(seed.to_owned())) + } + fn to_raw_vec(&self) -> Vec { + vec![] + } + } + + #[test] + fn interpret_std_seed_should_work() { + assert_eq!( + TestPair::from_string("0x0123456789abcdef", None), + Ok(TestPair::Seed(hex!["0123456789abcdef"][..].to_owned())) + ); + } + + #[test] + fn password_override_should_work() { + assert_eq!( + TestPair::from_string("hello world///password", None), + TestPair::from_string("hello world", Some("password")), + ); + assert_eq!( + TestPair::from_string("hello world///password", None), + TestPair::from_string("hello world///other password", Some("password")), + ); + } + + #[test] + fn interpret_std_secret_string_should_work() { + assert_eq!( + TestPair::from_string("hello world", None), + Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![]}) + ); + assert_eq!( + TestPair::from_string("hello world/1", None), + Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![DeriveJunction::soft(1)]}) + ); + assert_eq!( + TestPair::from_string("hello world/DOT", None), + Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![DeriveJunction::soft("DOT")]}) + ); + assert_eq!( + TestPair::from_string("hello world//1", None), + Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![DeriveJunction::hard(1)]}) + ); + assert_eq!( + TestPair::from_string("hello world//DOT", None), + Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![DeriveJunction::hard("DOT")]}) + ); + assert_eq!( + TestPair::from_string("hello world//1/DOT", None), + Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![DeriveJunction::hard(1), DeriveJunction::soft("DOT")]}) + ); + assert_eq!( + TestPair::from_string("hello world//DOT/1", None), + Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![DeriveJunction::hard("DOT"), DeriveJunction::soft(1)]}) + ); + assert_eq!( + TestPair::from_string("hello world///password", None), + Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: Some("password".to_owned()), path: vec![]}) + ); + assert_eq!( + TestPair::from_string("hello world//1/DOT///password", None), + Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: Some("password".to_owned()), path: vec![DeriveJunction::hard(1), DeriveJunction::soft("DOT")]}) + ); + assert_eq!( + TestPair::from_string("hello world/1//DOT///password", None), + Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: Some("password".to_owned()), path: vec![DeriveJunction::soft(1), DeriveJunction::hard("DOT")]}) + ); + } + + #[test] + fn accountid_32_from_str_works() { + use std::str::FromStr; + assert!(AccountId32::from_str("5G9VdMwXvzza9pS8qE8ZHJk3CheHW9uucBn9ngW4C1gmmzpv").is_ok()); + assert!(AccountId32::from_str("5c55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").is_ok()); + assert!(AccountId32::from_str("0x5c55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").is_ok()); + + assert_eq!( + AccountId32::from_str("99G9VdMwXvzza9pS8qE8ZHJk3CheHW9uucBn9ngW4C1gmmzpv").unwrap_err(), + "invalid ss58 address.", + ); + assert_eq!( + AccountId32::from_str("gc55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").unwrap_err(), + "invalid hex address.", + ); + assert_eq!( + AccountId32::from_str("0xgc55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").unwrap_err(), + "invalid hex address.", + ); + + // valid hex but invalid length will be treated as ss58. + assert_eq!( + AccountId32::from_str("55c55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").unwrap_err(), + "invalid ss58 address.", + ); + } +} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/ecdsa.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/ecdsa.rs new file mode 100644 index 00000000..a836eb0e --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/ecdsa.rs @@ -0,0 +1,717 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// tag::description[] +//! Simple ECDSA API. +// end::description[] + +#[cfg(feature = "full_crypto")] +use sp_std::vec::Vec; + +use sp_std::cmp::Ordering; +use codec::{Encode, Decode}; + +#[cfg(feature = "full_crypto")] +use core::convert::{TryFrom, TryInto}; +#[cfg(feature = "std")] +use substrate_bip39::seed_from_entropy; +#[cfg(feature = "std")] +use bip39::{Mnemonic, Language, MnemonicType}; +#[cfg(feature = "full_crypto")] +use crate::{hashing::blake2_256, crypto::{Pair as TraitPair, DeriveJunction, SecretStringError}}; +#[cfg(feature = "std")] +use crate::crypto::Ss58Codec; +#[cfg(feature = "std")] +use serde::{de, Serializer, Serialize, Deserializer, Deserialize}; +use crate::crypto::{Public as TraitPublic, CryptoTypePublicPair, UncheckedFrom, CryptoType, Derive, CryptoTypeId}; +use sp_runtime_interface::pass_by::PassByInner; +#[cfg(feature = "full_crypto")] +use secp256k1::{PublicKey, SecretKey}; + +/// An identifier used to match public keys against ecdsa keys +pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"ecds"); + +/// A secret seed (which is bytewise essentially equivalent to a SecretKey). +/// +/// We need it as a different type because `Seed` is expected to be AsRef<[u8]>. +#[cfg(feature = "full_crypto")] +type Seed = [u8; 32]; + +/// The ECDSA compressed public key. +#[derive(Clone, Encode, Decode, PassByInner)] +pub struct Public(pub [u8; 33]); + +impl PartialOrd for Public { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Public { + fn cmp(&self, other: &Self) -> Ordering { + self.as_ref().cmp(&other.as_ref()) + } +} + +impl PartialEq for Public { + fn eq(&self, other: &Self) -> bool { + self.as_ref() == other.as_ref() + } +} + +impl Eq for Public {} + +/// An error type for SS58 decoding. +#[cfg(feature = "std")] +#[derive(Clone, Copy, Eq, PartialEq, Debug)] +pub enum PublicError { + /// Bad alphabet. + BadBase58, + /// Bad length. + BadLength, + /// Unknown version. + UnknownVersion, + /// Invalid checksum. + InvalidChecksum, +} + +impl Public { + /// A new instance from the given 33-byte `data`. + /// + /// NOTE: No checking goes on to ensure this is a real public key. Only use it if + /// you are certain that the array actually is a pubkey. GIGO! + pub fn from_raw(data: [u8; 33]) -> Self { + Self(data) + } + + /// Create a new instance from the given full public key. + /// + /// This will convert the full public key into the compressed format. + #[cfg(feature = "std")] + pub fn from_full(full: &[u8]) -> Result { + secp256k1::PublicKey::parse_slice(full, None) + .map(|k| k.serialize_compressed()) + .map(Self) + .map_err(|_| ()) + } +} + +impl TraitPublic for Public { + /// A new instance from the given slice that should be 33 bytes long. + /// + /// NOTE: No checking goes on to ensure this is a real public key. Only use it if + /// you are certain that the array actually is a pubkey. GIGO! + fn from_slice(data: &[u8]) -> Self { + let mut r = [0u8; 33]; + r.copy_from_slice(data); + Self(r) + } + + fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { + CryptoTypePublicPair(CRYPTO_ID, self.to_raw_vec()) + } +} + +impl From for CryptoTypePublicPair { + fn from(key: Public) -> Self { + (&key).into() + } +} + +impl From<&Public> for CryptoTypePublicPair { + fn from(key: &Public) -> Self { + CryptoTypePublicPair(CRYPTO_ID, key.to_raw_vec()) + } +} + +impl Derive for Public {} + +impl Default for Public { + fn default() -> Self { + Public([0u8; 33]) + } +} + +impl AsRef<[u8]> for Public { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl AsMut<[u8]> for Public { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0[..] + } +} + +impl sp_std::convert::TryFrom<&[u8]> for Public { + type Error = (); + + fn try_from(data: &[u8]) -> Result { + if data.len() == 33 { + Ok(Self::from_slice(data)) + } else { + + Err(()) + } + } +} + +#[cfg(feature = "full_crypto")] +impl From for Public { + fn from(x: Pair) -> Self { + x.public() + } +} + +impl UncheckedFrom<[u8; 33]> for Public { + fn unchecked_from(x: [u8; 33]) -> Self { + Public(x) + } +} + +#[cfg(feature = "std")] +impl std::fmt::Display for Public { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_ss58check()) + } +} + +impl sp_std::fmt::Debug for Public { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + let s = self.to_ss58check(); + write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.as_ref()), &s[0..8]) + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } +} + +#[cfg(feature = "std")] +impl Serialize for Public { + fn serialize(&self, serializer: S) -> Result where S: Serializer { + serializer.serialize_str(&self.to_ss58check()) + } +} + +#[cfg(feature = "std")] +impl<'de> Deserialize<'de> for Public { + fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { + Public::from_ss58check(&String::deserialize(deserializer)?) + .map_err(|e| de::Error::custom(format!("{:?}", e))) + } +} + +#[cfg(feature = "full_crypto")] +impl sp_std::hash::Hash for Public { + fn hash(&self, state: &mut H) { + self.as_ref().hash(state); + } +} + +/// A signature (a 512-bit value, plus 8 bits for recovery ID). +#[derive(Encode, Decode, PassByInner)] +pub struct Signature(pub [u8; 65]); + +impl sp_std::convert::TryFrom<&[u8]> for Signature { + type Error = (); + + fn try_from(data: &[u8]) -> Result { + if data.len() == 65 { + let mut inner = [0u8; 65]; + inner.copy_from_slice(data); + Ok(Signature(inner)) + } else { + Err(()) + } + } +} + +#[cfg(feature = "std")] +impl Serialize for Signature { + fn serialize(&self, serializer: S) -> Result where S: Serializer { + serializer.serialize_str(&hex::encode(self)) + } +} + +#[cfg(feature = "std")] +impl<'de> Deserialize<'de> for Signature { + fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { + let signature_hex = hex::decode(&String::deserialize(deserializer)?) + .map_err(|e| de::Error::custom(format!("{:?}", e)))?; + Ok(Signature::try_from(signature_hex.as_ref()) + .map_err(|e| de::Error::custom(format!("{:?}", e)))?) + } +} + +impl Clone for Signature { + fn clone(&self) -> Self { + let mut r = [0u8; 65]; + r.copy_from_slice(&self.0[..]); + Signature(r) + } +} + +impl Default for Signature { + fn default() -> Self { + Signature([0u8; 65]) + } +} + +impl PartialEq for Signature { + fn eq(&self, b: &Self) -> bool { + self.0[..] == b.0[..] + } +} + +impl Eq for Signature {} + +impl From for [u8; 65] { + fn from(v: Signature) -> [u8; 65] { + v.0 + } +} + +impl AsRef<[u8; 65]> for Signature { + fn as_ref(&self) -> &[u8; 65] { + &self.0 + } +} + +impl AsRef<[u8]> for Signature { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl AsMut<[u8]> for Signature { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0[..] + } +} + +impl sp_std::fmt::Debug for Signature { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0)) + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } +} + +#[cfg(feature = "full_crypto")] +impl sp_std::hash::Hash for Signature { + fn hash(&self, state: &mut H) { + sp_std::hash::Hash::hash(&self.0[..], state); + } +} + +impl Signature { + /// A new instance from the given 65-byte `data`. + /// + /// NOTE: No checking goes on to ensure this is a real signature. Only use it if + /// you are certain that the array actually is a signature. GIGO! + pub fn from_raw(data: [u8; 65]) -> Signature { + Signature(data) + } + + /// A new instance from the given slice that should be 65 bytes long. + /// + /// NOTE: No checking goes on to ensure this is a real signature. Only use it if + /// you are certain that the array actually is a signature. GIGO! + pub fn from_slice(data: &[u8]) -> Self { + let mut r = [0u8; 65]; + r.copy_from_slice(data); + Signature(r) + } + + /// Recover the public key from this signature and a message. + #[cfg(feature = "full_crypto")] + pub fn recover>(&self, message: M) -> Option { + let message = secp256k1::Message::parse(&blake2_256(message.as_ref())); + let sig: (_, _) = self.try_into().ok()?; + secp256k1::recover(&message, &sig.0, &sig.1) + .ok() + .map(|recovered| Public(recovered.serialize_compressed())) + } +} + +#[cfg(feature = "full_crypto")] +impl From<(secp256k1::Signature, secp256k1::RecoveryId)> for Signature { + fn from(x: (secp256k1::Signature, secp256k1::RecoveryId)) -> Signature { + let mut r = Self::default(); + r.0[0..64].copy_from_slice(&x.0.serialize()[..]); + r.0[64] = x.1.serialize(); + r + } +} + +#[cfg(feature = "full_crypto")] +impl<'a> TryFrom<&'a Signature> for (secp256k1::Signature, secp256k1::RecoveryId) { + type Error = (); + fn try_from(x: &'a Signature) -> Result<(secp256k1::Signature, secp256k1::RecoveryId), Self::Error> { + Ok(( + secp256k1::Signature::parse_slice(&x.0[0..64]).expect("hardcoded to 64 bytes; qed"), + secp256k1::RecoveryId::parse(x.0[64]).map_err(|_| ())?, + )) + } +} + +/// Derive a single hard junction. +#[cfg(feature = "full_crypto")] +fn derive_hard_junction(secret_seed: &Seed, cc: &[u8; 32]) -> Seed { + ("Secp256k1HDKD", secret_seed, cc).using_encoded(|data| { + let mut res = [0u8; 32]; + res.copy_from_slice(blake2_rfc::blake2b::blake2b(32, &[], data).as_bytes()); + res + }) +} + +/// An error when deriving a key. +#[cfg(feature = "full_crypto")] +pub enum DeriveError { + /// A soft key was found in the path (and is unsupported). + SoftKeyInPath, +} + +/// A key pair. +#[cfg(feature = "full_crypto")] +#[derive(Clone)] +pub struct Pair { + public: PublicKey, + secret: SecretKey, +} + +#[cfg(feature = "full_crypto")] +impl TraitPair for Pair { + type Public = Public; + type Seed = Seed; + type Signature = Signature; + type DeriveError = DeriveError; + + /// Generate new secure (random) key pair and provide the recovery phrase. + /// + /// You can recover the same key later with `from_phrase`. + #[cfg(feature = "std")] + fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) { + let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English); + let phrase = mnemonic.phrase(); + let (pair, seed) = Self::from_phrase(phrase, password) + .expect("All phrases generated by Mnemonic are valid; qed"); + ( + pair, + phrase.to_owned(), + seed, + ) + } + + /// Generate key pair from given recovery phrase and password. + #[cfg(feature = "std")] + fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> { + let big_seed = seed_from_entropy( + Mnemonic::from_phrase(phrase, Language::English) + .map_err(|_| SecretStringError::InvalidPhrase)?.entropy(), + password.unwrap_or(""), + ).map_err(|_| SecretStringError::InvalidSeed)?; + let mut seed = Seed::default(); + seed.copy_from_slice(&big_seed[0..32]); + Self::from_seed_slice(&big_seed[0..32]).map(|x| (x, seed)) + } + + /// Make a new key pair from secret seed material. + /// + /// You should never need to use this; generate(), generate_with_phrase + fn from_seed(seed: &Seed) -> Pair { + Self::from_seed_slice(&seed[..]).expect("seed has valid length; qed") + } + + /// Make a new key pair from secret seed material. The slice must be 32 bytes long or it + /// will return `None`. + /// + /// You should never need to use this; generate(), generate_with_phrase + fn from_seed_slice(seed_slice: &[u8]) -> Result { + let secret = SecretKey::parse_slice(seed_slice) + .map_err(|_| SecretStringError::InvalidSeedLength)?; + let public = PublicKey::from_secret_key(&secret); + Ok(Pair{ secret, public }) + } + + /// Derive a child key from a series of given junctions. + fn derive>(&self, + path: Iter, + _seed: Option + ) -> Result<(Pair, Option), DeriveError> { + let mut acc = self.secret.serialize(); + for j in path { + match j { + DeriveJunction::Soft(_cc) => return Err(DeriveError::SoftKeyInPath), + DeriveJunction::Hard(cc) => acc = derive_hard_junction(&acc, &cc), + } + } + Ok((Self::from_seed(&acc), Some(acc))) + } + + /// Get the public key. + fn public(&self) -> Public { + Public(self.public.serialize_compressed()) + } + + /// Sign a message. + fn sign(&self, message: &[u8]) -> Signature { + let message = secp256k1::Message::parse(&blake2_256(message)); + secp256k1::sign(&message, &self.secret).into() + } + + /// Verify a signature on a message. Returns true if the signature is good. + fn verify>(sig: &Self::Signature, message: M, pubkey: &Self::Public) -> bool { + let message = secp256k1::Message::parse(&blake2_256(message.as_ref())); + let sig: (_, _) = match sig.try_into() { Ok(x) => x, _ => return false }; + match secp256k1::recover(&message, &sig.0, &sig.1) { + Ok(actual) => &pubkey.0[..] == &actual.serialize_compressed()[..], + _ => false, + } + } + + /// Verify a signature on a message. Returns true if the signature is good. + /// + /// This doesn't use the type system to ensure that `sig` and `pubkey` are the correct + /// size. Use it only if you're coming from byte buffers and need the speed. + fn verify_weak, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool { + let message = secp256k1::Message::parse(&blake2_256(message.as_ref())); + if sig.len() != 65 { return false } + let ri = match secp256k1::RecoveryId::parse(sig[64]) { Ok(x) => x, _ => return false }; + let sig = match secp256k1::Signature::parse_slice(&sig[0..64]) { Ok(x) => x, _ => return false }; + match secp256k1::recover(&message, &sig, &ri) { + Ok(actual) => pubkey.as_ref() == &actual.serialize()[1..], + _ => false, + } + } + + /// Return a vec filled with raw data. + fn to_raw_vec(&self) -> Vec { + self.seed().to_vec() + } +} + +#[cfg(feature = "full_crypto")] +impl Pair { + /// Get the seed for this key. + pub fn seed(&self) -> Seed { + self.secret.serialize() + } + + /// Exactly as `from_string` except that if no matches are found then, the the first 32 + /// characters are taken (padded with spaces as necessary) and used as the MiniSecretKey. + #[cfg(feature = "std")] + pub fn from_legacy_string(s: &str, password_override: Option<&str>) -> Pair { + Self::from_string(s, password_override).unwrap_or_else(|_| { + let mut padded_seed: Seed = [' ' as u8; 32]; + let len = s.len().min(32); + padded_seed[..len].copy_from_slice(&s.as_bytes()[..len]); + Self::from_seed(&padded_seed) + }) + } +} + +impl CryptoType for Public { + #[cfg(feature="full_crypto")] + type Pair = Pair; +} + +impl CryptoType for Signature { + #[cfg(feature="full_crypto")] + type Pair = Pair; +} + +#[cfg(feature="full_crypto")] +impl CryptoType for Pair { + type Pair = Pair; +} + +#[cfg(test)] +mod test { + use super::*; + use hex_literal::hex; + use crate::crypto::{DEV_PHRASE, set_default_ss58_version}; + use serde_json; + + #[test] + fn default_phrase_should_be_used() { + assert_eq!( + Pair::from_string("//Alice///password", None).unwrap().public(), + Pair::from_string(&format!("{}//Alice", DEV_PHRASE), Some("password")).unwrap().public(), + ); + } + + #[test] + fn seed_and_derive_should_work() { + let seed = hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"); + let pair = Pair::from_seed(&seed); + assert_eq!(pair.seed(), seed); + let path = vec![DeriveJunction::Hard([0u8; 32])]; + let derived = pair.derive(path.into_iter(), None).ok().unwrap(); + assert_eq!( + derived.0.seed(), + hex!("b8eefc4937200a8382d00050e050ced2d4ab72cc2ef1b061477afb51564fdd61") + ); + } + + #[test] + fn test_vector_should_work() { + let pair = Pair::from_seed( + &hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60") + ); + let public = pair.public(); + assert_eq!( + public, + Public::from_full( + &hex!("8db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd913ebbe148dd17c56551a52952371071a6c604b3f3abe8f2c8fa742158ea6dd7d4")[..], + ).unwrap(), + ); + let message = b""; + let signature = hex!("3dde91174bd9359027be59a428b8146513df80a2a3c7eda2194f64de04a69ab97b753169e94db6ffd50921a2668a48b94ca11e3d32c1ff19cfe88890aa7e8f3c00"); + let signature = Signature::from_raw(signature); + assert!(&pair.sign(&message[..]) == &signature); + assert!(Pair::verify(&signature, &message[..], &public)); + } + + #[test] + fn test_vector_by_string_should_work() { + let pair = Pair::from_string( + "0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60", + None + ).unwrap(); + let public = pair.public(); + assert_eq!( + public, + Public::from_full( + &hex!("8db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd913ebbe148dd17c56551a52952371071a6c604b3f3abe8f2c8fa742158ea6dd7d4")[..], + ).unwrap(), + ); + let message = b""; + let signature = hex!("3dde91174bd9359027be59a428b8146513df80a2a3c7eda2194f64de04a69ab97b753169e94db6ffd50921a2668a48b94ca11e3d32c1ff19cfe88890aa7e8f3c00"); + let signature = Signature::from_raw(signature); + assert!(&pair.sign(&message[..]) == &signature); + assert!(Pair::verify(&signature, &message[..], &public)); + } + + #[test] + fn generated_pair_should_work() { + let (pair, _) = Pair::generate(); + let public = pair.public(); + let message = b"Something important"; + let signature = pair.sign(&message[..]); + assert!(Pair::verify(&signature, &message[..], &public)); + assert!(!Pair::verify(&signature, b"Something else", &public)); + } + + #[test] + fn seeded_pair_should_work() { + let pair = Pair::from_seed(b"12345678901234567890123456789012"); + let public = pair.public(); + assert_eq!( + public, + Public::from_full( + &hex!("5676109c54b9a16d271abeb4954316a40a32bcce023ac14c8e26e958aa68fba995840f3de562156558efbfdac3f16af0065e5f66795f4dd8262a228ef8c6d813")[..], + ).unwrap(), + ); + let message = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000200d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000"); + let signature = pair.sign(&message[..]); + println!("Correct signature: {:?}", signature); + assert!(Pair::verify(&signature, &message[..], &public)); + assert!(!Pair::verify(&signature, "Other message", &public)); + } + + #[test] + fn generate_with_phrase_recovery_possible() { + let (pair1, phrase, _) = Pair::generate_with_phrase(None); + let (pair2, _) = Pair::from_phrase(&phrase, None).unwrap(); + + assert_eq!(pair1.public(), pair2.public()); + } + + #[test] + fn generate_with_password_phrase_recovery_possible() { + let (pair1, phrase, _) = Pair::generate_with_phrase(Some("password")); + let (pair2, _) = Pair::from_phrase(&phrase, Some("password")).unwrap(); + + assert_eq!(pair1.public(), pair2.public()); + } + + #[test] + fn password_does_something() { + let (pair1, phrase, _) = Pair::generate_with_phrase(Some("password")); + let (pair2, _) = Pair::from_phrase(&phrase, None).unwrap(); + + assert_ne!(pair1.public(), pair2.public()); + } + + #[test] + fn ss58check_roundtrip_works() { + let pair = Pair::from_seed(b"12345678901234567890123456789012"); + let public = pair.public(); + let s = public.to_ss58check(); + println!("Correct: {}", s); + let cmp = Public::from_ss58check(&s).unwrap(); + assert_eq!(cmp, public); + } + + #[test] + fn ss58check_custom_format_works() { + use crate::crypto::Ss58AddressFormat; + // temp save default format version + let default_format = Ss58AddressFormat::default(); + // set current ss58 version is custom "200" `Ss58AddressFormat::Custom(200)` + set_default_ss58_version(Ss58AddressFormat::Custom(200)); + // custom addr encoded by version 200 + let addr = "2X64kMNEWAW5KLZMSKcGKEc96MyuaRsRUku7vomuYxKgqjVCRj"; + Public::from_ss58check(&addr).unwrap(); + set_default_ss58_version(default_format); + // set current ss58 version to default version + let addr = "KWAfgC2aRG5UVD6CpbPQXCx4YZZUhvWqqAJE6qcYc9Rtr6g5C"; + Public::from_ss58check(&addr).unwrap(); + } + + #[test] + fn signature_serialization_works() { + let pair = Pair::from_seed(b"12345678901234567890123456789012"); + let message = b"Something important"; + let signature = pair.sign(&message[..]); + let serialized_signature = serde_json::to_string(&signature).unwrap(); + // Signature is 65 bytes, so 130 chars + 2 quote chars + assert_eq!(serialized_signature.len(), 132); + let signature = serde_json::from_str(&serialized_signature).unwrap(); + assert!(Pair::verify(&signature, &message[..], &pair.public())); + } + + #[test] + fn signature_serialization_doesnt_panic() { + fn deserialize_signature(text: &str) -> Result { + Ok(serde_json::from_str(text)?) + } + assert!(deserialize_signature("Not valid json.").is_err()); + assert!(deserialize_signature("\"Not an actual signature.\"").is_err()); + // Poorly-sized + assert!(deserialize_signature("\"abc123\"").is_err()); + } +} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/ed25519.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/ed25519.rs new file mode 100644 index 00000000..fcc84c5c --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/ed25519.rs @@ -0,0 +1,711 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// tag::description[] +//! Simple Ed25519 API. +// end::description[] + +#[cfg(feature = "full_crypto")] +use sp_std::vec::Vec; + +use crate::{hash::H256, hash::H512}; +use codec::{Encode, Decode}; + +#[cfg(feature = "full_crypto")] +use blake2_rfc; +#[cfg(feature = "full_crypto")] +use core::convert::TryFrom; +#[cfg(feature = "full_crypto")] +use ed25519_dalek::{Signer as _, Verifier as _}; +#[cfg(feature = "std")] +use substrate_bip39::seed_from_entropy; +#[cfg(feature = "std")] +use bip39::{Mnemonic, Language, MnemonicType}; +#[cfg(feature = "full_crypto")] +use crate::crypto::{Pair as TraitPair, DeriveJunction, SecretStringError}; +#[cfg(feature = "std")] +use crate::crypto::Ss58Codec; +#[cfg(feature = "std")] +use serde::{de, Serializer, Serialize, Deserializer, Deserialize}; +use crate::crypto::{Public as TraitPublic, CryptoTypePublicPair, UncheckedFrom, CryptoType, Derive, CryptoTypeId}; +use sp_runtime_interface::pass_by::PassByInner; +use sp_std::ops::Deref; + +/// An identifier used to match public keys against ed25519 keys +pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"ed25"); + +/// A secret seed. It's not called a "secret key" because ring doesn't expose the secret keys +/// of the key pair (yeah, dumb); as such we're forced to remember the seed manually if we +/// will need it later (such as for HDKD). +#[cfg(feature = "full_crypto")] +type Seed = [u8; 32]; + +/// A public key. +#[cfg_attr(feature = "full_crypto", derive(Hash))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Encode, Decode, Default, PassByInner)] +pub struct Public(pub [u8; 32]); + +/// A key pair. +#[cfg(feature = "full_crypto")] +pub struct Pair(ed25519_dalek::Keypair); + +#[cfg(feature = "full_crypto")] +impl Clone for Pair { + fn clone(&self) -> Self { + Pair(ed25519_dalek::Keypair { + public: self.0.public.clone(), + secret: ed25519_dalek::SecretKey::from_bytes(self.0.secret.as_bytes()) + .expect("key is always the correct size; qed") + }) + } +} + +impl AsRef<[u8; 32]> for Public { + fn as_ref(&self) -> &[u8; 32] { + &self.0 + } +} + +impl AsRef<[u8]> for Public { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl AsMut<[u8]> for Public { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0[..] + } +} + +impl Deref for Public { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl sp_std::convert::TryFrom<&[u8]> for Public { + type Error = (); + + fn try_from(data: &[u8]) -> Result { + if data.len() == 32 { + let mut inner = [0u8; 32]; + inner.copy_from_slice(data); + Ok(Public(inner)) + } else { + Err(()) + } + } +} + +impl From for [u8; 32] { + fn from(x: Public) -> Self { + x.0 + } +} + +#[cfg(feature = "full_crypto")] +impl From for Public { + fn from(x: Pair) -> Self { + x.public() + } +} + +impl From for H256 { + fn from(x: Public) -> Self { + x.0.into() + } +} + +#[cfg(feature = "std")] +impl std::str::FromStr for Public { + type Err = crate::crypto::PublicError; + + fn from_str(s: &str) -> Result { + Self::from_ss58check(s) + } +} + +impl UncheckedFrom<[u8; 32]> for Public { + fn unchecked_from(x: [u8; 32]) -> Self { + Public::from_raw(x) + } +} + +impl UncheckedFrom for Public { + fn unchecked_from(x: H256) -> Self { + Public::from_h256(x) + } +} + +#[cfg(feature = "std")] +impl std::fmt::Display for Public { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_ss58check()) + } +} + +impl sp_std::fmt::Debug for Public { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + let s = self.to_ss58check(); + write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } +} + +#[cfg(feature = "std")] +impl Serialize for Public { + fn serialize(&self, serializer: S) -> Result where S: Serializer { + serializer.serialize_str(&self.to_ss58check()) + } +} + +#[cfg(feature = "std")] +impl<'de> Deserialize<'de> for Public { + fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { + Public::from_ss58check(&String::deserialize(deserializer)?) + .map_err(|e| de::Error::custom(format!("{:?}", e))) + } +} + +/// A signature (a 512-bit value). +#[derive(Encode, Decode, PassByInner)] +pub struct Signature(pub [u8; 64]); + +impl sp_std::convert::TryFrom<&[u8]> for Signature { + type Error = (); + + fn try_from(data: &[u8]) -> Result { + if data.len() == 64 { + let mut inner = [0u8; 64]; + inner.copy_from_slice(data); + Ok(Signature(inner)) + } else { + Err(()) + } + } +} + +#[cfg(feature = "std")] +impl Serialize for Signature { + fn serialize(&self, serializer: S) -> Result where S: Serializer { + serializer.serialize_str(&hex::encode(self)) + } +} + +#[cfg(feature = "std")] +impl<'de> Deserialize<'de> for Signature { + fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { + let signature_hex = hex::decode(&String::deserialize(deserializer)?) + .map_err(|e| de::Error::custom(format!("{:?}", e)))?; + Ok(Signature::try_from(signature_hex.as_ref()) + .map_err(|e| de::Error::custom(format!("{:?}", e)))?) + } +} + +impl Clone for Signature { + fn clone(&self) -> Self { + let mut r = [0u8; 64]; + r.copy_from_slice(&self.0[..]); + Signature(r) + } +} + +impl Default for Signature { + fn default() -> Self { + Signature([0u8; 64]) + } +} + +impl PartialEq for Signature { + fn eq(&self, b: &Self) -> bool { + self.0[..] == b.0[..] + } +} + +impl Eq for Signature {} + +impl From for H512 { + fn from(v: Signature) -> H512 { + H512::from(v.0) + } +} + +impl From for [u8; 64] { + fn from(v: Signature) -> [u8; 64] { + v.0 + } +} + +impl AsRef<[u8; 64]> for Signature { + fn as_ref(&self) -> &[u8; 64] { + &self.0 + } +} + +impl AsRef<[u8]> for Signature { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl AsMut<[u8]> for Signature { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0[..] + } +} + +impl sp_std::fmt::Debug for Signature { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0)) + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } +} + +#[cfg(feature = "full_crypto")] +impl sp_std::hash::Hash for Signature { + fn hash(&self, state: &mut H) { + sp_std::hash::Hash::hash(&self.0[..], state); + } +} + +impl Signature { + /// A new instance from the given 64-byte `data`. + /// + /// NOTE: No checking goes on to ensure this is a real signature. Only use it if + /// you are certain that the array actually is a signature. GIGO! + pub fn from_raw(data: [u8; 64]) -> Signature { + Signature(data) + } + + /// A new instance from the given slice that should be 64 bytes long. + /// + /// NOTE: No checking goes on to ensure this is a real signature. Only use it if + /// you are certain that the array actually is a signature. GIGO! + pub fn from_slice(data: &[u8]) -> Self { + let mut r = [0u8; 64]; + r.copy_from_slice(data); + Signature(r) + } + + /// A new instance from an H512. + /// + /// NOTE: No checking goes on to ensure this is a real signature. Only use it if + /// you are certain that the array actually is a signature. GIGO! + pub fn from_h512(v: H512) -> Signature { + Signature(v.into()) + } +} + +/// A localized signature also contains sender information. +#[cfg(feature = "std")] +#[derive(PartialEq, Eq, Clone, Debug, Encode, Decode)] +pub struct LocalizedSignature { + /// The signer of the signature. + pub signer: Public, + /// The signature itself. + pub signature: Signature, +} + +/// An error type for SS58 decoding. +#[cfg(feature = "std")] +#[derive(Clone, Copy, Eq, PartialEq, Debug)] +pub enum PublicError { + /// Bad alphabet. + BadBase58, + /// Bad length. + BadLength, + /// Unknown version. + UnknownVersion, + /// Invalid checksum. + InvalidChecksum, +} + +impl Public { + /// A new instance from the given 32-byte `data`. + /// + /// NOTE: No checking goes on to ensure this is a real public key. Only use it if + /// you are certain that the array actually is a pubkey. GIGO! + pub fn from_raw(data: [u8; 32]) -> Self { + Public(data) + } + + /// A new instance from an H256. + /// + /// NOTE: No checking goes on to ensure this is a real public key. Only use it if + /// you are certain that the array actually is a pubkey. GIGO! + pub fn from_h256(x: H256) -> Self { + Public(x.into()) + } + + /// Return a slice filled with raw data. + pub fn as_array_ref(&self) -> &[u8; 32] { + self.as_ref() + } +} + +impl TraitPublic for Public { + /// A new instance from the given slice that should be 32 bytes long. + /// + /// NOTE: No checking goes on to ensure this is a real public key. Only use it if + /// you are certain that the array actually is a pubkey. GIGO! + fn from_slice(data: &[u8]) -> Self { + let mut r = [0u8; 32]; + r.copy_from_slice(data); + Public(r) + } + + fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { + CryptoTypePublicPair(CRYPTO_ID, self.to_raw_vec()) + } +} + +impl Derive for Public {} + +impl From for CryptoTypePublicPair { + fn from(key: Public) -> Self { + (&key).into() + } +} + +impl From<&Public> for CryptoTypePublicPair { + fn from(key: &Public) -> Self { + CryptoTypePublicPair(CRYPTO_ID, key.to_raw_vec()) + } +} + +/// Derive a single hard junction. +#[cfg(feature = "full_crypto")] +fn derive_hard_junction(secret_seed: &Seed, cc: &[u8; 32]) -> Seed { + ("Ed25519HDKD", secret_seed, cc).using_encoded(|data| { + let mut res = [0u8; 32]; + res.copy_from_slice(blake2_rfc::blake2b::blake2b(32, &[], data).as_bytes()); + res + }) +} + +/// An error when deriving a key. +#[cfg(feature = "full_crypto")] +pub enum DeriveError { + /// A soft key was found in the path (and is unsupported). + SoftKeyInPath, +} + +#[cfg(feature = "full_crypto")] +impl TraitPair for Pair { + type Public = Public; + type Seed = Seed; + type Signature = Signature; + type DeriveError = DeriveError; + + /// Generate new secure (random) key pair and provide the recovery phrase. + /// + /// You can recover the same key later with `from_phrase`. + #[cfg(feature = "std")] + fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) { + let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English); + let phrase = mnemonic.phrase(); + let (pair, seed) = Self::from_phrase(phrase, password) + .expect("All phrases generated by Mnemonic are valid; qed"); + ( + pair, + phrase.to_owned(), + seed, + ) + } + + /// Generate key pair from given recovery phrase and password. + #[cfg(feature = "std")] + fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> { + let big_seed = seed_from_entropy( + Mnemonic::from_phrase(phrase, Language::English) + .map_err(|_| SecretStringError::InvalidPhrase)?.entropy(), + password.unwrap_or(""), + ).map_err(|_| SecretStringError::InvalidSeed)?; + let mut seed = Seed::default(); + seed.copy_from_slice(&big_seed[0..32]); + Self::from_seed_slice(&big_seed[0..32]).map(|x| (x, seed)) + } + + /// Make a new key pair from secret seed material. + /// + /// You should never need to use this; generate(), generate_with_phrase + fn from_seed(seed: &Seed) -> Pair { + Self::from_seed_slice(&seed[..]).expect("seed has valid length; qed") + } + + /// Make a new key pair from secret seed material. The slice must be 32 bytes long or it + /// will return `None`. + /// + /// You should never need to use this; generate(), generate_with_phrase + fn from_seed_slice(seed_slice: &[u8]) -> Result { + let secret = ed25519_dalek::SecretKey::from_bytes(seed_slice) + .map_err(|_| SecretStringError::InvalidSeedLength)?; + let public = ed25519_dalek::PublicKey::from(&secret); + Ok(Pair(ed25519_dalek::Keypair { secret, public })) + } + + /// Derive a child key from a series of given junctions. + fn derive>(&self, + path: Iter, + _seed: Option, + ) -> Result<(Pair, Option), DeriveError> { + let mut acc = self.0.secret.to_bytes(); + for j in path { + match j { + DeriveJunction::Soft(_cc) => return Err(DeriveError::SoftKeyInPath), + DeriveJunction::Hard(cc) => acc = derive_hard_junction(&acc, &cc), + } + } + Ok((Self::from_seed(&acc), Some(acc))) + } + + /// Get the public key. + fn public(&self) -> Public { + let mut r = [0u8; 32]; + let pk = self.0.public.as_bytes(); + r.copy_from_slice(pk); + Public(r) + } + + /// Sign a message. + fn sign(&self, message: &[u8]) -> Signature { + let r = self.0.sign(message).to_bytes(); + Signature::from_raw(r) + } + + /// Verify a signature on a message. Returns true if the signature is good. + fn verify>(sig: &Self::Signature, message: M, pubkey: &Self::Public) -> bool { + Self::verify_weak(&sig.0[..], message.as_ref(), pubkey) + } + + /// Verify a signature on a message. Returns true if the signature is good. + /// + /// This doesn't use the type system to ensure that `sig` and `pubkey` are the correct + /// size. Use it only if you're coming from byte buffers and need the speed. + fn verify_weak, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool { + let public_key = match ed25519_dalek::PublicKey::from_bytes(pubkey.as_ref()) { + Ok(pk) => pk, + Err(_) => return false, + }; + + let sig = match ed25519_dalek::Signature::try_from(sig) { + Ok(s) => s, + Err(_) => return false + }; + + match public_key.verify(message.as_ref(), &sig) { + Ok(_) => true, + _ => false, + } + } + + /// Return a vec filled with raw data. + fn to_raw_vec(&self) -> Vec { + self.seed().to_vec() + } +} + +#[cfg(feature = "full_crypto")] +impl Pair { + /// Get the seed for this key. + pub fn seed(&self) -> &Seed { + self.0.secret.as_bytes() + } + + /// Exactly as `from_string` except that if no matches are found then, the the first 32 + /// characters are taken (padded with spaces as necessary) and used as the MiniSecretKey. + #[cfg(feature = "std")] + pub fn from_legacy_string(s: &str, password_override: Option<&str>) -> Pair { + Self::from_string(s, password_override).unwrap_or_else(|_| { + let mut padded_seed: Seed = [' ' as u8; 32]; + let len = s.len().min(32); + padded_seed[..len].copy_from_slice(&s.as_bytes()[..len]); + Self::from_seed(&padded_seed) + }) + } +} + +impl CryptoType for Public { + #[cfg(feature = "full_crypto")] + type Pair = Pair; +} + +impl CryptoType for Signature { + #[cfg(feature = "full_crypto")] + type Pair = Pair; +} + +#[cfg(feature = "full_crypto")] +impl CryptoType for Pair { + type Pair = Pair; +} + +#[cfg(test)] +mod test { + use super::*; + use hex_literal::hex; + use crate::crypto::DEV_PHRASE; + use serde_json; + + #[test] + fn default_phrase_should_be_used() { + assert_eq!( + Pair::from_string("//Alice///password", None).unwrap().public(), + Pair::from_string(&format!("{}//Alice", DEV_PHRASE), Some("password")).unwrap().public(), + ); + } + + #[test] + fn seed_and_derive_should_work() { + let seed = hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"); + let pair = Pair::from_seed(&seed); + assert_eq!(pair.seed(), &seed); + let path = vec![DeriveJunction::Hard([0u8; 32])]; + let derived = pair.derive(path.into_iter(), None).ok().unwrap().0; + assert_eq!( + derived.seed(), + &hex!("ede3354e133f9c8e337ddd6ee5415ed4b4ffe5fc7d21e933f4930a3730e5b21c") + ); + } + + #[test] + fn test_vector_should_work() { + let pair = Pair::from_seed( + &hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60") + ); + let public = pair.public(); + assert_eq!(public, Public::from_raw( + hex!("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a") + )); + let message = b""; + let signature = hex!("e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"); + let signature = Signature::from_raw(signature); + assert!(&pair.sign(&message[..]) == &signature); + assert!(Pair::verify(&signature, &message[..], &public)); + } + + #[test] + fn test_vector_by_string_should_work() { + let pair = Pair::from_string( + "0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60", + None + ).unwrap(); + let public = pair.public(); + assert_eq!(public, Public::from_raw( + hex!("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a") + )); + let message = b""; + let signature = hex!("e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"); + let signature = Signature::from_raw(signature); + assert!(&pair.sign(&message[..]) == &signature); + assert!(Pair::verify(&signature, &message[..], &public)); + } + + #[test] + fn generated_pair_should_work() { + let (pair, _) = Pair::generate(); + let public = pair.public(); + let message = b"Something important"; + let signature = pair.sign(&message[..]); + assert!(Pair::verify(&signature, &message[..], &public)); + assert!(!Pair::verify(&signature, b"Something else", &public)); + } + + #[test] + fn seeded_pair_should_work() { + let pair = Pair::from_seed(b"12345678901234567890123456789012"); + let public = pair.public(); + assert_eq!(public, Public::from_raw( + hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee") + )); + let message = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000200d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000"); + let signature = pair.sign(&message[..]); + println!("Correct signature: {:?}", signature); + assert!(Pair::verify(&signature, &message[..], &public)); + assert!(!Pair::verify(&signature, "Other message", &public)); + } + + #[test] + fn generate_with_phrase_recovery_possible() { + let (pair1, phrase, _) = Pair::generate_with_phrase(None); + let (pair2, _) = Pair::from_phrase(&phrase, None).unwrap(); + + assert_eq!(pair1.public(), pair2.public()); + } + + #[test] + fn generate_with_password_phrase_recovery_possible() { + let (pair1, phrase, _) = Pair::generate_with_phrase(Some("password")); + let (pair2, _) = Pair::from_phrase(&phrase, Some("password")).unwrap(); + + assert_eq!(pair1.public(), pair2.public()); + } + + #[test] + fn password_does_something() { + let (pair1, phrase, _) = Pair::generate_with_phrase(Some("password")); + let (pair2, _) = Pair::from_phrase(&phrase, None).unwrap(); + + assert_ne!(pair1.public(), pair2.public()); + } + + #[test] + fn ss58check_roundtrip_works() { + let pair = Pair::from_seed(b"12345678901234567890123456789012"); + let public = pair.public(); + let s = public.to_ss58check(); + println!("Correct: {}", s); + let cmp = Public::from_ss58check(&s).unwrap(); + assert_eq!(cmp, public); + } + + #[test] + fn signature_serialization_works() { + let pair = Pair::from_seed(b"12345678901234567890123456789012"); + let message = b"Something important"; + let signature = pair.sign(&message[..]); + let serialized_signature = serde_json::to_string(&signature).unwrap(); + // Signature is 64 bytes, so 128 chars + 2 quote chars + assert_eq!(serialized_signature.len(), 130); + let signature = serde_json::from_str(&serialized_signature).unwrap(); + assert!(Pair::verify(&signature, &message[..], &pair.public())); + } + + #[test] + fn signature_serialization_doesnt_panic() { + fn deserialize_signature(text: &str) -> Result { + Ok(serde_json::from_str(text)?) + } + assert!(deserialize_signature("Not valid json.").is_err()); + assert!(deserialize_signature("\"Not an actual signature.\"").is_err()); + // Poorly-sized + assert!(deserialize_signature("\"abc123\"").is_err()); + } +} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/hash.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/hash.rs new file mode 100644 index 00000000..20a6788c --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/hash.rs @@ -0,0 +1,82 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! A fixed hash type. + +pub use primitive_types::{H160, H256, H512}; + +/// Hash conversion. Used to convert between unbound associated hash types in traits, +/// implemented by the same hash type. +/// Panics if used to convert between different hash types. +pub fn convert_hash, H2: AsRef<[u8]>>(src: &H2) -> H1 { + let mut dest = H1::default(); + assert_eq!(dest.as_mut().len(), src.as_ref().len()); + dest.as_mut().copy_from_slice(src.as_ref()); + dest +} + +#[cfg(test)] +mod tests { + use super::*; + use sp_serializer as ser; + + #[test] + fn test_h160() { + let tests = vec![ + (Default::default(), "0x0000000000000000000000000000000000000000"), + (H160::from_low_u64_be(2), "0x0000000000000000000000000000000000000002"), + (H160::from_low_u64_be(15), "0x000000000000000000000000000000000000000f"), + (H160::from_low_u64_be(16), "0x0000000000000000000000000000000000000010"), + (H160::from_low_u64_be(1_000), "0x00000000000000000000000000000000000003e8"), + (H160::from_low_u64_be(100_000), "0x00000000000000000000000000000000000186a0"), + (H160::from_low_u64_be(u64::max_value()), "0x000000000000000000000000ffffffffffffffff"), + ]; + + for (number, expected) in tests { + assert_eq!(format!("{:?}", expected), ser::to_string_pretty(&number)); + assert_eq!(number, ser::from_str(&format!("{:?}", expected)).unwrap()); + } + } + + #[test] + fn test_h256() { + let tests = vec![ + (Default::default(), "0x0000000000000000000000000000000000000000000000000000000000000000"), + (H256::from_low_u64_be(2), "0x0000000000000000000000000000000000000000000000000000000000000002"), + (H256::from_low_u64_be(15), "0x000000000000000000000000000000000000000000000000000000000000000f"), + (H256::from_low_u64_be(16), "0x0000000000000000000000000000000000000000000000000000000000000010"), + (H256::from_low_u64_be(1_000), "0x00000000000000000000000000000000000000000000000000000000000003e8"), + (H256::from_low_u64_be(100_000), "0x00000000000000000000000000000000000000000000000000000000000186a0"), + (H256::from_low_u64_be(u64::max_value()), "0x000000000000000000000000000000000000000000000000ffffffffffffffff"), + ]; + + for (number, expected) in tests { + assert_eq!(format!("{:?}", expected), ser::to_string_pretty(&number)); + assert_eq!(number, ser::from_str(&format!("{:?}", expected)).unwrap()); + } + } + + #[test] + fn test_invalid() { + assert!(ser::from_str::("\"0x000000000000000000000000000000000000000000000000000000000000000\"").unwrap_err().is_data()); + assert!(ser::from_str::("\"0x000000000000000000000000000000000000000000000000000000000000000g\"").unwrap_err().is_data()); + assert!(ser::from_str::("\"0x00000000000000000000000000000000000000000000000000000000000000000\"").unwrap_err().is_data()); + assert!(ser::from_str::("\"\"").unwrap_err().is_data()); + assert!(ser::from_str::("\"0\"").unwrap_err().is_data()); + assert!(ser::from_str::("\"10\"").unwrap_err().is_data()); + } +} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/hasher.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/hasher.rs new file mode 100644 index 00000000..8ccaa4d9 --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/hasher.rs @@ -0,0 +1,58 @@ +// This file is part of Substrate. + +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Substrate Blake2b Hasher implementation + +pub mod blake2 { + use hash_db::Hasher; + use hash256_std_hasher::Hash256StdHasher; + use crate::hash::H256; + + /// Concrete implementation of Hasher using Blake2b 256-bit hashes + #[derive(Debug)] + pub struct Blake2Hasher; + + impl Hasher for Blake2Hasher { + type Out = H256; + type StdHasher = Hash256StdHasher; + const LENGTH: usize = 32; + + fn hash(x: &[u8]) -> Self::Out { + crate::hashing::blake2_256(x).into() + } + } +} + +pub mod keccak { + use hash_db::Hasher; + use hash256_std_hasher::Hash256StdHasher; + use crate::hash::H256; + + /// Concrete implementation of Hasher using Keccak 256-bit hashes + #[derive(Debug)] + pub struct KeccakHasher; + + impl Hasher for KeccakHasher { + type Out = H256; + type StdHasher = Hash256StdHasher; + const LENGTH: usize = 32; + + fn hash(x: &[u8]) -> Self::Out { + crate::hashing::keccak_256(x).into() + } + } +} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/hashing.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/hashing.rs new file mode 100644 index 00000000..f61700a5 --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/hashing.rs @@ -0,0 +1,156 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Hashing functions. + +use blake2_rfc; +use sha2::{Digest, Sha256}; +use tiny_keccak::{Hasher, Keccak}; +use twox_hash; + +/// Do a Blake2 512-bit hash and place result in `dest`. +pub fn blake2_512_into(data: &[u8], dest: &mut [u8; 64]) { + dest.copy_from_slice(blake2_rfc::blake2b::blake2b(64, &[], data).as_bytes()); +} + +/// Do a Blake2 512-bit hash and return result. +pub fn blake2_512(data: &[u8]) -> [u8; 64] { + let mut r = [0; 64]; + blake2_512_into(data, &mut r); + r +} + +/// Do a Blake2 256-bit hash and place result in `dest`. +pub fn blake2_256_into(data: &[u8], dest: &mut [u8; 32]) { + dest.copy_from_slice(blake2_rfc::blake2b::blake2b(32, &[], data).as_bytes()); +} + +/// Do a Blake2 256-bit hash and return result. +pub fn blake2_256(data: &[u8]) -> [u8; 32] { + let mut r = [0; 32]; + blake2_256_into(data, &mut r); + r +} + +/// Do a Blake2 128-bit hash and place result in `dest`. +pub fn blake2_128_into(data: &[u8], dest: &mut [u8; 16]) { + dest.copy_from_slice(blake2_rfc::blake2b::blake2b(16, &[], data).as_bytes()); +} + +/// Do a Blake2 128-bit hash and return result. +pub fn blake2_128(data: &[u8]) -> [u8; 16] { + let mut r = [0; 16]; + blake2_128_into(data, &mut r); + r +} + +/// Do a Blake2 64-bit hash and place result in `dest`. +pub fn blake2_64_into(data: &[u8], dest: &mut [u8; 8]) { + dest.copy_from_slice(blake2_rfc::blake2b::blake2b(8, &[], data).as_bytes()); +} + +/// Do a Blake2 64-bit hash and return result. +pub fn blake2_64(data: &[u8]) -> [u8; 8] { + let mut r = [0; 8]; + blake2_64_into(data, &mut r); + r +} + +/// Do a XX 64-bit hash and place result in `dest`. +pub fn twox_64_into(data: &[u8], dest: &mut [u8; 8]) { + use ::core::hash::Hasher; + let mut h0 = twox_hash::XxHash::with_seed(0); + h0.write(data); + let r0 = h0.finish(); + use byteorder::{ByteOrder, LittleEndian}; + LittleEndian::write_u64(&mut dest[0..8], r0); +} + +/// Do a XX 64-bit hash and return result. +pub fn twox_64(data: &[u8]) -> [u8; 8] { + let mut r: [u8; 8] = [0; 8]; + twox_64_into(data, &mut r); + r +} + +/// Do a XX 128-bit hash and place result in `dest`. +pub fn twox_128_into(data: &[u8], dest: &mut [u8; 16]) { + use ::core::hash::Hasher; + let mut h0 = twox_hash::XxHash::with_seed(0); + let mut h1 = twox_hash::XxHash::with_seed(1); + h0.write(data); + h1.write(data); + let r0 = h0.finish(); + let r1 = h1.finish(); + use byteorder::{ByteOrder, LittleEndian}; + LittleEndian::write_u64(&mut dest[0..8], r0); + LittleEndian::write_u64(&mut dest[8..16], r1); +} + +/// Do a XX 128-bit hash and return result. +pub fn twox_128(data: &[u8]) -> [u8; 16] { + let mut r: [u8; 16] = [0; 16]; + twox_128_into(data, &mut r); + r +} + +/// Do a XX 256-bit hash and place result in `dest`. +pub fn twox_256_into(data: &[u8], dest: &mut [u8; 32]) { + use ::core::hash::Hasher; + use byteorder::{ByteOrder, LittleEndian}; + let mut h0 = twox_hash::XxHash::with_seed(0); + let mut h1 = twox_hash::XxHash::with_seed(1); + let mut h2 = twox_hash::XxHash::with_seed(2); + let mut h3 = twox_hash::XxHash::with_seed(3); + h0.write(data); + h1.write(data); + h2.write(data); + h3.write(data); + let r0 = h0.finish(); + let r1 = h1.finish(); + let r2 = h2.finish(); + let r3 = h3.finish(); + LittleEndian::write_u64(&mut dest[0..8], r0); + LittleEndian::write_u64(&mut dest[8..16], r1); + LittleEndian::write_u64(&mut dest[16..24], r2); + LittleEndian::write_u64(&mut dest[24..32], r3); +} + +/// Do a XX 256-bit hash and return result. +pub fn twox_256(data: &[u8]) -> [u8; 32] { + let mut r: [u8; 32] = [0; 32]; + twox_256_into(data, &mut r); + r +} + +/// Do a keccak 256-bit hash and return result. +pub fn keccak_256(data: &[u8]) -> [u8; 32] { + let mut keccak = Keccak::v256(); + keccak.update(data); + let mut output = [0u8; 32]; + keccak.finalize(&mut output); + output +} + +/// Do a sha2 256-bit hash and return result. +pub fn sha2_256(data: &[u8]) -> [u8; 32] { + let mut hasher = Sha256::new(); + hasher.input(data); + let mut output = [0u8; 32]; + output.copy_from_slice(&hasher.result()); + output +} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/hexdisplay.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/hexdisplay.rs new file mode 100644 index 00000000..9d2b7a12 --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/hexdisplay.rs @@ -0,0 +1,104 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Wrapper type for byte collections that outputs hex. + +/// Simple wrapper to display hex representation of bytes. +pub struct HexDisplay<'a>(&'a [u8]); + +impl<'a> HexDisplay<'a> { + /// Create new instance that will display `d` as a hex string when displayed. + pub fn from(d: &'a R) -> Self { HexDisplay(d.as_bytes_ref()) } +} + +impl<'a> sp_std::fmt::Display for HexDisplay<'a> { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> Result<(), sp_std::fmt::Error> { + if self.0.len() < 1027 { + for byte in self.0 { + f.write_fmt(format_args!("{:02x}", byte))?; + } + } else { + for byte in &self.0[0..512] { + f.write_fmt(format_args!("{:02x}", byte))?; + } + f.write_str("...")?; + for byte in &self.0[self.0.len() - 512..] { + f.write_fmt(format_args!("{:02x}", byte))?; + } + } + Ok(()) + } +} + +impl<'a> sp_std::fmt::Debug for HexDisplay<'a> { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> Result<(), sp_std::fmt::Error> { + for byte in self.0 { + f.write_fmt(format_args!("{:02x}", byte))?; + } + Ok(()) + } +} + +/// Simple trait to transform various types to `&[u8]` +pub trait AsBytesRef { + /// Transform `self` into `&[u8]`. + fn as_bytes_ref(&self) -> &[u8]; +} + +impl AsBytesRef for &[u8] { + fn as_bytes_ref(&self) -> &[u8] { self } +} + +impl AsBytesRef for [u8] { + fn as_bytes_ref(&self) -> &[u8] { &self } +} + +impl AsBytesRef for sp_std::vec::Vec { + fn as_bytes_ref(&self) -> &[u8] { &self } +} + +macro_rules! impl_non_endians { + ( $( $t:ty ),* ) => { $( + impl AsBytesRef for $t { + fn as_bytes_ref(&self) -> &[u8] { &self[..] } + } + )* } +} + +impl_non_endians!([u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8], + [u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40], + [u8; 48], [u8; 56], [u8; 64], [u8; 65], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); + +/// Format into ASCII + # + hex, suitable for storage key preimages. +#[cfg(feature = "std")] +pub fn ascii_format(asciish: &[u8]) -> String { + let mut r = String::new(); + let mut latch = false; + for c in asciish { + match (latch, *c) { + (false, 32..=127) => r.push(*c as char), + _ => { + if !latch { + r.push('#'); + latch = true; + } + r.push_str(&format!("{:02x}", *c)); + } + } + } + r +} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/lib.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/lib.rs new file mode 100644 index 00000000..94f6bb29 --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/lib.rs @@ -0,0 +1,390 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Shareable Substrate types. + +#![warn(missing_docs)] + +#![cfg_attr(not(feature = "std"), no_std)] + +/// Initialize a key-value collection from array. +/// +/// Creates a vector of given pairs and calls `collect` on the iterator from it. +/// Can be used to create a `HashMap`. +#[macro_export] +macro_rules! map { + ($( $name:expr => $value:expr ),* $(,)? ) => ( + vec![ $( ( $name, $value ) ),* ].into_iter().collect() + ); +} + +use sp_runtime_interface::pass_by::{PassByEnum, PassByInner}; +use sp_std::prelude::*; +use sp_std::ops::Deref; +#[cfg(feature = "std")] +use std::borrow::Cow; +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; +#[cfg(feature = "std")] +pub use serde; +#[doc(hidden)] +pub use codec::{Encode, Decode}; + +pub use sp_debug_derive::RuntimeDebug; + +#[cfg(feature = "std")] +pub use impl_serde::serialize as bytes; + +#[cfg(feature = "full_crypto")] +pub mod hashing; + +#[cfg(feature = "full_crypto")] +pub use hashing::{blake2_128, blake2_256, twox_64, twox_128, twox_256, keccak_256}; +pub mod hexdisplay; +pub mod crypto; + +pub mod u32_trait; + +pub mod ed25519; +pub mod sr25519; +pub mod ecdsa; +pub mod hash; +#[cfg(feature = "std")] +mod hasher; +pub mod offchain; +pub mod sandbox; +pub mod uint; +mod changes_trie; +#[cfg(feature = "std")] +pub mod traits; +pub mod testing; +#[cfg(feature = "std")] +pub mod vrf; + +pub use self::hash::{H160, H256, H512, convert_hash}; +pub use self::uint::{U256, U512}; +pub use changes_trie::{ChangesTrieConfiguration, ChangesTrieConfigurationRange}; +#[cfg(feature = "full_crypto")] +pub use crypto::{DeriveJunction, Pair, Public}; + +pub use hash_db::Hasher; +#[cfg(feature = "std")] +pub use self::hasher::blake2::Blake2Hasher; +#[cfg(feature = "std")] +pub use self::hasher::keccak::KeccakHasher; + +pub use sp_storage as storage; + +#[doc(hidden)] +pub use sp_std; + +/// Context for executing a call into the runtime. +pub enum ExecutionContext { + /// Context used for general block import (including locally authored blocks). + Importing, + /// Context used for importing blocks as part of an initial sync of the blockchain. + /// + /// We distinguish between major sync and import so that validators who are running + /// their initial sync (or catching up after some time offline) can use the faster + /// native runtime (since we can reasonably assume the network as a whole has already + /// come to a broad conensus on the block and it probably hasn't been crafted + /// specifically to attack this node), but when importing blocks at the head of the + /// chain in normal operation they can use the safer Wasm version. + Syncing, + /// Context used for block construction. + BlockConstruction, + /// Context used for offchain calls. + /// + /// This allows passing offchain extension and customizing available capabilities. + OffchainCall(Option<(Box, offchain::Capabilities)>), +} + +impl ExecutionContext { + /// Returns the capabilities of particular context. + pub fn capabilities(&self) -> offchain::Capabilities { + use ExecutionContext::*; + + match self { + Importing | Syncing | BlockConstruction => + offchain::Capabilities::none(), + // Enable keystore and transaction pool by default for offchain calls. + OffchainCall(None) => [ + offchain::Capability::Keystore, + offchain::Capability::TransactionPool, + ][..].into(), + OffchainCall(Some((_, capabilities))) => *capabilities, + } + } +} + +/// Hex-serialized shim for `Vec`. +#[derive(PartialEq, Eq, Clone, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash, PartialOrd, Ord))] +pub struct Bytes(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec); + +impl From> for Bytes { + fn from(s: Vec) -> Self { Bytes(s) } +} + +impl From for Bytes { + fn from(s: OpaqueMetadata) -> Self { Bytes(s.0) } +} + +impl Deref for Bytes { + type Target = [u8]; + fn deref(&self) -> &[u8] { &self.0[..] } +} + +#[cfg(feature = "std")] +impl sp_std::str::FromStr for Bytes { + type Err = bytes::FromHexError; + + fn from_str(s: &str) -> Result { + bytes::from_hex(s).map(Bytes) + } +} + +/// Stores the encoded `RuntimeMetadata` for the native side as opaque type. +#[derive(Encode, Decode, PartialEq)] +pub struct OpaqueMetadata(Vec); + +impl OpaqueMetadata { + /// Creates a new instance with the given metadata blob. + pub fn new(metadata: Vec) -> Self { + OpaqueMetadata(metadata) + } +} + +impl sp_std::ops::Deref for OpaqueMetadata { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +/// Simple blob to hold a `PeerId` without committing to its format. +#[derive(Default, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, PassByInner)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct OpaquePeerId(pub Vec); + +impl OpaquePeerId { + /// Create new `OpaquePeerId` + pub fn new(vec: Vec) -> Self { + OpaquePeerId(vec) + } +} + +/// Something that is either a native or an encoded value. +#[cfg(feature = "std")] +pub enum NativeOrEncoded { + /// The native representation. + Native(R), + /// The encoded representation. + Encoded(Vec) +} + +#[cfg(feature = "std")] +impl sp_std::fmt::Debug for NativeOrEncoded { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + hexdisplay::HexDisplay::from(&self.as_encoded().as_ref()).fmt(f) + } +} + +#[cfg(feature = "std")] +impl NativeOrEncoded { + /// Return the value as the encoded format. + pub fn as_encoded(&self) -> Cow<'_, [u8]> { + match self { + NativeOrEncoded::Encoded(e) => Cow::Borrowed(e.as_slice()), + NativeOrEncoded::Native(n) => Cow::Owned(n.encode()), + } + } + + /// Return the value as the encoded format. + pub fn into_encoded(self) -> Vec { + match self { + NativeOrEncoded::Encoded(e) => e, + NativeOrEncoded::Native(n) => n.encode(), + } + } +} + +#[cfg(feature = "std")] +impl PartialEq for NativeOrEncoded { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (NativeOrEncoded::Native(l), NativeOrEncoded::Native(r)) => l == r, + (NativeOrEncoded::Native(n), NativeOrEncoded::Encoded(e)) | + (NativeOrEncoded::Encoded(e), NativeOrEncoded::Native(n)) => + Some(n) == codec::Decode::decode(&mut &e[..]).ok().as_ref(), + (NativeOrEncoded::Encoded(l), NativeOrEncoded::Encoded(r)) => l == r, + } + } +} + +/// A value that is never in a native representation. +/// This is type is useful in conjunction with `NativeOrEncoded`. +#[cfg(feature = "std")] +#[derive(PartialEq)] +pub enum NeverNativeValue {} + +#[cfg(feature = "std")] +impl codec::Encode for NeverNativeValue { + fn encode(&self) -> Vec { + // The enum is not constructable, so this function should never be callable! + unreachable!() + } +} + +#[cfg(feature = "std")] +impl codec::EncodeLike for NeverNativeValue {} + +#[cfg(feature = "std")] +impl codec::Decode for NeverNativeValue { + fn decode(_: &mut I) -> Result { + Err("`NeverNativeValue` should never be decoded".into()) + } +} + +/// Provide a simple 4 byte identifier for a type. +pub trait TypeId { + /// Simple 4 byte identifier. + const TYPE_ID: [u8; 4]; +} + +/// A log level matching the one from `log` crate. +/// +/// Used internally by `sp_io::log` method. +#[derive(Encode, Decode, PassByEnum, Copy, Clone)] +pub enum LogLevel { + /// `Error` log level. + Error = 1, + /// `Warn` log level. + Warn = 2, + /// `Info` log level. + Info = 3, + /// `Debug` log level. + Debug = 4, + /// `Trace` log level. + Trace = 5, +} + +impl From for LogLevel { + fn from(val: u32) -> Self { + match val { + x if x == LogLevel::Warn as u32 => LogLevel::Warn, + x if x == LogLevel::Info as u32 => LogLevel::Info, + x if x == LogLevel::Debug as u32 => LogLevel::Debug, + x if x == LogLevel::Trace as u32 => LogLevel::Trace, + _ => LogLevel::Error, + } + } +} + +impl From for LogLevel { + fn from(l: log::Level) -> Self { + use log::Level::*; + match l { + Error => Self::Error, + Warn => Self::Warn, + Info => Self::Info, + Debug => Self::Debug, + Trace => Self::Trace, + } + } +} + +impl From for log::Level { + fn from(l: LogLevel) -> Self { + use self::LogLevel::*; + match l { + Error => Self::Error, + Warn => Self::Warn, + Info => Self::Info, + Debug => Self::Debug, + Trace => Self::Trace, + } + } +} + +/// Encodes the given value into a buffer and returns the pointer and the length as a single `u64`. +/// +/// When Substrate calls into Wasm it expects a fixed signature for functions exported +/// from the Wasm blob. The return value of this signature is always a `u64`. +/// This `u64` stores the pointer to the encoded return value and the length of this encoded value. +/// The low `32bits` are reserved for the pointer, followed by `32bit` for the length. +#[cfg(not(feature = "std"))] +pub fn to_substrate_wasm_fn_return_value(value: &impl Encode) -> u64 { + let encoded = value.encode(); + + let ptr = encoded.as_ptr() as u64; + let length = encoded.len() as u64; + let res = ptr | (length << 32); + + // Leak the output vector to avoid it being freed. + // This is fine in a WASM context since the heap + // will be discarded after the call. + sp_std::mem::forget(encoded); + + res +} + +/// The void type - it cannot exist. +// Oh rust, you crack me up... +#[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebug)] +pub enum Void {} + +/// Macro for creating `Maybe*` marker traits. +/// +/// Such a maybe-marker trait requires the given bound when `feature = std` and doesn't require +/// the bound on `no_std`. This is useful for situations where you require that a type implements +/// a certain trait with `feature = std`, but not on `no_std`. +/// +/// # Example +/// +/// ``` +/// sp_core::impl_maybe_marker! { +/// /// A marker for a type that implements `Debug` when `feature = std`. +/// trait MaybeDebug: std::fmt::Debug; +/// /// A marker for a type that implements `Debug + Display` when `feature = std`. +/// trait MaybeDebugDisplay: std::fmt::Debug, std::fmt::Display; +/// } +/// ``` +#[macro_export] +macro_rules! impl_maybe_marker { + ( + $( + $(#[$doc:meta] )+ + trait $trait_name:ident: $( $trait_bound:path ),+; + )+ + ) => { + $( + $(#[$doc])+ + #[cfg(feature = "std")] + pub trait $trait_name: $( $trait_bound + )+ {} + #[cfg(feature = "std")] + impl $trait_name for T {} + + $(#[$doc])+ + #[cfg(not(feature = "std"))] + pub trait $trait_name {} + #[cfg(not(feature = "std"))] + impl $trait_name for T {} + )+ + } +} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/mod.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/mod.rs new file mode 100644 index 00000000..4768496c --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/mod.rs @@ -0,0 +1,775 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Offchain workers types + +use codec::{Encode, Decode}; +use sp_std::{prelude::{Vec, Box}, convert::TryFrom}; +use crate::{OpaquePeerId, RuntimeDebug}; +use sp_runtime_interface::pass_by::{PassByCodec, PassByInner, PassByEnum}; + +pub use crate::crypto::KeyTypeId; + +#[cfg(feature = "std")] +pub mod storage; +#[cfg(feature = "std")] +pub mod testing; + +/// Local storage prefix used by the Offchain Worker API to +pub const STORAGE_PREFIX : &'static [u8] = b"storage"; + +/// Offchain workers local storage. +pub trait OffchainStorage: Clone + Send + Sync { + /// Persist a value in storage under given key and prefix. + fn set(&mut self, prefix: &[u8], key: &[u8], value: &[u8]); + + /// Clear a storage entry under given key and prefix. + fn remove(&mut self, prefix: &[u8], key: &[u8]); + + /// Retrieve a value from storage under given key and prefix. + fn get(&self, prefix: &[u8], key: &[u8]) -> Option>; + + /// Replace the value in storage if given old_value matches the current one. + /// + /// Returns `true` if the value has been set and false otherwise. + fn compare_and_set( + &mut self, + prefix: &[u8], + key: &[u8], + old_value: Option<&[u8]>, + new_value: &[u8], + ) -> bool; +} + +/// A type of supported crypto. +#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, RuntimeDebug, PassByEnum)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +#[repr(C)] +pub enum StorageKind { + /// Persistent storage is non-revertible and not fork-aware. It means that any value + /// set by the offchain worker triggered at block `N(hash1)` is persisted even + /// if that block is reverted as non-canonical and is available for the worker + /// that is re-run at block `N(hash2)`. + /// This storage can be used by offchain workers to handle forks + /// and coordinate offchain workers running on different forks. + PERSISTENT = 1, + /// Local storage is revertible and fork-aware. It means that any value + /// set by the offchain worker triggered at block `N(hash1)` is reverted + /// if that block is reverted as non-canonical and is NOT available for the worker + /// that is re-run at block `N(hash2)`. + LOCAL = 2, +} + +impl TryFrom for StorageKind { + type Error = (); + + fn try_from(kind: u32) -> Result { + match kind { + e if e == u32::from(StorageKind::PERSISTENT as u8) => Ok(StorageKind::PERSISTENT), + e if e == u32::from(StorageKind::LOCAL as u8) => Ok(StorageKind::LOCAL), + _ => Err(()), + } + } +} + +impl From for u32 { + fn from(c: StorageKind) -> Self { + c as u8 as u32 + } +} + +/// Opaque type for offchain http requests. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, Encode, Decode, PassByInner)] +#[cfg_attr(feature = "std", derive(Hash))] +pub struct HttpRequestId(pub u16); + +impl From for u32 { + fn from(c: HttpRequestId) -> Self { + c.0 as u32 + } +} + +/// An error enum returned by some http methods. +#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug, Encode, Decode, PassByEnum)] +#[repr(C)] +pub enum HttpError { + /// The requested action couldn't been completed within a deadline. + DeadlineReached = 1, + /// There was an IO Error while processing the request. + IoError = 2, + /// The ID of the request is invalid in this context. + Invalid = 3, +} + +impl TryFrom for HttpError { + type Error = (); + + fn try_from(error: u32) -> Result { + match error { + e if e == HttpError::DeadlineReached as u8 as u32 => Ok(HttpError::DeadlineReached), + e if e == HttpError::IoError as u8 as u32 => Ok(HttpError::IoError), + e if e == HttpError::Invalid as u8 as u32 => Ok(HttpError::Invalid), + _ => Err(()) + } + } +} + +impl From for u32 { + fn from(c: HttpError) -> Self { + c as u8 as u32 + } +} + +/// Status of the HTTP request +#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug, Encode, Decode, PassByCodec)] +pub enum HttpRequestStatus { + /// Deadline was reached while we waited for this request to finish. + /// + /// Note the deadline is controlled by the calling part, it not necessarily + /// means that the request has timed out. + DeadlineReached, + /// An error has occurred during the request, for example a timeout or the + /// remote has closed our socket. + /// + /// The request is now considered destroyed. To retry the request you need + /// to construct it again. + IoError, + /// The passed ID is invalid in this context. + Invalid, + /// The request has finished with given status code. + Finished(u16), +} + +impl From for u32 { + fn from(status: HttpRequestStatus) -> Self { + match status { + HttpRequestStatus::Invalid => 0, + HttpRequestStatus::DeadlineReached => 10, + HttpRequestStatus::IoError => 20, + HttpRequestStatus::Finished(code) => u32::from(code), + } + } +} + +impl TryFrom for HttpRequestStatus { + type Error = (); + + fn try_from(status: u32) -> Result { + match status { + 0 => Ok(HttpRequestStatus::Invalid), + 10 => Ok(HttpRequestStatus::DeadlineReached), + 20 => Ok(HttpRequestStatus::IoError), + 100..=999 => u16::try_from(status).map(HttpRequestStatus::Finished).map_err(|_| ()), + _ => Err(()), + } + } +} + +/// A blob to hold information about the local node's network state +/// without committing to its format. +#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, PassByCodec)] +#[cfg_attr(feature = "std", derive(Default))] +pub struct OpaqueNetworkState { + /// PeerId of the local node in SCALE encoded. + pub peer_id: OpaquePeerId, + /// List of addresses the node knows it can be reached as. + pub external_addresses: Vec, +} + +/// Simple blob to hold a `Multiaddr` without committing to its format. +#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, PassByInner)] +pub struct OpaqueMultiaddr(pub Vec); + +impl OpaqueMultiaddr { + /// Create new `OpaqueMultiaddr` + pub fn new(vec: Vec) -> Self { + OpaqueMultiaddr(vec) + } +} + +/// Opaque timestamp type +#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default, RuntimeDebug, PassByInner, Encode, Decode)] +pub struct Timestamp(u64); + +/// Duration type +#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default, RuntimeDebug, PassByInner, Encode, Decode)] +pub struct Duration(u64); + +impl Duration { + /// Create new duration representing given number of milliseconds. + pub const fn from_millis(millis: u64) -> Self { + Duration(millis) + } + + /// Returns number of milliseconds this Duration represents. + pub fn millis(&self) -> u64 { + self.0 + } +} + +impl Timestamp { + /// Creates new `Timestamp` given unix timestamp in milliseconds. + pub fn from_unix_millis(millis: u64) -> Self { + Timestamp(millis) + } + + /// Increase the timestamp by given `Duration`. + pub fn add(&self, duration: Duration) -> Timestamp { + Timestamp(self.0.saturating_add(duration.0)) + } + + /// Decrease the timestamp by given `Duration` + pub fn sub(&self, duration: Duration) -> Timestamp { + Timestamp(self.0.saturating_sub(duration.0)) + } + + /// Returns a saturated difference (Duration) between two Timestamps. + pub fn diff(&self, other: &Self) -> Duration { + Duration(self.0.saturating_sub(other.0)) + } + + /// Return number of milliseconds since UNIX epoch. + pub fn unix_millis(&self) -> u64 { + self.0 + } +} + +/// Execution context extra capabilities. +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[repr(u8)] +pub enum Capability { + /// Access to transaction pool. + TransactionPool = 1, + /// External http calls. + Http = 2, + /// Keystore access. + Keystore = 4, + /// Randomness source. + Randomness = 8, + /// Access to opaque network state. + NetworkState = 16, + /// Access to offchain worker DB (read only). + OffchainWorkerDbRead = 32, + /// Access to offchain worker DB (writes). + OffchainWorkerDbWrite = 64, + /// Manage the authorized nodes + NodeAuthorization = 128, +} + +/// A set of capabilities +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub struct Capabilities(u8); + +impl Capabilities { + /// Return an object representing an empty set of capabilities. + pub fn none() -> Self { + Self(0) + } + + /// Return an object representing all capabilities enabled. + pub fn all() -> Self { + Self(u8::max_value()) + } + + /// Return capabilities for rich offchain calls. + /// + /// Those calls should be allowed to sign and submit transactions + /// and access offchain workers database (but read only!). + pub fn rich_offchain_call() -> Self { + [ + Capability::TransactionPool, + Capability::Keystore, + Capability::OffchainWorkerDbRead, + ][..].into() + } + + /// Check if particular capability is enabled. + pub fn has(&self, capability: Capability) -> bool { + self.0 & capability as u8 != 0 + } + + /// Check if this capability object represents all capabilities. + pub fn has_all(&self) -> bool { + self == &Capabilities::all() + } +} + +impl<'a> From<&'a [Capability]> for Capabilities { + fn from(list: &'a [Capability]) -> Self { + Capabilities(list.iter().fold(0_u8, |a, b| a | *b as u8)) + } +} + +/// An extended externalities for offchain workers. +pub trait Externalities: Send { + /// Returns if the local node is a potential validator. + /// + /// Even if this function returns `true`, it does not mean that any keys are configured + /// and that the validator is registered in the chain. + fn is_validator(&self) -> bool; + + /// Returns information about the local node's network state. + fn network_state(&self) -> Result; + + /// Returns current UNIX timestamp (in millis) + fn timestamp(&mut self) -> Timestamp; + + /// Pause the execution until `deadline` is reached. + fn sleep_until(&mut self, deadline: Timestamp); + + /// Returns a random seed. + /// + /// This is a truly random non deterministic seed generated by host environment. + /// Obviously fine in the off-chain worker context. + fn random_seed(&mut self) -> [u8; 32]; + + /// Sets a value in the local storage. + /// + /// Note this storage is not part of the consensus, it's only accessible by + /// offchain worker tasks running on the same machine. It _is_ persisted between runs. + fn local_storage_set(&mut self, kind: StorageKind, key: &[u8], value: &[u8]); + + /// Removes a value in the local storage. + /// + /// Note this storage is not part of the consensus, it's only accessible by + /// offchain worker tasks running on the same machine. It _is_ persisted between runs. + fn local_storage_clear(&mut self, kind: StorageKind, key: &[u8]); + + /// Sets a value in the local storage if it matches current value. + /// + /// Since multiple offchain workers may be running concurrently, to prevent + /// data races use CAS to coordinate between them. + /// + /// Returns `true` if the value has been set, `false` otherwise. + /// + /// Note this storage is not part of the consensus, it's only accessible by + /// offchain worker tasks running on the same machine. It _is_ persisted between runs. + fn local_storage_compare_and_set( + &mut self, + kind: StorageKind, + key: &[u8], + old_value: Option<&[u8]>, + new_value: &[u8], + ) -> bool; + + /// Gets a value from the local storage. + /// + /// If the value does not exist in the storage `None` will be returned. + /// Note this storage is not part of the consensus, it's only accessible by + /// offchain worker tasks running on the same machine. It _is_ persisted between runs. + fn local_storage_get(&mut self, kind: StorageKind, key: &[u8]) -> Option>; + + /// Initiates a http request given HTTP verb and the URL. + /// + /// Meta is a future-reserved field containing additional, parity-scale-codec encoded parameters. + /// Returns the id of newly started request. + /// + /// Returns an error if: + /// - No new request identifier could be allocated. + /// - The method or URI contain invalid characters. + /// + fn http_request_start( + &mut self, + method: &str, + uri: &str, + meta: &[u8] + ) -> Result; + + /// Append header to the request. + /// + /// Calling this function multiple times with the same header name continues appending new + /// headers. In other words, headers are never replaced. + /// + /// Returns an error if: + /// - The request identifier is invalid. + /// - You have called `http_request_write_body` on that request. + /// - The name or value contain invalid characters. + /// + /// An error doesn't poison the request, and you can continue as if the call had never been + /// made. + /// + fn http_request_add_header( + &mut self, + request_id: HttpRequestId, + name: &str, + value: &str + ) -> Result<(), ()>; + + /// Write a chunk of request body. + /// + /// Calling this function with a non-empty slice may or may not start the + /// HTTP request. Calling this function with an empty chunks finalizes the + /// request and always starts it. It is no longer valid to write more data + /// afterwards. + /// Passing `None` as deadline blocks forever. + /// + /// Returns an error if: + /// - The request identifier is invalid. + /// - `http_response_wait` has already been called on this request. + /// - The deadline is reached. + /// - An I/O error has happened, for example the remote has closed our + /// request. The request is then considered invalid. + /// + fn http_request_write_body( + &mut self, + request_id: HttpRequestId, + chunk: &[u8], + deadline: Option + ) -> Result<(), HttpError>; + + /// Block and wait for the responses for given requests. + /// + /// Returns a vector of request statuses (the len is the same as ids). + /// Note that if deadline is not provided the method will block indefinitely, + /// otherwise unready responses will produce `DeadlineReached` status. + /// + /// If a response returns an `IoError`, it is then considered destroyed. + /// Its id is then invalid. + /// + /// Passing `None` as deadline blocks forever. + fn http_response_wait( + &mut self, + ids: &[HttpRequestId], + deadline: Option + ) -> Vec; + + /// Read all response headers. + /// + /// Returns a vector of pairs `(HeaderKey, HeaderValue)`. + /// + /// Dispatches the request if it hasn't been done yet. It is no longer + /// valid to modify the headers or write data to the request. + /// + /// Returns an empty list if the identifier is unknown/invalid, hasn't + /// received a response, or has finished. + fn http_response_headers( + &mut self, + request_id: HttpRequestId + ) -> Vec<(Vec, Vec)>; + + /// Read a chunk of body response to given buffer. + /// + /// Dispatches the request if it hasn't been done yet. It is no longer + /// valid to modify the headers or write data to the request. + /// + /// Returns the number of bytes written or an error in case a deadline + /// is reached or server closed the connection. + /// Passing `None` as a deadline blocks forever. + /// + /// If `Ok(0)` or `Err(IoError)` is returned, the request is considered + /// destroyed. Doing another read or getting the response's headers, for + /// example, is then invalid. + /// + /// Returns an error if: + /// - The request identifier is invalid. + /// - The deadline is reached. + /// - An I/O error has happened, for example the remote has closed our + /// request. The request is then considered invalid. + /// + fn http_response_read_body( + &mut self, + request_id: HttpRequestId, + buffer: &mut [u8], + deadline: Option + ) -> Result; + + /// Set the authorized nodes from runtime. + /// + /// In a permissioned network, the connections between nodes need to reach a + /// consensus between participants. + /// + /// - `nodes`: a set of nodes which are allowed to connect for the local node. + /// each one is identified with an `OpaquePeerId`, here it just use plain bytes + /// without any encoding. Invalid `OpaquePeerId`s are silently ignored. + /// - `authorized_only`: if true, only the authorized nodes are allowed to connect, + /// otherwise unauthorized nodes can also be connected through other mechanism. + fn set_authorized_nodes(&mut self, nodes: Vec, authorized_only: bool); +} + +impl Externalities for Box { + fn is_validator(&self) -> bool { + (& **self).is_validator() + } + + fn network_state(&self) -> Result { + (& **self).network_state() + } + + fn timestamp(&mut self) -> Timestamp { + (&mut **self).timestamp() + } + + fn sleep_until(&mut self, deadline: Timestamp) { + (&mut **self).sleep_until(deadline) + } + + fn random_seed(&mut self) -> [u8; 32] { + (&mut **self).random_seed() + } + + fn local_storage_set(&mut self, kind: StorageKind, key: &[u8], value: &[u8]) { + (&mut **self).local_storage_set(kind, key, value) + } + + fn local_storage_clear(&mut self, kind: StorageKind, key: &[u8]) { + (&mut **self).local_storage_clear(kind, key) + } + + fn local_storage_compare_and_set( + &mut self, + kind: StorageKind, + key: &[u8], + old_value: Option<&[u8]>, + new_value: &[u8], + ) -> bool { + (&mut **self).local_storage_compare_and_set(kind, key, old_value, new_value) + } + + fn local_storage_get(&mut self, kind: StorageKind, key: &[u8]) -> Option> { + (&mut **self).local_storage_get(kind, key) + } + + fn http_request_start(&mut self, method: &str, uri: &str, meta: &[u8]) -> Result { + (&mut **self).http_request_start(method, uri, meta) + } + + fn http_request_add_header(&mut self, request_id: HttpRequestId, name: &str, value: &str) -> Result<(), ()> { + (&mut **self).http_request_add_header(request_id, name, value) + } + + fn http_request_write_body( + &mut self, + request_id: HttpRequestId, + chunk: &[u8], + deadline: Option + ) -> Result<(), HttpError> { + (&mut **self).http_request_write_body(request_id, chunk, deadline) + } + + fn http_response_wait(&mut self, ids: &[HttpRequestId], deadline: Option) -> Vec { + (&mut **self).http_response_wait(ids, deadline) + } + + fn http_response_headers(&mut self, request_id: HttpRequestId) -> Vec<(Vec, Vec)> { + (&mut **self).http_response_headers(request_id) + } + + fn http_response_read_body( + &mut self, + request_id: HttpRequestId, + buffer: &mut [u8], + deadline: Option + ) -> Result { + (&mut **self).http_response_read_body(request_id, buffer, deadline) + } + + fn set_authorized_nodes(&mut self, nodes: Vec, authorized_only: bool) { + (&mut **self).set_authorized_nodes(nodes, authorized_only) + } +} + +/// An `OffchainExternalities` implementation with limited capabilities. +pub struct LimitedExternalities { + capabilities: Capabilities, + externalities: T, +} + +impl LimitedExternalities { + /// Create new externalities limited to given `capabilities`. + pub fn new(capabilities: Capabilities, externalities: T) -> Self { + Self { + capabilities, + externalities, + } + } + + /// Check if given capability is allowed. + /// + /// Panics in case it is not. + fn check(&self, capability: Capability, name: &'static str) { + if !self.capabilities.has(capability) { + panic!("Accessing a forbidden API: {}. No: {:?} capability.", name, capability); + } + } +} + +impl Externalities for LimitedExternalities { + fn is_validator(&self) -> bool { + self.check(Capability::Keystore, "is_validator"); + self.externalities.is_validator() + } + + fn network_state(&self) -> Result { + self.check(Capability::NetworkState, "network_state"); + self.externalities.network_state() + } + + fn timestamp(&mut self) -> Timestamp { + self.check(Capability::Http, "timestamp"); + self.externalities.timestamp() + } + + fn sleep_until(&mut self, deadline: Timestamp) { + self.check(Capability::Http, "sleep_until"); + self.externalities.sleep_until(deadline) + } + + fn random_seed(&mut self) -> [u8; 32] { + self.check(Capability::Randomness, "random_seed"); + self.externalities.random_seed() + } + + fn local_storage_set(&mut self, kind: StorageKind, key: &[u8], value: &[u8]) { + self.check(Capability::OffchainWorkerDbWrite, "local_storage_set"); + self.externalities.local_storage_set(kind, key, value) + } + + fn local_storage_clear(&mut self, kind: StorageKind, key: &[u8]) { + self.check(Capability::OffchainWorkerDbWrite, "local_storage_clear"); + self.externalities.local_storage_clear(kind, key) + } + + fn local_storage_compare_and_set( + &mut self, + kind: StorageKind, + key: &[u8], + old_value: Option<&[u8]>, + new_value: &[u8], + ) -> bool { + self.check(Capability::OffchainWorkerDbWrite, "local_storage_compare_and_set"); + self.externalities.local_storage_compare_and_set(kind, key, old_value, new_value) + } + + fn local_storage_get(&mut self, kind: StorageKind, key: &[u8]) -> Option> { + self.check(Capability::OffchainWorkerDbRead, "local_storage_get"); + self.externalities.local_storage_get(kind, key) + } + + fn http_request_start(&mut self, method: &str, uri: &str, meta: &[u8]) -> Result { + self.check(Capability::Http, "http_request_start"); + self.externalities.http_request_start(method, uri, meta) + } + + fn http_request_add_header(&mut self, request_id: HttpRequestId, name: &str, value: &str) -> Result<(), ()> { + self.check(Capability::Http, "http_request_add_header"); + self.externalities.http_request_add_header(request_id, name, value) + } + + fn http_request_write_body( + &mut self, + request_id: HttpRequestId, + chunk: &[u8], + deadline: Option + ) -> Result<(), HttpError> { + self.check(Capability::Http, "http_request_write_body"); + self.externalities.http_request_write_body(request_id, chunk, deadline) + } + + fn http_response_wait(&mut self, ids: &[HttpRequestId], deadline: Option) -> Vec { + self.check(Capability::Http, "http_response_wait"); + self.externalities.http_response_wait(ids, deadline) + } + + fn http_response_headers(&mut self, request_id: HttpRequestId) -> Vec<(Vec, Vec)> { + self.check(Capability::Http, "http_response_headers"); + self.externalities.http_response_headers(request_id) + } + + fn http_response_read_body( + &mut self, + request_id: HttpRequestId, + buffer: &mut [u8], + deadline: Option + ) -> Result { + self.check(Capability::Http, "http_response_read_body"); + self.externalities.http_response_read_body(request_id, buffer, deadline) + } + + fn set_authorized_nodes(&mut self, nodes: Vec, authorized_only: bool) { + self.check(Capability::NodeAuthorization, "set_authorized_nodes"); + self.externalities.set_authorized_nodes(nodes, authorized_only) + } +} + +#[cfg(feature = "std")] +sp_externalities::decl_extension! { + /// The offchain extension that will be registered at the Substrate externalities. + pub struct OffchainExt(Box); +} + +#[cfg(feature = "std")] +impl OffchainExt { + /// Create a new instance of `Self`. + pub fn new(offchain: O) -> Self { + Self(Box::new(offchain)) + } +} + +/// Abstraction over transaction pool. +/// +/// This trait is currently used within the `ExternalitiesExtension` +/// to provide offchain calls with access to the transaction pool without +/// tight coupling with any pool implementation. +#[cfg(feature = "std")] +pub trait TransactionPool { + /// Submit transaction. + /// + /// The transaction will end up in the pool and be propagated to others. + fn submit_transaction(&mut self, extrinsic: Vec) -> Result<(), ()>; +} + +#[cfg(feature = "std")] +sp_externalities::decl_extension! { + /// An externalities extension to submit transactions to the pool. + pub struct TransactionPoolExt(Box); +} + +#[cfg(feature = "std")] +impl TransactionPoolExt { + /// Create a new instance of `TransactionPoolExt`. + pub fn new(pool: O) -> Self { + Self(Box::new(pool)) + } +} + + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn timestamp_ops() { + let t = Timestamp(5); + assert_eq!(t.add(Duration::from_millis(10)), Timestamp(15)); + assert_eq!(t.sub(Duration::from_millis(10)), Timestamp(0)); + assert_eq!(t.diff(&Timestamp(3)), Duration(2)); + } + + #[test] + fn capabilities() { + let none = Capabilities::none(); + let all = Capabilities::all(); + let some = Capabilities::from(&[Capability::Keystore, Capability::Randomness][..]); + + assert!(!none.has(Capability::Keystore)); + assert!(all.has(Capability::Keystore)); + assert!(some.has(Capability::Keystore)); + assert!(!none.has(Capability::TransactionPool)); + assert!(all.has(Capability::TransactionPool)); + assert!(!some.has(Capability::TransactionPool)); + } +} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/storage.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/storage.rs new file mode 100644 index 00000000..7d7c711e --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/storage.rs @@ -0,0 +1,297 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! In-memory implementation of offchain workers database. + +use std::collections::hash_map::{HashMap, Entry}; +use crate::offchain::OffchainStorage; +use std::iter::Iterator; + +/// In-memory storage for offchain workers. +#[derive(Debug, Clone, Default)] +pub struct InMemOffchainStorage { + storage: HashMap, Vec>, +} + +impl InMemOffchainStorage { + /// Consume the offchain storage and iterate over all key value pairs. + pub fn into_iter(self) -> impl Iterator,Vec)> { + self.storage.into_iter() + } + + /// Iterate over all key value pairs by reference. + pub fn iter<'a>(&'a self) -> impl Iterator,&'a Vec)> { + self.storage.iter() + } + + /// Remove a key and its associated value from the offchain database. + pub fn remove(&mut self, prefix: &[u8], key: &[u8]) { + let key: Vec = prefix.iter().chain(key).cloned().collect(); + let _ = self.storage.remove(&key); + } +} + +impl OffchainStorage for InMemOffchainStorage { + fn set(&mut self, prefix: &[u8], key: &[u8], value: &[u8]) { + let key = prefix.iter().chain(key).cloned().collect(); + self.storage.insert(key, value.to_vec()); + } + + fn remove(&mut self, prefix: &[u8], key: &[u8]) { + let key: Vec = prefix.iter().chain(key).cloned().collect(); + self.storage.remove(&key); + } + + fn get(&self, prefix: &[u8], key: &[u8]) -> Option> { + let key: Vec = prefix.iter().chain(key).cloned().collect(); + self.storage.get(&key).cloned() + } + + fn compare_and_set( + &mut self, + prefix: &[u8], + key: &[u8], + old_value: Option<&[u8]>, + new_value: &[u8], + ) -> bool { + let key = prefix.iter().chain(key).cloned().collect(); + + match self.storage.entry(key) { + Entry::Vacant(entry) => if old_value.is_none() { + entry.insert(new_value.to_vec()); + true + } else { false }, + Entry::Occupied(ref mut entry) if Some(entry.get().as_slice()) == old_value => { + entry.insert(new_value.to_vec()); + true + }, + _ => false, + } + } +} + + + + +/// Change to be applied to the offchain worker db in regards to a key. +#[derive(Debug,Clone,Hash,Eq,PartialEq)] +pub enum OffchainOverlayedChange { + /// Remove the data associated with the key + Remove, + /// Overwrite the value of an associated key + SetValue(Vec), +} + +/// In-memory storage for offchain workers recoding changes for the actual offchain storage implementation. +#[derive(Debug, Clone)] +pub enum OffchainOverlayedChanges { + /// Writing overlay changes to the offchain worker database is disabled by configuration. + Disabled, + /// Overlay changes can be recorded using the inner collection of this variant, + /// where the identifier is the tuple of `(prefix, key)`. + Enabled(HashMap<(Vec, Vec), OffchainOverlayedChange>), +} + +impl Default for OffchainOverlayedChanges { + fn default() -> Self { + Self::Disabled + } +} + +impl OffchainOverlayedChanges { + /// Create the disabled variant. + pub fn disabled() -> Self { + Self::Disabled + } + + /// Create the enabled variant. + pub fn enabled() -> Self { + Self::Enabled(HashMap::new()) + } + + /// Consume the offchain storage and iterate over all key value pairs. + pub fn into_iter(self) -> OffchainOverlayedChangesIntoIter { + OffchainOverlayedChangesIntoIter::new(self) + } + + /// Iterate over all key value pairs by reference. + pub fn iter<'a>(&'a self) -> OffchainOverlayedChangesIter { + OffchainOverlayedChangesIter::new(&self) + } + + /// Drain all elements of changeset. + pub fn drain<'a, 'd>(&'a mut self) -> OffchainOverlayedChangesDrain<'d> where 'a: 'd { + OffchainOverlayedChangesDrain::new(self) + } + + /// Remove a key and its associated value from the offchain database. + pub fn remove(&mut self, prefix: &[u8], key: &[u8]) { + if let Self::Enabled(ref mut storage) = self { + let _ = storage.insert((prefix.to_vec(), key.to_vec()), OffchainOverlayedChange::Remove); + } + } + + /// Set the value associated with a key under a prefix to the value provided. + pub fn set(&mut self, prefix: &[u8], key: &[u8], value: &[u8]) { + if let Self::Enabled(ref mut storage) = self { + let _ = storage.insert((prefix.to_vec(), key.to_vec()), OffchainOverlayedChange::SetValue(value.to_vec())); + } + } + + /// Obtain a associated value to the given key in storage with prefix. + pub fn get(&self, prefix: &[u8], key: &[u8]) -> Option { + if let Self::Enabled(ref storage) = self { + let key = (prefix.to_vec(), key.to_vec()); + storage.get(&key).cloned() + } else { + None + } + } +} + +use std::collections::hash_map; + +/// Iterate by reference over the prepared offchain worker storage changes. +pub struct OffchainOverlayedChangesIter<'i> { + inner: Option, Vec), OffchainOverlayedChange>>, +} + +impl<'i> Iterator for OffchainOverlayedChangesIter<'i> { + type Item = (&'i (Vec, Vec), &'i OffchainOverlayedChange); + fn next(&mut self) -> Option { + if let Some(ref mut iter) = self.inner { + iter.next() + } else { + None + } + } +} + +impl<'i> OffchainOverlayedChangesIter<'i> { + /// Create a new iterator based on a refernce to the parent container. + pub fn new(container: &'i OffchainOverlayedChanges) -> Self { + match container { + OffchainOverlayedChanges::Enabled(inner) => Self { + inner: Some(inner.iter()) + }, + OffchainOverlayedChanges::Disabled => Self { inner: None, }, + } + } +} + + +/// Iterate by value over the prepared offchain worker storage changes. +pub struct OffchainOverlayedChangesIntoIter { + inner: Option,Vec),OffchainOverlayedChange>>, +} + +impl Iterator for OffchainOverlayedChangesIntoIter { + type Item = ((Vec, Vec), OffchainOverlayedChange); + fn next(&mut self) -> Option { + if let Some(ref mut iter) = self.inner { + iter.next() + } else { + None + } + } +} + +impl OffchainOverlayedChangesIntoIter { + /// Create a new iterator by consuming the collection. + pub fn new(container: OffchainOverlayedChanges) -> Self { + match container { + OffchainOverlayedChanges::Enabled(inner) => Self { + inner: Some(inner.into_iter()) + }, + OffchainOverlayedChanges::Disabled => Self { inner: None, }, + } + } +} + +/// Iterate over all items while draining them from the collection. +pub struct OffchainOverlayedChangesDrain<'d> { + inner: Option, Vec), OffchainOverlayedChange>>, +} + +impl<'d> Iterator for OffchainOverlayedChangesDrain<'d> { + type Item = ((Vec, Vec), OffchainOverlayedChange); + fn next(&mut self) -> Option { + if let Some(ref mut iter) = self.inner { + iter.next() + } else { + None + } + } +} + +impl<'d> OffchainOverlayedChangesDrain<'d> { + /// Create a new iterator by taking a mut reference to the collection, + /// for the lifetime of the created drain iterator. + pub fn new(container: &'d mut OffchainOverlayedChanges) -> Self { + match container { + OffchainOverlayedChanges::Enabled(ref mut inner) => Self { + inner: Some(inner.drain()) + }, + OffchainOverlayedChanges::Disabled => Self { inner: None, }, + } + } +} + + +#[cfg(test)] +mod test { + use super::*; + use super::super::STORAGE_PREFIX; + + #[test] + fn test_drain() { + let mut ooc = OffchainOverlayedChanges::enabled(); + ooc.set(STORAGE_PREFIX,b"kkk", b"vvv"); + let drained = ooc.drain().count(); + assert_eq!(drained, 1); + let leftover = ooc.iter().count(); + assert_eq!(leftover, 0); + + ooc.set(STORAGE_PREFIX, b"a", b"v"); + ooc.set(STORAGE_PREFIX, b"b", b"v"); + ooc.set(STORAGE_PREFIX, b"c", b"v"); + ooc.set(STORAGE_PREFIX, b"d", b"v"); + ooc.set(STORAGE_PREFIX, b"e", b"v"); + assert_eq!(ooc.iter().count(), 5); + } + + #[test] + fn test_accumulated_set_remove_set() { + let mut ooc = OffchainOverlayedChanges::enabled(); + ooc.set(STORAGE_PREFIX, b"ppp", b"qqq"); + ooc.remove(STORAGE_PREFIX, b"ppp"); + // keys are equiv, so it will overwrite the value and the overlay will contain + // one item + assert_eq!(ooc.iter().count(), 1); + + ooc.set(STORAGE_PREFIX, b"ppp", b"rrr"); + let mut iter = ooc.into_iter(); + assert_eq!( + iter.next(), + Some( + ((STORAGE_PREFIX.to_vec(), b"ppp".to_vec()), + OffchainOverlayedChange::SetValue(b"rrr".to_vec())) + ) + ); + assert_eq!(iter.next(), None); + } +} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/testing.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/testing.rs new file mode 100644 index 00000000..3fe34cc0 --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/testing.rs @@ -0,0 +1,418 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Utilities for offchain calls testing. +//! +//! Namely all ExecutionExtensions that allow mocking +//! the extra APIs. + +use std::{ + collections::{BTreeMap, VecDeque}, + sync::Arc, +}; +use crate::OpaquePeerId; +use crate::offchain::{ + self, + storage::{InMemOffchainStorage, OffchainOverlayedChange, OffchainOverlayedChanges}, + HttpError, + HttpRequestId as RequestId, + HttpRequestStatus as RequestStatus, + Timestamp, + StorageKind, + OpaqueNetworkState, + TransactionPool, + OffchainStorage, +}; + +use parking_lot::RwLock; + +/// Pending request. +#[derive(Debug, Default, PartialEq, Eq)] +pub struct PendingRequest { + /// HTTP method + pub method: String, + /// URI + pub uri: String, + /// Encoded Metadata + pub meta: Vec, + /// Request headers + pub headers: Vec<(String, String)>, + /// Request body + pub body: Vec, + /// Has the request been sent already. + pub sent: bool, + /// Response body + pub response: Option>, + /// Number of bytes already read from the response body. + pub read: usize, + /// Response headers + pub response_headers: Vec<(String, String)>, +} + +/// Sharable "persistent" offchain storage for test. +#[derive(Debug, Clone, Default)] +pub struct TestPersistentOffchainDB { + persistent: Arc>, +} + +impl TestPersistentOffchainDB { + /// Create a new and empty offchain storage db for persistent items + pub fn new() -> Self { + Self { + persistent: Arc::new(RwLock::new(InMemOffchainStorage::default())) + } + } + + /// Apply a set of off-chain changes directly to the test backend + pub fn apply_offchain_changes(&mut self, changes: &mut OffchainOverlayedChanges) { + let mut me = self.persistent.write(); + for ((_prefix, key), value_operation) in changes.drain() { + match value_operation { + OffchainOverlayedChange::SetValue(val) => me.set(b"", key.as_slice(), val.as_slice()), + OffchainOverlayedChange::Remove => me.remove(b"", key.as_slice()), + } + } + } +} + +impl OffchainStorage for TestPersistentOffchainDB { + fn set(&mut self, prefix: &[u8], key: &[u8], value: &[u8]) { + self.persistent.write().set(prefix, key, value); + } + + fn remove(&mut self, prefix: &[u8], key: &[u8]) { + self.persistent.write().remove(prefix, key); + } + + fn get(&self, prefix: &[u8], key: &[u8]) -> Option> { + self.persistent.read().get(prefix, key) + } + + fn compare_and_set( + &mut self, + prefix: &[u8], + key: &[u8], + old_value: Option<&[u8]>, + new_value: &[u8], + ) -> bool { + self.persistent.write().compare_and_set(prefix, key, old_value, new_value) + } +} + + +/// Internal state of the externalities. +/// +/// This can be used in tests to respond or assert stuff about interactions. +#[derive(Debug, Default)] +pub struct OffchainState { + /// A list of pending requests. + pub requests: BTreeMap, + // Queue of requests that the test is expected to perform (in order). + expected_requests: VecDeque, + /// Persistent local storage + pub persistent_storage: TestPersistentOffchainDB, + /// Local storage + pub local_storage: InMemOffchainStorage, + /// A supposedly random seed. + pub seed: [u8; 32], + /// A timestamp simulating the current time. + pub timestamp: Timestamp, +} + +impl OffchainState { + /// Asserts that pending request has been submitted and fills it's response. + pub fn fulfill_pending_request( + &mut self, + id: u16, + expected: PendingRequest, + response: impl Into>, + response_headers: impl IntoIterator, + ) { + match self.requests.get_mut(&RequestId(id)) { + None => { + panic!("Missing pending request: {:?}.\n\nAll: {:?}", id, self.requests); + } + Some(req) => { + assert_eq!( + *req, + expected, + ); + req.response = Some(response.into()); + req.response_headers = response_headers.into_iter().collect(); + } + } + } + + fn fulfill_expected(&mut self, id: u16) { + if let Some(mut req) = self.expected_requests.pop_back() { + let response = req.response.take().expect("Response checked when added."); + let headers = std::mem::take(&mut req.response_headers); + self.fulfill_pending_request(id, req, response, headers); + } + } + + /// Add expected HTTP request. + /// + /// This method can be used to initialize expected HTTP requests and their responses + /// before running the actual code that utilizes them (for instance before calling into runtime). + /// Expected request has to be fulfilled before this struct is dropped, + /// the `response` and `response_headers` fields will be used to return results to the callers. + /// Requests are expected to be performed in the insertion order. + pub fn expect_request(&mut self, expected: PendingRequest) { + if expected.response.is_none() { + panic!("Expected request needs to have a response."); + } + self.expected_requests.push_front(expected); + } +} + +impl Drop for OffchainState { + fn drop(&mut self) { + // If we panic! while we are already in a panic, the test dies with an illegal instruction. + if !self.expected_requests.is_empty() && !std::thread::panicking() { + panic!("Unfulfilled expected requests: {:?}", self.expected_requests); + } + } +} + +/// Implementation of offchain externalities used for tests. +#[derive(Clone, Default, Debug)] +pub struct TestOffchainExt(pub Arc>); + +impl TestOffchainExt { + /// Create new `TestOffchainExt` and a reference to the internal state. + pub fn new() -> (Self, Arc>) { + let ext = Self::default(); + let state = ext.0.clone(); + (ext, state) + } + + /// Create new `TestOffchainExt` and a reference to the internal state. + pub fn with_offchain_db(offchain_db: TestPersistentOffchainDB) -> (Self, Arc>) { + let (ext, state) = Self::new(); + ext.0.write().persistent_storage = offchain_db; + (ext, state) + } +} + +impl offchain::Externalities for TestOffchainExt { + fn is_validator(&self) -> bool { + true + } + + fn network_state(&self) -> Result { + Ok(OpaqueNetworkState { + peer_id: Default::default(), + external_addresses: vec![], + }) + } + + fn timestamp(&mut self) -> Timestamp { + self.0.read().timestamp + } + + fn sleep_until(&mut self, deadline: Timestamp) { + self.0.write().timestamp = deadline; + } + + fn random_seed(&mut self) -> [u8; 32] { + self.0.read().seed + } + + fn local_storage_set(&mut self, kind: StorageKind, key: &[u8], value: &[u8]) { + let mut state = self.0.write(); + match kind { + StorageKind::LOCAL => state.local_storage.set(b"", key, value), + StorageKind::PERSISTENT => state.persistent_storage.set(b"", key, value), + }; + } + + fn local_storage_clear(&mut self, kind: StorageKind, key: &[u8]) { + let mut state = self.0.write(); + match kind { + StorageKind::LOCAL => state.local_storage.remove(b"", key), + StorageKind::PERSISTENT => state.persistent_storage.remove(b"", key), + }; + } + + fn local_storage_compare_and_set( + &mut self, + kind: StorageKind, + key: &[u8], + old_value: Option<&[u8]>, + new_value: &[u8] + ) -> bool { + let mut state = self.0.write(); + match kind { + StorageKind::LOCAL => state.local_storage.compare_and_set(b"", key, old_value, new_value), + StorageKind::PERSISTENT => state.persistent_storage.compare_and_set(b"", key, old_value, new_value), + } + } + + fn local_storage_get(&mut self, kind: StorageKind, key: &[u8]) -> Option> { + let state = self.0.read(); + match kind { + StorageKind::LOCAL => state.local_storage.get(b"", key), + StorageKind::PERSISTENT => state.persistent_storage.get(b"", key), + } + } + + fn http_request_start(&mut self, method: &str, uri: &str, meta: &[u8]) -> Result { + let mut state = self.0.write(); + let id = RequestId(state.requests.len() as u16); + state.requests.insert(id.clone(), PendingRequest { + method: method.into(), + uri: uri.into(), + meta: meta.into(), + ..Default::default() + }); + Ok(id) + } + + fn http_request_add_header( + &mut self, + request_id: RequestId, + name: &str, + value: &str, + ) -> Result<(), ()> { + let mut state = self.0.write(); + if let Some(req) = state.requests.get_mut(&request_id) { + req.headers.push((name.into(), value.into())); + Ok(()) + } else { + Err(()) + } + } + + fn http_request_write_body( + &mut self, + request_id: RequestId, + chunk: &[u8], + _deadline: Option + ) -> Result<(), HttpError> { + let mut state = self.0.write(); + + let sent = { + let req = state.requests.get_mut(&request_id).ok_or(HttpError::IoError)?; + req.body.extend(chunk); + if chunk.is_empty() { + req.sent = true; + } + req.sent + }; + + if sent { + state.fulfill_expected(request_id.0); + } + + Ok(()) + } + + fn http_response_wait( + &mut self, + ids: &[RequestId], + _deadline: Option, + ) -> Vec { + let state = self.0.read(); + + ids.iter().map(|id| match state.requests.get(id) { + Some(req) if req.response.is_none() => + panic!("No `response` provided for request with id: {:?}", id), + None => RequestStatus::Invalid, + _ => RequestStatus::Finished(200), + }).collect() + } + + fn http_response_headers(&mut self, request_id: RequestId) -> Vec<(Vec, Vec)> { + let state = self.0.read(); + if let Some(req) = state.requests.get(&request_id) { + req.response_headers + .clone() + .into_iter() + .map(|(k, v)| (k.into_bytes(), v.into_bytes())) + .collect() + } else { + Default::default() + } + } + + fn http_response_read_body( + &mut self, + request_id: RequestId, + buffer: &mut [u8], + _deadline: Option + ) -> Result { + let mut state = self.0.write(); + if let Some(req) = state.requests.get_mut(&request_id) { + let response = req.response + .as_mut() + .unwrap_or_else(|| panic!("No response provided for request: {:?}", request_id)); + + if req.read >= response.len() { + // Remove the pending request as per spec. + state.requests.remove(&request_id); + Ok(0) + } else { + let read = std::cmp::min(buffer.len(), response[req.read..].len()); + buffer[0..read].copy_from_slice(&response[req.read..read]); + req.read += read; + Ok(read) + } + } else { + Err(HttpError::IoError) + } + } + + fn set_authorized_nodes(&mut self, _nodes: Vec, _authorized_only: bool) { + unimplemented!() + } +} + +/// The internal state of the fake transaction pool. +#[derive(Default)] +pub struct PoolState { + /// A vector of transactions submitted from the runtime. + pub transactions: Vec>, +} + +/// Implementation of transaction pool used for test. +/// +/// Note that this implementation does not verify correctness +/// of sent extrinsics. It's meant to be used in contexts +/// where an actual runtime is not known. +/// +/// It's advised to write integration tests that include the +/// actual transaction pool to make sure the produced +/// transactions are valid. +#[derive(Default)] +pub struct TestTransactionPoolExt(Arc>); + +impl TestTransactionPoolExt { + /// Create new `TestTransactionPoolExt` and a reference to the internal state. + pub fn new() -> (Self, Arc>) { + let ext = Self::default(); + let state = ext.0.clone(); + (ext, state) + } +} + +impl TransactionPool for TestTransactionPoolExt { + fn submit_transaction(&mut self, extrinsic: Vec) -> Result<(), ()> { + self.0.write().transactions.push(extrinsic); + Ok(()) + } +} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/sandbox.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/sandbox.rs new file mode 100644 index 00000000..4cb5bd41 --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/sandbox.rs @@ -0,0 +1,128 @@ +// This file is part of Substrate. + +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Definition of a sandbox environment. + +use codec::{Encode, Decode}; +use sp_std::vec::Vec; + +/// Error error that can be returned from host function. +#[derive(Encode, Decode)] +#[derive(crate::RuntimeDebug)] +pub struct HostError; + +/// Describes an entity to define or import into the environment. +#[derive(Clone, PartialEq, Eq, Encode, Decode)] +#[derive(crate::RuntimeDebug)] +pub enum ExternEntity { + /// Function that is specified by an index in a default table of + /// a module that creates the sandbox. + #[codec(index = "1")] + Function(u32), + + /// Linear memory that is specified by some identifier returned by sandbox + /// module upon creation new sandboxed memory. + #[codec(index = "2")] + Memory(u32), +} + +/// An entry in a environment definition table. +/// +/// Each entry has a two-level name and description of an entity +/// being defined. +#[derive(Clone, PartialEq, Eq, Encode, Decode)] +#[derive(crate::RuntimeDebug)] +pub struct Entry { + /// Module name of which corresponding entity being defined. + pub module_name: Vec, + /// Field name in which corresponding entity being defined. + pub field_name: Vec, + /// External entity being defined. + pub entity: ExternEntity, +} + +/// Definition of runtime that could be used by sandboxed code. +#[derive(Clone, PartialEq, Eq, Encode, Decode)] +#[derive(crate::RuntimeDebug)] +pub struct EnvironmentDefinition { + /// Vector of all entries in the environment definition. + pub entries: Vec, +} + +/// Constant for specifying no limit when creating a sandboxed +/// memory instance. For FFI purposes. +pub const MEM_UNLIMITED: u32 = -1i32 as u32; + +/// No error happened. +/// +/// For FFI purposes. +pub const ERR_OK: u32 = 0; + +/// Validation or instantiation error occurred when creating new +/// sandboxed module instance. +/// +/// For FFI purposes. +pub const ERR_MODULE: u32 = -1i32 as u32; + +/// Out-of-bounds access attempted with memory or table. +/// +/// For FFI purposes. +pub const ERR_OUT_OF_BOUNDS: u32 = -2i32 as u32; + +/// Execution error occurred (typically trap). +/// +/// For FFI purposes. +pub const ERR_EXECUTION: u32 = -3i32 as u32; + +#[cfg(test)] +mod tests { + use super::*; + use std::fmt; + use codec::Codec; + + fn roundtrip(s: S) { + let encoded = s.encode(); + assert_eq!(S::decode(&mut &encoded[..]).unwrap(), s); + } + + #[test] + fn env_def_roundtrip() { + roundtrip(EnvironmentDefinition { + entries: vec![], + }); + + roundtrip(EnvironmentDefinition { + entries: vec![ + Entry { + module_name: b"kernel"[..].into(), + field_name: b"memory"[..].into(), + entity: ExternEntity::Memory(1337), + }, + ], + }); + + roundtrip(EnvironmentDefinition { + entries: vec![ + Entry { + module_name: b"env"[..].into(), + field_name: b"abort"[..].into(), + entity: ExternEntity::Function(228), + }, + ], + }); + } +} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/sr25519.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/sr25519.rs new file mode 100644 index 00000000..9a757c89 --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/sr25519.rs @@ -0,0 +1,889 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// tag::description[] +//! Simple sr25519 (Schnorr-Ristretto) API. +//! +//! Note: `CHAIN_CODE_LENGTH` must be equal to `crate::crypto::JUNCTION_ID_LEN` +//! for this to work. +// end::description[] +#[cfg(feature = "full_crypto")] +use sp_std::vec::Vec; +#[cfg(feature = "full_crypto")] +use schnorrkel::{signing_context, ExpansionMode, Keypair, SecretKey, MiniSecretKey, PublicKey, + derive::{Derivation, ChainCode, CHAIN_CODE_LENGTH} +}; +#[cfg(feature = "std")] +use std::convert::TryFrom; +#[cfg(feature = "std")] +use substrate_bip39::mini_secret_from_entropy; +#[cfg(feature = "std")] +use bip39::{Mnemonic, Language, MnemonicType}; +#[cfg(feature = "full_crypto")] +use crate::crypto::{ + Pair as TraitPair, DeriveJunction, Infallible, SecretStringError +}; +#[cfg(feature = "std")] +use crate::crypto::Ss58Codec; + +use crate::crypto::{Public as TraitPublic, CryptoTypePublicPair, UncheckedFrom, CryptoType, Derive, CryptoTypeId}; +use crate::hash::{H256, H512}; +use codec::{Encode, Decode}; +use sp_std::ops::Deref; + +#[cfg(feature = "std")] +use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; +#[cfg(feature = "full_crypto")] +use schnorrkel::keys::{MINI_SECRET_KEY_LENGTH, SECRET_KEY_LENGTH}; +use sp_runtime_interface::pass_by::PassByInner; + +// signing context +#[cfg(feature = "full_crypto")] +const SIGNING_CTX: &[u8] = b"substrate"; + +/// An identifier used to match public keys against sr25519 keys +pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"sr25"); + +/// An Schnorrkel/Ristretto x25519 ("sr25519") public key. +#[cfg_attr(feature = "full_crypto", derive(Hash))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Encode, Decode, Default, PassByInner)] +pub struct Public(pub [u8; 32]); + +/// An Schnorrkel/Ristretto x25519 ("sr25519") key pair. +#[cfg(feature = "full_crypto")] +pub struct Pair(Keypair); + +#[cfg(feature = "full_crypto")] +impl Clone for Pair { + fn clone(&self) -> Self { + Pair(schnorrkel::Keypair { + public: self.0.public, + secret: schnorrkel::SecretKey::from_bytes(&self.0.secret.to_bytes()[..]) + .expect("key is always the correct size; qed") + }) + } +} + +impl AsRef<[u8; 32]> for Public { + fn as_ref(&self) -> &[u8; 32] { + &self.0 + } +} + +impl AsRef<[u8]> for Public { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl AsMut<[u8]> for Public { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0[..] + } +} + +impl Deref for Public { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for [u8; 32] { + fn from(x: Public) -> [u8; 32] { + x.0 + } +} + +impl From for H256 { + fn from(x: Public) -> H256 { + x.0.into() + } +} + +#[cfg(feature = "std")] +impl std::str::FromStr for Public { + type Err = crate::crypto::PublicError; + + fn from_str(s: &str) -> Result { + Self::from_ss58check(s) + } +} + +impl sp_std::convert::TryFrom<&[u8]> for Public { + type Error = (); + + fn try_from(data: &[u8]) -> Result { + if data.len() == 32 { + let mut inner = [0u8; 32]; + inner.copy_from_slice(data); + Ok(Public(inner)) + } else { + Err(()) + } + } +} + +impl UncheckedFrom<[u8; 32]> for Public { + fn unchecked_from(x: [u8; 32]) -> Self { + Public::from_raw(x) + } +} + +impl UncheckedFrom for Public { + fn unchecked_from(x: H256) -> Self { + Public::from_h256(x) + } +} + +#[cfg(feature = "std")] +impl std::fmt::Display for Public { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_ss58check()) + } +} + +impl sp_std::fmt::Debug for Public { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + let s = self.to_ss58check(); + write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } +} + +#[cfg(feature = "std")] +impl Serialize for Public { + fn serialize(&self, serializer: S) -> Result where S: Serializer { + serializer.serialize_str(&self.to_ss58check()) + } +} + +#[cfg(feature = "std")] +impl<'de> Deserialize<'de> for Public { + fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { + Public::from_ss58check(&String::deserialize(deserializer)?) + .map_err(|e| de::Error::custom(format!("{:?}", e))) + } +} + +/// An Schnorrkel/Ristretto x25519 ("sr25519") signature. +/// +/// Instead of importing it for the local module, alias it to be available as a public type +#[derive(Encode, Decode, PassByInner)] +pub struct Signature(pub [u8; 64]); + +impl sp_std::convert::TryFrom<&[u8]> for Signature { + type Error = (); + + fn try_from(data: &[u8]) -> Result { + if data.len() == 64 { + let mut inner = [0u8; 64]; + inner.copy_from_slice(data); + Ok(Signature(inner)) + } else { + Err(()) + } + } +} + +#[cfg(feature = "std")] +impl Serialize for Signature { + fn serialize(&self, serializer: S) -> Result where S: Serializer { + serializer.serialize_str(&hex::encode(self)) + } +} + +#[cfg(feature = "std")] +impl<'de> Deserialize<'de> for Signature { + fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { + let signature_hex = hex::decode(&String::deserialize(deserializer)?) + .map_err(|e| de::Error::custom(format!("{:?}", e)))?; + Ok(Signature::try_from(signature_hex.as_ref()) + .map_err(|e| de::Error::custom(format!("{:?}", e)))?) + } +} + +impl Clone for Signature { + fn clone(&self) -> Self { + let mut r = [0u8; 64]; + r.copy_from_slice(&self.0[..]); + Signature(r) + } +} + +impl Default for Signature { + fn default() -> Self { + Signature([0u8; 64]) + } +} + +impl PartialEq for Signature { + fn eq(&self, b: &Self) -> bool { + self.0[..] == b.0[..] + } +} + +impl Eq for Signature {} + +impl From for [u8; 64] { + fn from(v: Signature) -> [u8; 64] { + v.0 + } +} + +impl From for H512 { + fn from(v: Signature) -> H512 { + H512::from(v.0) + } +} + +impl AsRef<[u8; 64]> for Signature { + fn as_ref(&self) -> &[u8; 64] { + &self.0 + } +} + +impl AsRef<[u8]> for Signature { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl AsMut<[u8]> for Signature { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0[..] + } +} + +#[cfg(feature = "full_crypto")] +impl From for Signature { + fn from(s: schnorrkel::Signature) -> Signature { + Signature(s.to_bytes()) + } +} + +impl sp_std::fmt::Debug for Signature { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0)) + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } +} + +#[cfg(feature = "full_crypto")] +impl sp_std::hash::Hash for Signature { + fn hash(&self, state: &mut H) { + sp_std::hash::Hash::hash(&self.0[..], state); + } +} + +/// A localized signature also contains sender information. +/// NOTE: Encode and Decode traits are supported in ed25519 but not possible for now here. +#[cfg(feature = "std")] +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct LocalizedSignature { + /// The signer of the signature. + pub signer: Public, + /// The signature itself. + pub signature: Signature, +} + +impl Signature { + /// A new instance from the given 64-byte `data`. + /// + /// NOTE: No checking goes on to ensure this is a real signature. Only use + /// it if you are certain that the array actually is a signature, or if you + /// immediately verify the signature. All functions that verify signatures + /// will fail if the `Signature` is not actually a valid signature. + pub fn from_raw(data: [u8; 64]) -> Signature { + Signature(data) + } + + /// A new instance from the given slice that should be 64 bytes long. + /// + /// NOTE: No checking goes on to ensure this is a real signature. Only use it if + /// you are certain that the array actually is a signature. GIGO! + pub fn from_slice(data: &[u8]) -> Self { + let mut r = [0u8; 64]; + r.copy_from_slice(data); + Signature(r) + } + + /// A new instance from an H512. + /// + /// NOTE: No checking goes on to ensure this is a real signature. Only use it if + /// you are certain that the array actually is a signature. GIGO! + pub fn from_h512(v: H512) -> Signature { + Signature(v.into()) + } +} + +impl Derive for Public { + /// Derive a child key from a series of given junctions. + /// + /// `None` if there are any hard junctions in there. + #[cfg(feature = "std")] + fn derive>(&self, path: Iter) -> Option { + let mut acc = PublicKey::from_bytes(self.as_ref()).ok()?; + for j in path { + match j { + DeriveJunction::Soft(cc) => acc = acc.derived_key_simple(ChainCode(cc), &[]).0, + DeriveJunction::Hard(_cc) => return None, + } + } + Some(Self(acc.to_bytes())) + } +} + +impl Public { + /// A new instance from the given 32-byte `data`. + /// + /// NOTE: No checking goes on to ensure this is a real public key. Only use it if + /// you are certain that the array actually is a pubkey. GIGO! + pub fn from_raw(data: [u8; 32]) -> Self { + Public(data) + } + + /// A new instance from an H256. + /// + /// NOTE: No checking goes on to ensure this is a real public key. Only use it if + /// you are certain that the array actually is a pubkey. GIGO! + pub fn from_h256(x: H256) -> Self { + Public(x.into()) + } + + /// Return a slice filled with raw data. + pub fn as_array_ref(&self) -> &[u8; 32] { + self.as_ref() + } +} + +impl TraitPublic for Public { + /// A new instance from the given slice that should be 32 bytes long. + /// + /// NOTE: No checking goes on to ensure this is a real public key. Only use it if + /// you are certain that the array actually is a pubkey. GIGO! + fn from_slice(data: &[u8]) -> Self { + let mut r = [0u8; 32]; + r.copy_from_slice(data); + Public(r) + } + + fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { + CryptoTypePublicPair(CRYPTO_ID, self.to_raw_vec()) + } +} + +impl From for CryptoTypePublicPair { + fn from(key: Public) -> Self { + (&key).into() + } +} + +impl From<&Public> for CryptoTypePublicPair { + fn from(key: &Public) -> Self { + CryptoTypePublicPair(CRYPTO_ID, key.to_raw_vec()) + } +} + +#[cfg(feature = "std")] +impl From for Pair { + fn from(sec: MiniSecretKey) -> Pair { + Pair(sec.expand_to_keypair(ExpansionMode::Ed25519)) + } +} + +#[cfg(feature = "std")] +impl From for Pair { + fn from(sec: SecretKey) -> Pair { + Pair(Keypair::from(sec)) + } +} + +#[cfg(feature = "full_crypto")] +impl From for Pair { + fn from(p: schnorrkel::Keypair) -> Pair { + Pair(p) + } +} + +#[cfg(feature = "full_crypto")] +impl From for schnorrkel::Keypair { + fn from(p: Pair) -> schnorrkel::Keypair { + p.0 + } +} + +#[cfg(feature = "full_crypto")] +impl AsRef for Pair { + fn as_ref(&self) -> &schnorrkel::Keypair { + &self.0 + } +} + +/// Derive a single hard junction. +#[cfg(feature = "full_crypto")] +fn derive_hard_junction(secret: &SecretKey, cc: &[u8; CHAIN_CODE_LENGTH]) -> MiniSecretKey { + secret.hard_derive_mini_secret_key(Some(ChainCode(cc.clone())), b"").0 +} + +/// The raw secret seed, which can be used to recreate the `Pair`. +#[cfg(feature = "full_crypto")] +type Seed = [u8; MINI_SECRET_KEY_LENGTH]; + +#[cfg(feature = "full_crypto")] +impl TraitPair for Pair { + type Public = Public; + type Seed = Seed; + type Signature = Signature; + type DeriveError = Infallible; + + /// Make a new key pair from raw secret seed material. + /// + /// This is generated using schnorrkel's Mini-Secret-Keys. + /// + /// A MiniSecretKey is literally what Ed25519 calls a SecretKey, which is just 32 random bytes. + fn from_seed(seed: &Seed) -> Pair { + Self::from_seed_slice(&seed[..]) + .expect("32 bytes can always build a key; qed") + } + + /// Get the public key. + fn public(&self) -> Public { + let mut pk = [0u8; 32]; + pk.copy_from_slice(&self.0.public.to_bytes()); + Public(pk) + } + + /// Make a new key pair from secret seed material. The slice must be 32 bytes long or it + /// will return `None`. + /// + /// You should never need to use this; generate(), generate_with_phrase(), from_phrase() + fn from_seed_slice(seed: &[u8]) -> Result { + match seed.len() { + MINI_SECRET_KEY_LENGTH => { + Ok(Pair( + MiniSecretKey::from_bytes(seed) + .map_err(|_| SecretStringError::InvalidSeed)? + .expand_to_keypair(ExpansionMode::Ed25519) + )) + } + SECRET_KEY_LENGTH => { + Ok(Pair( + SecretKey::from_bytes(seed) + .map_err(|_| SecretStringError::InvalidSeed)? + .to_keypair() + )) + } + _ => Err(SecretStringError::InvalidSeedLength) + } + } + #[cfg(feature = "std")] + fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) { + let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English); + let phrase = mnemonic.phrase(); + let (pair, seed) = Self::from_phrase(phrase, password) + .expect("All phrases generated by Mnemonic are valid; qed"); + ( + pair, + phrase.to_owned(), + seed, + ) + } + #[cfg(feature = "std")] + fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> { + Mnemonic::from_phrase(phrase, Language::English) + .map_err(|_| SecretStringError::InvalidPhrase) + .map(|m| Self::from_entropy(m.entropy(), password)) + } + + fn derive>(&self, + path: Iter, + seed: Option, + ) -> Result<(Pair, Option), Self::DeriveError> { + let seed = if let Some(s) = seed { + if let Ok(msk) = MiniSecretKey::from_bytes(&s) { + if msk.expand(ExpansionMode::Ed25519) == self.0.secret { + Some(msk) + } else { None } + } else { None } + } else { None }; + let init = self.0.secret.clone(); + let (result, seed) = path.fold((init, seed), |(acc, acc_seed), j| match (j, acc_seed) { + (DeriveJunction::Soft(cc), _) => + (acc.derived_key_simple(ChainCode(cc), &[]).0, None), + (DeriveJunction::Hard(cc), maybe_seed) => { + let seed = derive_hard_junction(&acc, &cc); + (seed.expand(ExpansionMode::Ed25519), maybe_seed.map(|_| seed)) + } + }); + Ok((Self(result.into()), seed.map(|s| MiniSecretKey::to_bytes(&s)))) + } + + fn sign(&self, message: &[u8]) -> Signature { + let context = signing_context(SIGNING_CTX); + self.0.sign(context.bytes(message)).into() + } + + fn verify>(sig: &Self::Signature, message: M, pubkey: &Self::Public) -> bool { + Self::verify_weak(&sig.0[..], message, pubkey) + } + + fn verify_weak, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool { + let signature = match schnorrkel::Signature::from_bytes(sig) { + Ok(signature) => signature, + Err(_) => return false, + }; + + let pub_key = match PublicKey::from_bytes(pubkey.as_ref()) { + Ok(pub_key) => pub_key, + Err(_) => return false, + }; + + pub_key.verify_simple(SIGNING_CTX, message.as_ref(), &signature).is_ok() + } + + fn to_raw_vec(&self) -> Vec { + self.0.secret.to_bytes().to_vec() + } +} + +#[cfg(feature = "std")] +impl Pair { + /// Make a new key pair from binary data derived from a valid seed phrase. + /// + /// This uses a key derivation function to convert the entropy into a seed, then returns + /// the pair generated from it. + pub fn from_entropy(entropy: &[u8], password: Option<&str>) -> (Pair, Seed) { + let mini_key: MiniSecretKey = mini_secret_from_entropy(entropy, password.unwrap_or("")) + .expect("32 bytes can always build a key; qed"); + + let kp = mini_key.expand_to_keypair(ExpansionMode::Ed25519); + (Pair(kp), mini_key.to_bytes()) + } + + /// Verify a signature on a message. Returns `true` if the signature is good. + /// Supports old 0.1.1 deprecated signatures and should be used only for backward + /// compatibility. + pub fn verify_deprecated>(sig: &Signature, message: M, pubkey: &Public) -> bool { + // Match both schnorrkel 0.1.1 and 0.8.0+ signatures, supporting both wallets + // that have not been upgraded and those that have. + match PublicKey::from_bytes(pubkey.as_ref()) { + Ok(pk) => pk.verify_simple_preaudit_deprecated( + SIGNING_CTX, message.as_ref(), &sig.0[..], + ).is_ok(), + Err(_) => false, + } + } +} + +impl CryptoType for Public { + #[cfg(feature = "full_crypto")] + type Pair = Pair; +} + +impl CryptoType for Signature { + #[cfg(feature = "full_crypto")] + type Pair = Pair; +} + +#[cfg(feature = "full_crypto")] +impl CryptoType for Pair { + type Pair = Pair; +} + +/// Batch verification. +/// +/// `messages`, `signatures` and `pub_keys` should all have equal length. +/// +/// Returns `true` if all signatures are correct, `false` otherwise. +#[cfg(feature = "std")] +pub fn verify_batch( + messages: Vec<&[u8]>, + signatures: Vec<&Signature>, + pub_keys: Vec<&Public>, +) -> bool { + let mut sr_pub_keys = Vec::with_capacity(pub_keys.len()); + for pub_key in pub_keys { + match schnorrkel::PublicKey::from_bytes(pub_key.as_ref()) { + Ok(pk) => sr_pub_keys.push(pk), + Err(_) => return false, + }; + } + + let mut sr_signatures = Vec::with_capacity(signatures.len()); + for signature in signatures { + match schnorrkel::Signature::from_bytes(signature.as_ref()) { + Ok(s) => sr_signatures.push(s), + Err(_) => return false + }; + } + + let mut messages: Vec = messages.into_iter().map( + |msg| signing_context(SIGNING_CTX).bytes(msg) + ).collect(); + + schnorrkel::verify_batch( + &mut messages, + &sr_signatures, + &sr_pub_keys, + true, + ).is_ok() +} + +#[cfg(test)] +mod compatibility_test { + use super::*; + use crate::crypto::DEV_PHRASE; + use hex_literal::hex; + + // NOTE: tests to ensure addresses that are created with the `0.1.x` version (pre-audit) are + // still functional. + + #[test] + fn derive_soft_known_pair_should_work() { + let pair = Pair::from_string(&format!("{}/Alice", DEV_PHRASE), None).unwrap(); + // known address of DEV_PHRASE with 1.1 + let known = hex!("d6c71059dbbe9ad2b0ed3f289738b800836eb425544ce694825285b958ca755e"); + assert_eq!(pair.public().to_raw_vec(), known); + } + + #[test] + fn derive_hard_known_pair_should_work() { + let pair = Pair::from_string(&format!("{}//Alice", DEV_PHRASE), None).unwrap(); + // known address of DEV_PHRASE with 1.1 + let known = hex!("d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"); + assert_eq!(pair.public().to_raw_vec(), known); + } + + #[test] + fn verify_known_old_message_should_work() { + let public = Public::from_raw(hex!("b4bfa1f7a5166695eb75299fd1c4c03ea212871c342f2c5dfea0902b2c246918")); + // signature generated by the 1.1 version with the same ^^ public key. + let signature = Signature::from_raw(hex!( + "5a9755f069939f45d96aaf125cf5ce7ba1db998686f87f2fb3cbdea922078741a73891ba265f70c31436e18a9acd14d189d73c12317ab6c313285cd938453202" + )); + let message = b"Verifying that I am the owner of 5G9hQLdsKQswNPgB499DeA5PkFBbgkLPJWkkS6FAM6xGQ8xD. Hash: 221455a3\n"; + assert!(Pair::verify_deprecated(&signature, &message[..], &public)); + assert!(!Pair::verify(&signature, &message[..], &public)); + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::crypto::{Ss58Codec, DEV_PHRASE, DEV_ADDRESS}; + use hex_literal::hex; + use serde_json; + + #[test] + fn default_phrase_should_be_used() { + assert_eq!( + Pair::from_string("//Alice///password", None).unwrap().public(), + Pair::from_string(&format!("{}//Alice", DEV_PHRASE), Some("password")).unwrap().public(), + ); + assert_eq!( + Pair::from_string(&format!("{}/Alice", DEV_PHRASE), None).as_ref().map(Pair::public), + Pair::from_string("/Alice", None).as_ref().map(Pair::public) + ); + } + + #[test] + fn default_address_should_be_used() { + assert_eq!( + Public::from_string(&format!("{}/Alice", DEV_ADDRESS)), + Public::from_string("/Alice") + ); + } + + #[test] + fn default_phrase_should_correspond_to_default_address() { + assert_eq!( + Pair::from_string(&format!("{}/Alice", DEV_PHRASE), None).unwrap().public(), + Public::from_string(&format!("{}/Alice", DEV_ADDRESS)).unwrap(), + ); + assert_eq!( + Pair::from_string("/Alice", None).unwrap().public(), + Public::from_string("/Alice").unwrap() + ); + } + + #[test] + fn derive_soft_should_work() { + let pair = Pair::from_seed(&hex!( + "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" + )); + let derive_1 = pair.derive(Some(DeriveJunction::soft(1)).into_iter(), None).unwrap().0; + let derive_1b = pair.derive(Some(DeriveJunction::soft(1)).into_iter(), None).unwrap().0; + let derive_2 = pair.derive(Some(DeriveJunction::soft(2)).into_iter(), None).unwrap().0; + assert_eq!(derive_1.public(), derive_1b.public()); + assert_ne!(derive_1.public(), derive_2.public()); + } + + #[test] + fn derive_hard_should_work() { + let pair = Pair::from_seed(&hex!( + "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" + )); + let derive_1 = pair.derive(Some(DeriveJunction::hard(1)).into_iter(), None).unwrap().0; + let derive_1b = pair.derive(Some(DeriveJunction::hard(1)).into_iter(), None).unwrap().0; + let derive_2 = pair.derive(Some(DeriveJunction::hard(2)).into_iter(), None).unwrap().0; + assert_eq!(derive_1.public(), derive_1b.public()); + assert_ne!(derive_1.public(), derive_2.public()); + } + + #[test] + fn derive_soft_public_should_work() { + let pair = Pair::from_seed(&hex!( + "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" + )); + let path = Some(DeriveJunction::soft(1)); + let pair_1 = pair.derive(path.clone().into_iter(), None).unwrap().0; + let public_1 = pair.public().derive(path.into_iter()).unwrap(); + assert_eq!(pair_1.public(), public_1); + } + + #[test] + fn derive_hard_public_should_fail() { + let pair = Pair::from_seed(&hex!( + "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" + )); + let path = Some(DeriveJunction::hard(1)); + assert!(pair.public().derive(path.into_iter()).is_none()); + } + + #[test] + fn sr_test_vector_should_work() { + let pair = Pair::from_seed(&hex!( + "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" + )); + let public = pair.public(); + assert_eq!( + public, + Public::from_raw(hex!( + "44a996beb1eef7bdcab976ab6d2ca26104834164ecf28fb375600576fcc6eb0f" + )) + ); + let message = b""; + let signature = pair.sign(message); + assert!(Pair::verify(&signature, &message[..], &public)); + } + + #[test] + fn generated_pair_should_work() { + let (pair, _) = Pair::generate(); + let public = pair.public(); + let message = b"Something important"; + let signature = pair.sign(&message[..]); + assert!(Pair::verify(&signature, &message[..], &public)); + } + + #[test] + fn messed_signature_should_not_work() { + let (pair, _) = Pair::generate(); + let public = pair.public(); + let message = b"Signed payload"; + let Signature(mut bytes) = pair.sign(&message[..]); + bytes[0] = !bytes[0]; + bytes[2] = !bytes[2]; + let signature = Signature(bytes); + assert!(!Pair::verify(&signature, &message[..], &public)); + } + + #[test] + fn messed_message_should_not_work() { + let (pair, _) = Pair::generate(); + let public = pair.public(); + let message = b"Something important"; + let signature = pair.sign(&message[..]); + assert!(!Pair::verify(&signature, &b"Something unimportant", &public)); + } + + #[test] + fn seeded_pair_should_work() { + let pair = Pair::from_seed(b"12345678901234567890123456789012"); + let public = pair.public(); + assert_eq!( + public, + Public::from_raw(hex!( + "741c08a06f41c596608f6774259bd9043304adfa5d3eea62760bd9be97634d63" + )) + ); + let message = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000200d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000"); + let signature = pair.sign(&message[..]); + assert!(Pair::verify(&signature, &message[..], &public)); + } + + #[test] + fn ss58check_roundtrip_works() { + let (pair, _) = Pair::generate(); + let public = pair.public(); + let s = public.to_ss58check(); + println!("Correct: {}", s); + let cmp = Public::from_ss58check(&s).unwrap(); + assert_eq!(cmp, public); + } + + #[test] + fn verify_from_old_wasm_works() { + // The values in this test case are compared to the output of `node-test.js` in schnorrkel-js. + // + // This is to make sure that the wasm library is compatible. + let pk = Pair::from_seed( + &hex!("0000000000000000000000000000000000000000000000000000000000000000") + ); + let public = pk.public(); + let js_signature = Signature::from_raw(hex!( + "28a854d54903e056f89581c691c1f7d2ff39f8f896c9e9c22475e60902cc2b3547199e0e91fa32902028f2ca2355e8cdd16cfe19ba5e8b658c94aa80f3b81a00" + )); + assert!(Pair::verify_deprecated(&js_signature, b"SUBSTRATE", &public)); + assert!(!Pair::verify(&js_signature, b"SUBSTRATE", &public)); + } + + #[test] + fn signature_serialization_works() { + let pair = Pair::from_seed(b"12345678901234567890123456789012"); + let message = b"Something important"; + let signature = pair.sign(&message[..]); + let serialized_signature = serde_json::to_string(&signature).unwrap(); + // Signature is 64 bytes, so 128 chars + 2 quote chars + assert_eq!(serialized_signature.len(), 130); + let signature = serde_json::from_str(&serialized_signature).unwrap(); + assert!(Pair::verify(&signature, &message[..], &pair.public())); + } + + #[test] + fn signature_serialization_doesnt_panic() { + fn deserialize_signature(text: &str) -> Result { + Ok(serde_json::from_str(text)?) + } + assert!(deserialize_signature("Not valid json.").is_err()); + assert!(deserialize_signature("\"Not an actual signature.\"").is_err()); + // Poorly-sized + assert!(deserialize_signature("\"abc123\"").is_err()); + } +} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/testing.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/testing.rs new file mode 100644 index 00000000..5c4af736 --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/testing.rs @@ -0,0 +1,464 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Types that should only be used for testing! + +use crate::crypto::KeyTypeId; +#[cfg(feature = "std")] +use crate::{ + crypto::{Pair, Public, CryptoTypePublicPair}, + ed25519, sr25519, ecdsa, + traits::Error, + vrf::{VRFTranscriptData, VRFSignature, make_transcript}, +}; +#[cfg(feature = "std")] +use std::collections::HashSet; + +/// Key type for generic Ed25519 key. +pub const ED25519: KeyTypeId = KeyTypeId(*b"ed25"); +/// Key type for generic Sr 25519 key. +pub const SR25519: KeyTypeId = KeyTypeId(*b"sr25"); +/// Key type for generic Sr 25519 key. +pub const ECDSA: KeyTypeId = KeyTypeId(*b"ecds"); + +/// A keystore implementation usable in tests. +#[cfg(feature = "std")] +#[derive(Default)] +pub struct KeyStore { + /// `KeyTypeId` maps to public keys and public keys map to private keys. + keys: std::collections::HashMap, String>>, +} + +#[cfg(feature = "std")] +impl KeyStore { + /// Creates a new instance of `Self`. + pub fn new() -> crate::traits::BareCryptoStorePtr { + std::sync::Arc::new(parking_lot::RwLock::new(Self::default())) + } + + fn sr25519_key_pair(&self, id: KeyTypeId, pub_key: &sr25519::Public) -> Option { + self.keys.get(&id) + .and_then(|inner| + inner.get(pub_key.as_slice()) + .map(|s| sr25519::Pair::from_string(s, None).expect("`sr25519` seed slice is valid")) + ) + } + + fn ed25519_key_pair(&self, id: KeyTypeId, pub_key: &ed25519::Public) -> Option { + self.keys.get(&id) + .and_then(|inner| + inner.get(pub_key.as_slice()) + .map(|s| ed25519::Pair::from_string(s, None).expect("`ed25519` seed slice is valid")) + ) + } + + fn ecdsa_key_pair(&self, id: KeyTypeId, pub_key: &ecdsa::Public) -> Option { + self.keys.get(&id) + .and_then(|inner| + inner.get(pub_key.as_slice()) + .map(|s| ecdsa::Pair::from_string(s, None).expect("`ecdsa` seed slice is valid")) + ) + } + +} + +#[cfg(feature = "std")] +impl crate::traits::BareCryptoStore for KeyStore { + fn keys(&self, id: KeyTypeId) -> Result, Error> { + self.keys + .get(&id) + .map(|map| { + Ok(map.keys() + .fold(Vec::new(), |mut v, k| { + v.push(CryptoTypePublicPair(sr25519::CRYPTO_ID, k.clone())); + v.push(CryptoTypePublicPair(ed25519::CRYPTO_ID, k.clone())); + v.push(CryptoTypePublicPair(ecdsa::CRYPTO_ID, k.clone())); + v + })) + }) + .unwrap_or_else(|| Ok(vec![])) + } + + fn sr25519_public_keys(&self, id: KeyTypeId) -> Vec { + self.keys.get(&id) + .map(|keys| + keys.values() + .map(|s| sr25519::Pair::from_string(s, None).expect("`sr25519` seed slice is valid")) + .map(|p| p.public()) + .collect() + ) + .unwrap_or_default() + } + + fn sr25519_generate_new( + &mut self, + id: KeyTypeId, + seed: Option<&str>, + ) -> Result { + match seed { + Some(seed) => { + let pair = sr25519::Pair::from_string(seed, None) + .map_err(|_| Error::ValidationError("Generates an `sr25519` pair.".to_owned()))?; + self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into()); + Ok(pair.public()) + }, + None => { + let (pair, phrase, _) = sr25519::Pair::generate_with_phrase(None); + self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), phrase); + Ok(pair.public()) + } + } + } + + fn ed25519_public_keys(&self, id: KeyTypeId) -> Vec { + self.keys.get(&id) + .map(|keys| + keys.values() + .map(|s| ed25519::Pair::from_string(s, None).expect("`ed25519` seed slice is valid")) + .map(|p| p.public()) + .collect() + ) + .unwrap_or_default() + } + + fn ed25519_generate_new( + &mut self, + id: KeyTypeId, + seed: Option<&str>, + ) -> Result { + match seed { + Some(seed) => { + let pair = ed25519::Pair::from_string(seed, None) + .map_err(|_| Error::ValidationError("Generates an `ed25519` pair.".to_owned()))?; + self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into()); + Ok(pair.public()) + }, + None => { + let (pair, phrase, _) = ed25519::Pair::generate_with_phrase(None); + self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), phrase); + Ok(pair.public()) + } + } + } + + fn ecdsa_public_keys(&self, id: KeyTypeId) -> Vec { + self.keys.get(&id) + .map(|keys| + keys.values() + .map(|s| ecdsa::Pair::from_string(s, None).expect("`ecdsa` seed slice is valid")) + .map(|p| p.public()) + .collect() + ) + .unwrap_or_default() + } + + fn ecdsa_generate_new( + &mut self, + id: KeyTypeId, + seed: Option<&str>, + ) -> Result { + match seed { + Some(seed) => { + let pair = ecdsa::Pair::from_string(seed, None) + .map_err(|_| Error::ValidationError("Generates an `ecdsa` pair.".to_owned()))?; + self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into()); + Ok(pair.public()) + }, + None => { + let (pair, phrase, _) = ecdsa::Pair::generate_with_phrase(None); + self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), phrase); + Ok(pair.public()) + } + } + } + + fn insert_unknown(&mut self, id: KeyTypeId, suri: &str, public: &[u8]) -> Result<(), ()> { + self.keys.entry(id).or_default().insert(public.to_owned(), suri.to_string()); + Ok(()) + } + + fn password(&self) -> Option<&str> { + None + } + + fn has_keys(&self, public_keys: &[(Vec, KeyTypeId)]) -> bool { + public_keys.iter().all(|(k, t)| self.keys.get(&t).and_then(|s| s.get(k)).is_some()) + } + + fn supported_keys( + &self, + id: KeyTypeId, + keys: Vec, + ) -> std::result::Result, Error> { + let provided_keys = keys.into_iter().collect::>(); + let all_keys = self.keys(id)?.into_iter().collect::>(); + + Ok(provided_keys.intersection(&all_keys).cloned().collect()) + } + + fn sign_with( + &self, + id: KeyTypeId, + key: &CryptoTypePublicPair, + msg: &[u8], + ) -> Result, Error> { + use codec::Encode; + + match key.0 { + ed25519::CRYPTO_ID => { + let key_pair: ed25519::Pair = self + .ed25519_key_pair(id, &ed25519::Public::from_slice(key.1.as_slice())) + .ok_or_else(|| Error::PairNotFound("ed25519".to_owned()))?; + return Ok(key_pair.sign(msg).encode()); + } + sr25519::CRYPTO_ID => { + let key_pair: sr25519::Pair = self + .sr25519_key_pair(id, &sr25519::Public::from_slice(key.1.as_slice())) + .ok_or_else(|| Error::PairNotFound("sr25519".to_owned()))?; + return Ok(key_pair.sign(msg).encode()); + } + ecdsa::CRYPTO_ID => { + let key_pair: ecdsa::Pair = self + .ecdsa_key_pair(id, &ecdsa::Public::from_slice(key.1.as_slice())) + .ok_or_else(|| Error::PairNotFound("ecdsa".to_owned()))?; + return Ok(key_pair.sign(msg).encode()); + } + _ => Err(Error::KeyNotSupported(id)) + } + } + + fn sr25519_vrf_sign( + &self, + key_type: KeyTypeId, + public: &sr25519::Public, + transcript_data: VRFTranscriptData, + ) -> Result { + let transcript = make_transcript(transcript_data); + let pair = self.sr25519_key_pair(key_type, public) + .ok_or_else(|| Error::PairNotFound("Not found".to_owned()))?; + + let (inout, proof, _) = pair.as_ref().vrf_sign(transcript); + Ok(VRFSignature { + output: inout.to_output(), + proof, + }) + } +} + +/// Macro for exporting functions from wasm in with the expected signature for using it with the +/// wasm executor. This is useful for tests where you need to call a function in wasm. +/// +/// The input parameters are expected to be SCALE encoded and will be automatically decoded for you. +/// The output value is also SCALE encoded when returned back to the host. +/// +/// The functions are feature-gated with `#[cfg(not(feature = "std"))]`, so they are only available +/// from within wasm. +/// +/// # Example +/// +/// ``` +/// # use sp_core::wasm_export_functions; +/// +/// wasm_export_functions! { +/// fn test_in_wasm(value: bool, another_value: Vec) -> bool { +/// value && another_value.is_empty() +/// } +/// +/// fn without_return_value() { +/// // do something +/// } +/// } +/// ``` +#[macro_export] +macro_rules! wasm_export_functions { + ( + $( + fn $name:ident ( + $( $arg_name:ident: $arg_ty:ty ),* $(,)? + ) $( -> $ret_ty:ty )? { $( $fn_impl:tt )* } + )* + ) => { + $( + $crate::wasm_export_functions! { + @IMPL + fn $name ( + $( $arg_name: $arg_ty ),* + ) $( -> $ret_ty )? { $( $fn_impl )* } + } + )* + }; + (@IMPL + fn $name:ident ( + $( $arg_name:ident: $arg_ty:ty ),* + ) { $( $fn_impl:tt )* } + ) => { + #[no_mangle] + #[allow(unreachable_code)] + #[cfg(not(feature = "std"))] + pub fn $name(input_data: *mut u8, input_len: usize) -> u64 { + let input: &[u8] = if input_len == 0 { + &[0u8; 0] + } else { + unsafe { + $crate::sp_std::slice::from_raw_parts(input_data, input_len) + } + }; + + { + let ($( $arg_name ),*) : ($( $arg_ty ),*) = $crate::Decode::decode( + &mut &input[..], + ).expect("Input data is correctly encoded"); + + $( $fn_impl )* + } + + $crate::to_substrate_wasm_fn_return_value(&()) + } + }; + (@IMPL + fn $name:ident ( + $( $arg_name:ident: $arg_ty:ty ),* + ) $( -> $ret_ty:ty )? { $( $fn_impl:tt )* } + ) => { + #[no_mangle] + #[allow(unreachable_code)] + #[cfg(not(feature = "std"))] + pub fn $name(input_data: *mut u8, input_len: usize) -> u64 { + let input: &[u8] = if input_len == 0 { + &[0u8; 0] + } else { + unsafe { + $crate::sp_std::slice::from_raw_parts(input_data, input_len) + } + }; + + let output $( : $ret_ty )? = { + let ($( $arg_name ),*) : ($( $arg_ty ),*) = $crate::Decode::decode( + &mut &input[..], + ).expect("Input data is correctly encoded"); + + $( $fn_impl )* + }; + + $crate::to_substrate_wasm_fn_return_value(&output) + } + }; +} + +/// A task executor that can be used in tests. +/// +/// Internally this just wraps a `ThreadPool` with a pool size of `8`. This +/// should ensure that we have enough threads in tests for spawning blocking futures. +#[cfg(feature = "std")] +#[derive(Clone)] +pub struct TaskExecutor(futures::executor::ThreadPool); + +#[cfg(feature = "std")] +impl TaskExecutor { + /// Create a new instance of `Self`. + pub fn new() -> Self { + let mut builder = futures::executor::ThreadPoolBuilder::new(); + Self(builder.pool_size(8).create().expect("Failed to create thread pool")) + } +} + +#[cfg(feature = "std")] +impl crate::traits::SpawnNamed for TaskExecutor { + fn spawn_blocking(&self, _: &'static str, future: futures::future::BoxFuture<'static, ()>) { + self.0.spawn_ok(future); + } + fn spawn(&self, _: &'static str, future: futures::future::BoxFuture<'static, ()>) { + self.0.spawn_ok(future); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::sr25519; + use crate::testing::{ED25519, SR25519}; + use crate::vrf::VRFTranscriptValue; + + #[test] + fn store_key_and_extract() { + let store = KeyStore::new(); + + let public = store.write() + .ed25519_generate_new(ED25519, None) + .expect("Generates key"); + + let public_keys = store.read().keys(ED25519).unwrap(); + + assert!(public_keys.contains(&public.into())); + } + + #[test] + fn store_unknown_and_extract_it() { + let store = KeyStore::new(); + + let secret_uri = "//Alice"; + let key_pair = sr25519::Pair::from_string(secret_uri, None).expect("Generates key pair"); + + store.write().insert_unknown( + SR25519, + secret_uri, + key_pair.public().as_ref(), + ).expect("Inserts unknown key"); + + let public_keys = store.read().keys(SR25519).unwrap(); + + assert!(public_keys.contains(&key_pair.public().into())); + } + + #[test] + fn vrf_sign() { + let store = KeyStore::new(); + + let secret_uri = "//Alice"; + let key_pair = sr25519::Pair::from_string(secret_uri, None).expect("Generates key pair"); + + let transcript_data = VRFTranscriptData { + label: b"Test", + items: vec![ + ("one", VRFTranscriptValue::U64(1)), + ("two", VRFTranscriptValue::U64(2)), + ("three", VRFTranscriptValue::Bytes("test".as_bytes())), + ] + }; + + let result = store.read().sr25519_vrf_sign( + SR25519, + &key_pair.public(), + transcript_data.clone(), + ); + assert!(result.is_err()); + + store.write().insert_unknown( + SR25519, + secret_uri, + key_pair.public().as_ref(), + ).expect("Inserts unknown key"); + + let result = store.read().sr25519_vrf_sign( + SR25519, + &key_pair.public(), + transcript_data, + ); + + assert!(result.is_ok()); + } +} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/traits.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/traits.rs new file mode 100644 index 00000000..ab409b60 --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/traits.rs @@ -0,0 +1,388 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Shareable Substrate traits. + +use crate::{ + crypto::{KeyTypeId, CryptoTypePublicPair}, + vrf::{VRFTranscriptData, VRFSignature}, + ed25519, sr25519, ecdsa, +}; +use std::{ + borrow::Cow, + fmt::{Debug, Display}, + panic::UnwindSafe, + sync::Arc, +}; + +pub use sp_externalities::{Externalities, ExternalitiesExt}; + +/// BareCryptoStore error +#[derive(Debug, derive_more::Display)] +pub enum Error { + /// Public key type is not supported + #[display(fmt="Key not supported: {:?}", _0)] + KeyNotSupported(KeyTypeId), + /// Pair not found for public key and KeyTypeId + #[display(fmt="Pair was not found: {}", _0)] + PairNotFound(String), + /// Validation error + #[display(fmt="Validation error: {}", _0)] + ValidationError(String), + /// Keystore unavailable + #[display(fmt="Keystore unavailable")] + Unavailable, + /// Programming errors + #[display(fmt="An unknown keystore error occurred: {}", _0)] + Other(String) +} + +/// Something that generates, stores and provides access to keys. +pub trait BareCryptoStore: Send + Sync { + /// Returns all sr25519 public keys for the given key type. + fn sr25519_public_keys(&self, id: KeyTypeId) -> Vec; + /// Generate a new sr25519 key pair for the given key type and an optional seed. + /// + /// If the given seed is `Some(_)`, the key pair will only be stored in memory. + /// + /// Returns the public key of the generated key pair. + fn sr25519_generate_new( + &mut self, + id: KeyTypeId, + seed: Option<&str>, + ) -> Result; + /// Returns all ed25519 public keys for the given key type. + fn ed25519_public_keys(&self, id: KeyTypeId) -> Vec; + /// Generate a new ed25519 key pair for the given key type and an optional seed. + /// + /// If the given seed is `Some(_)`, the key pair will only be stored in memory. + /// + /// Returns the public key of the generated key pair. + fn ed25519_generate_new( + &mut self, + id: KeyTypeId, + seed: Option<&str>, + ) -> Result; + /// Returns all ecdsa public keys for the given key type. + fn ecdsa_public_keys(&self, id: KeyTypeId) -> Vec; + /// Generate a new ecdsa key pair for the given key type and an optional seed. + /// + /// If the given seed is `Some(_)`, the key pair will only be stored in memory. + /// + /// Returns the public key of the generated key pair. + fn ecdsa_generate_new( + &mut self, + id: KeyTypeId, + seed: Option<&str>, + ) -> Result; + + /// Insert a new key. This doesn't require any known of the crypto; but a public key must be + /// manually provided. + /// + /// Places it into the file system store. + /// + /// `Err` if there's some sort of weird filesystem error, but should generally be `Ok`. + fn insert_unknown(&mut self, _key_type: KeyTypeId, _suri: &str, _public: &[u8]) -> Result<(), ()>; + + /// Get the password for this store. + fn password(&self) -> Option<&str>; + /// Find intersection between provided keys and supported keys + /// + /// Provided a list of (CryptoTypeId,[u8]) pairs, this would return + /// a filtered set of public keys which are supported by the keystore. + fn supported_keys( + &self, + id: KeyTypeId, + keys: Vec + ) -> Result, Error>; + /// List all supported keys + /// + /// Returns a set of public keys the signer supports. + fn keys(&self, id: KeyTypeId) -> Result, Error>; + + /// Checks if the private keys for the given public key and key type combinations exist. + /// + /// Returns `true` iff all private keys could be found. + fn has_keys(&self, public_keys: &[(Vec, KeyTypeId)]) -> bool; + + /// Sign with key + /// + /// Signs a message with the private key that matches + /// the public key passed. + /// + /// Returns the SCALE encoded signature if key is found & supported, + /// an error otherwise. + fn sign_with( + &self, + id: KeyTypeId, + key: &CryptoTypePublicPair, + msg: &[u8], + ) -> Result, Error>; + + /// Sign with any key + /// + /// Given a list of public keys, find the first supported key and + /// sign the provided message with that key. + /// + /// Returns a tuple of the used key and the SCALE encoded signature. + fn sign_with_any( + &self, + id: KeyTypeId, + keys: Vec, + msg: &[u8] + ) -> Result<(CryptoTypePublicPair, Vec), Error> { + if keys.len() == 1 { + return self.sign_with(id, &keys[0], msg).map(|s| (keys[0].clone(), s)); + } else { + for k in self.supported_keys(id, keys)? { + if let Ok(sign) = self.sign_with(id, &k, msg) { + return Ok((k, sign)); + } + } + } + Err(Error::KeyNotSupported(id)) + } + + /// Sign with all keys + /// + /// Provided a list of public keys, sign a message with + /// each key given that the key is supported. + /// + /// Returns a list of `Result`s each representing the SCALE encoded + /// signature of each key or a Error for non-supported keys. + fn sign_with_all( + &self, + id: KeyTypeId, + keys: Vec, + msg: &[u8], + ) -> Result, Error>>, ()>{ + Ok(keys.iter().map(|k| self.sign_with(id, k, msg)).collect()) + } + + /// Generate VRF signature for given transcript data. + /// + /// Receives KeyTypeId and Public key to be able to map + /// them to a private key that exists in the keystore which + /// is, in turn, used for signing the provided transcript. + /// + /// Returns a result containing the signature data. + /// Namely, VRFOutput and VRFProof which are returned + /// inside the `VRFSignature` container struct. + /// + /// This function will return an error in the cases where + /// the public key and key type provided do not match a private + /// key in the keystore. Or, in the context of remote signing + /// an error could be a network one. + fn sr25519_vrf_sign( + &self, + key_type: KeyTypeId, + public: &sr25519::Public, + transcript_data: VRFTranscriptData, + ) -> Result; +} + +/// A pointer to the key store. +pub type BareCryptoStorePtr = Arc>; + +sp_externalities::decl_extension! { + /// The keystore extension to register/retrieve from the externalities. + pub struct KeystoreExt(BareCryptoStorePtr); +} + +/// Code execution engine. +pub trait CodeExecutor: Sized + Send + Sync + CallInWasm + Clone + 'static { + /// Externalities error type. + type Error: Display + Debug + Send + 'static; + + /// Call a given method in the runtime. Returns a tuple of the result (either the output data + /// or an execution error) together with a `bool`, which is true if native execution was used. + fn call< + R: codec::Codec + PartialEq, + NC: FnOnce() -> Result + UnwindSafe, + >( + &self, + ext: &mut dyn Externalities, + runtime_code: &RuntimeCode, + method: &str, + data: &[u8], + use_native: bool, + native_call: Option, + ) -> (Result, Self::Error>, bool); +} + +/// Something that can fetch the runtime `:code`. +pub trait FetchRuntimeCode { + /// Fetch the runtime `:code`. + /// + /// If the `:code` could not be found/not available, `None` should be returned. + fn fetch_runtime_code<'a>(&'a self) -> Option>; +} + +/// Wrapper to use a `u8` slice or `Vec` as [`FetchRuntimeCode`]. +pub struct WrappedRuntimeCode<'a>(pub std::borrow::Cow<'a, [u8]>); + +impl<'a> FetchRuntimeCode for WrappedRuntimeCode<'a> { + fn fetch_runtime_code<'b>(&'b self) -> Option> { + Some(self.0.as_ref().into()) + } +} + +/// Type that implements [`FetchRuntimeCode`] and always returns `None`. +pub struct NoneFetchRuntimeCode; + +impl FetchRuntimeCode for NoneFetchRuntimeCode { + fn fetch_runtime_code<'a>(&'a self) -> Option> { + None + } +} + +/// The Wasm code of a Substrate runtime. +#[derive(Clone)] +pub struct RuntimeCode<'a> { + /// The code fetcher that can be used to lazily fetch the code. + pub code_fetcher: &'a dyn FetchRuntimeCode, + /// The optional heap pages this `code` should be executed with. + /// + /// If `None` are given, the default value of the executor will be used. + pub heap_pages: Option, + /// The SCALE encoded hash of `code`. + /// + /// The hashing algorithm isn't that important, as long as all runtime + /// code instances use the same. + pub hash: Vec, +} + +impl<'a> PartialEq for RuntimeCode<'a> { + fn eq(&self, other: &Self) -> bool { + self.hash == other.hash + } +} + +impl<'a> RuntimeCode<'a> { + /// Create an empty instance. + /// + /// This is only useful for tests that don't want to execute any code. + pub fn empty() -> Self { + Self { + code_fetcher: &NoneFetchRuntimeCode, + hash: Vec::new(), + heap_pages: None, + } + } +} + +impl<'a> FetchRuntimeCode for RuntimeCode<'a> { + fn fetch_runtime_code<'b>(&'b self) -> Option> { + self.code_fetcher.fetch_runtime_code() + } +} + +/// Could not find the `:code` in the externalities while initializing the [`RuntimeCode`]. +#[derive(Debug)] +pub struct CodeNotFound; + +impl std::fmt::Display for CodeNotFound { + fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + write!(f, "the storage entry `:code` doesn't have any code") + } +} + +/// `Allow` or `Disallow` missing host functions when instantiating a WASM blob. +#[derive(Clone, Copy, Debug)] +pub enum MissingHostFunctions { + /// Any missing host function will be replaced by a stub that returns an error when + /// being called. + Allow, + /// Any missing host function will result in an error while instantiating the WASM blob, + Disallow, +} + +impl MissingHostFunctions { + /// Are missing host functions allowed? + pub fn allowed(self) -> bool { + matches!(self, Self::Allow) + } +} + +/// Something that can call a method in a WASM blob. +pub trait CallInWasm: Send + Sync { + /// Call the given `method` in the given `wasm_blob` using `call_data` (SCALE encoded arguments) + /// to decode the arguments for the method. + /// + /// Returns the SCALE encoded return value of the method. + /// + /// # Note + /// + /// If `code_hash` is `Some(_)` the `wasm_code` module and instance will be cached internally, + /// otherwise it is thrown away after the call. + fn call_in_wasm( + &self, + wasm_code: &[u8], + code_hash: Option>, + method: &str, + call_data: &[u8], + ext: &mut dyn Externalities, + missing_host_functions: MissingHostFunctions, + ) -> Result, String>; +} + +sp_externalities::decl_extension! { + /// The call-in-wasm extension to register/retrieve from the externalities. + pub struct CallInWasmExt(Box); +} + +impl CallInWasmExt { + /// Creates a new instance of `Self`. + pub fn new(inner: T) -> Self { + Self(Box::new(inner)) + } +} + +sp_externalities::decl_extension! { + /// Task executor extension. + pub struct TaskExecutorExt(Box); +} + +impl TaskExecutorExt { + /// New instance of task executor extension. + pub fn new(spawn_handle: impl SpawnNamed + Send + 'static) -> Self { + Self(Box::new(spawn_handle)) + } +} + +/// Something that can spawn futures (blocking and non-blocking) with an assigned name. +#[dyn_clonable::clonable] +pub trait SpawnNamed: Clone + Send + Sync { + /// Spawn the given blocking future. + /// + /// The given `name` is used to identify the future in tracing. + fn spawn_blocking(&self, name: &'static str, future: futures::future::BoxFuture<'static, ()>); + /// Spawn the given non-blocking future. + /// + /// The given `name` is used to identify the future in tracing. + fn spawn(&self, name: &'static str, future: futures::future::BoxFuture<'static, ()>); +} + +impl SpawnNamed for Box { + fn spawn_blocking(&self, name: &'static str, future: futures::future::BoxFuture<'static, ()>) { + (**self).spawn_blocking(name, future) + } + + fn spawn(&self, name: &'static str, future: futures::future::BoxFuture<'static, ()>) { + (**self).spawn(name, future) + } +} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/u32_trait.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/u32_trait.rs new file mode 100644 index 00000000..6f73e1f6 --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/u32_trait.rs @@ -0,0 +1,244 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! An u32 trait with "values" as impl'd types. + +/// A u32 value, wrapped in a trait because we don't yet have const generics. +pub trait Value { + /// The actual value represented by the impl'ing type. + const VALUE: u32; +} + +/// Type representing the value 0 for the `Value` trait. +pub struct _0; impl Value for _0 { const VALUE: u32 = 0; } +/// Type representing the value 1 for the `Value` trait. +pub struct _1; impl Value for _1 { const VALUE: u32 = 1; } +/// Type representing the value 2 for the `Value` trait. +pub struct _2; impl Value for _2 { const VALUE: u32 = 2; } +/// Type representing the value 3 for the `Value` trait. +pub struct _3; impl Value for _3 { const VALUE: u32 = 3; } +/// Type representing the value 4 for the `Value` trait. +pub struct _4; impl Value for _4 { const VALUE: u32 = 4; } +/// Type representing the value 5 for the `Value` trait. +pub struct _5; impl Value for _5 { const VALUE: u32 = 5; } +/// Type representing the value 6 for the `Value` trait. +pub struct _6; impl Value for _6 { const VALUE: u32 = 6; } +/// Type representing the value 7 for the `Value` trait. +pub struct _7; impl Value for _7 { const VALUE: u32 = 7; } +/// Type representing the value 8 for the `Value` trait. +pub struct _8; impl Value for _8 { const VALUE: u32 = 8; } +/// Type representing the value 9 for the `Value` trait. +pub struct _9; impl Value for _9 { const VALUE: u32 = 9; } +/// Type representing the value 10 for the `Value` trait. +pub struct _10; impl Value for _10 { const VALUE: u32 = 10; } +/// Type representing the value 11 for the `Value` trait. +pub struct _11; impl Value for _11 { const VALUE: u32 = 11; } +/// Type representing the value 12 for the `Value` trait. +pub struct _12; impl Value for _12 { const VALUE: u32 = 12; } +/// Type representing the value 13 for the `Value` trait. +pub struct _13; impl Value for _13 { const VALUE: u32 = 13; } +/// Type representing the value 14 for the `Value` trait. +pub struct _14; impl Value for _14 { const VALUE: u32 = 14; } +/// Type representing the value 15 for the `Value` trait. +pub struct _15; impl Value for _15 { const VALUE: u32 = 15; } +/// Type representing the value 16 for the `Value` trait. +pub struct _16; impl Value for _16 { const VALUE: u32 = 16; } +/// Type representing the value 17 for the `Value` trait. +pub struct _17; impl Value for _17 { const VALUE: u32 = 17; } +/// Type representing the value 18 for the `Value` trait. +pub struct _18; impl Value for _18 { const VALUE: u32 = 18; } +/// Type representing the value 19 for the `Value` trait. +pub struct _19; impl Value for _19 { const VALUE: u32 = 19; } +/// Type representing the value 20 for the `Value` trait. +pub struct _20; impl Value for _20 { const VALUE: u32 = 20; } +/// Type representing the value 21 for the `Value` trait. +pub struct _21; impl Value for _21 { const VALUE: u32 = 21; } +/// Type representing the value 22 for the `Value` trait. +pub struct _22; impl Value for _22 { const VALUE: u32 = 22; } +/// Type representing the value 23 for the `Value` trait. +pub struct _23; impl Value for _23 { const VALUE: u32 = 23; } +/// Type representing the value 24 for the `Value` trait. +pub struct _24; impl Value for _24 { const VALUE: u32 = 24; } +/// Type representing the value 25 for the `Value` trait. +pub struct _25; impl Value for _25 { const VALUE: u32 = 25; } +/// Type representing the value 26 for the `Value` trait. +pub struct _26; impl Value for _26 { const VALUE: u32 = 26; } +/// Type representing the value 27 for the `Value` trait. +pub struct _27; impl Value for _27 { const VALUE: u32 = 27; } +/// Type representing the value 28 for the `Value` trait. +pub struct _28; impl Value for _28 { const VALUE: u32 = 28; } +/// Type representing the value 29 for the `Value` trait. +pub struct _29; impl Value for _29 { const VALUE: u32 = 29; } +/// Type representing the value 30 for the `Value` trait. +pub struct _30; impl Value for _30 { const VALUE: u32 = 30; } +/// Type representing the value 31 for the `Value` trait. +pub struct _31; impl Value for _31 { const VALUE: u32 = 31; } +/// Type representing the value 32 for the `Value` trait. +pub struct _32; impl Value for _32 { const VALUE: u32 = 32; } +/// Type representing the value 33 for the `Value` trait. +pub struct _33; impl Value for _33 { const VALUE: u32 = 33; } +/// Type representing the value 34 for the `Value` trait. +pub struct _34; impl Value for _34 { const VALUE: u32 = 34; } +/// Type representing the value 35 for the `Value` trait. +pub struct _35; impl Value for _35 { const VALUE: u32 = 35; } +/// Type representing the value 36 for the `Value` trait. +pub struct _36; impl Value for _36 { const VALUE: u32 = 36; } +/// Type representing the value 37 for the `Value` trait. +pub struct _37; impl Value for _37 { const VALUE: u32 = 37; } +/// Type representing the value 38 for the `Value` trait. +pub struct _38; impl Value for _38 { const VALUE: u32 = 38; } +/// Type representing the value 39 for the `Value` trait. +pub struct _39; impl Value for _39 { const VALUE: u32 = 39; } +/// Type representing the value 40 for the `Value` trait. +pub struct _40; impl Value for _40 { const VALUE: u32 = 40; } +/// Type representing the value 41 for the `Value` trait. +pub struct _41; impl Value for _41 { const VALUE: u32 = 41; } +/// Type representing the value 42 for the `Value` trait. +pub struct _42; impl Value for _42 { const VALUE: u32 = 42; } +/// Type representing the value 43 for the `Value` trait. +pub struct _43; impl Value for _43 { const VALUE: u32 = 43; } +/// Type representing the value 44 for the `Value` trait. +pub struct _44; impl Value for _44 { const VALUE: u32 = 44; } +/// Type representing the value 45 for the `Value` trait. +pub struct _45; impl Value for _45 { const VALUE: u32 = 45; } +/// Type representing the value 46 for the `Value` trait. +pub struct _46; impl Value for _46 { const VALUE: u32 = 46; } +/// Type representing the value 47 for the `Value` trait. +pub struct _47; impl Value for _47 { const VALUE: u32 = 47; } +/// Type representing the value 48 for the `Value` trait. +pub struct _48; impl Value for _48 { const VALUE: u32 = 48; } +/// Type representing the value 49 for the `Value` trait. +pub struct _49; impl Value for _49 { const VALUE: u32 = 49; } +/// Type representing the value 50 for the `Value` trait. +pub struct _50; impl Value for _50 { const VALUE: u32 = 50; } +/// Type representing the value 51 for the `Value` trait. +pub struct _51; impl Value for _51 { const VALUE: u32 = 51; } +/// Type representing the value 52 for the `Value` trait. +pub struct _52; impl Value for _52 { const VALUE: u32 = 52; } +/// Type representing the value 53 for the `Value` trait. +pub struct _53; impl Value for _53 { const VALUE: u32 = 53; } +/// Type representing the value 54 for the `Value` trait. +pub struct _54; impl Value for _54 { const VALUE: u32 = 54; } +/// Type representing the value 55 for the `Value` trait. +pub struct _55; impl Value for _55 { const VALUE: u32 = 55; } +/// Type representing the value 56 for the `Value` trait. +pub struct _56; impl Value for _56 { const VALUE: u32 = 56; } +/// Type representing the value 57 for the `Value` trait. +pub struct _57; impl Value for _57 { const VALUE: u32 = 57; } +/// Type representing the value 58 for the `Value` trait. +pub struct _58; impl Value for _58 { const VALUE: u32 = 58; } +/// Type representing the value 59 for the `Value` trait. +pub struct _59; impl Value for _59 { const VALUE: u32 = 59; } +/// Type representing the value 60 for the `Value` trait. +pub struct _60; impl Value for _60 { const VALUE: u32 = 60; } +/// Type representing the value 61 for the `Value` trait. +pub struct _61; impl Value for _61 { const VALUE: u32 = 61; } +/// Type representing the value 62 for the `Value` trait. +pub struct _62; impl Value for _62 { const VALUE: u32 = 62; } +/// Type representing the value 63 for the `Value` trait. +pub struct _63; impl Value for _63 { const VALUE: u32 = 63; } +/// Type representing the value 64 for the `Value` trait. +pub struct _64; impl Value for _64 { const VALUE: u32 = 64; } +/// Type representing the value 65 for the `Value` trait. +pub struct _65; impl Value for _65 { const VALUE: u32 = 65; } +/// Type representing the value 66 for the `Value` trait. +pub struct _66; impl Value for _66 { const VALUE: u32 = 66; } +/// Type representing the value 67 for the `Value` trait. +pub struct _67; impl Value for _67 { const VALUE: u32 = 67; } +/// Type representing the value 68 for the `Value` trait. +pub struct _68; impl Value for _68 { const VALUE: u32 = 68; } +/// Type representing the value 69 for the `Value` trait. +pub struct _69; impl Value for _69 { const VALUE: u32 = 69; } +/// Type representing the value 70 for the `Value` trait. +pub struct _70; impl Value for _70 { const VALUE: u32 = 70; } +/// Type representing the value 71 for the `Value` trait. +pub struct _71; impl Value for _71 { const VALUE: u32 = 71; } +/// Type representing the value 72 for the `Value` trait. +pub struct _72; impl Value for _72 { const VALUE: u32 = 72; } +/// Type representing the value 73 for the `Value` trait. +pub struct _73; impl Value for _73 { const VALUE: u32 = 73; } +/// Type representing the value 74 for the `Value` trait. +pub struct _74; impl Value for _74 { const VALUE: u32 = 74; } +/// Type representing the value 75 for the `Value` trait. +pub struct _75; impl Value for _75 { const VALUE: u32 = 75; } +/// Type representing the value 76 for the `Value` trait. +pub struct _76; impl Value for _76 { const VALUE: u32 = 76; } +/// Type representing the value 77 for the `Value` trait. +pub struct _77; impl Value for _77 { const VALUE: u32 = 77; } +/// Type representing the value 78 for the `Value` trait. +pub struct _78; impl Value for _78 { const VALUE: u32 = 78; } +/// Type representing the value 79 for the `Value` trait. +pub struct _79; impl Value for _79 { const VALUE: u32 = 79; } +/// Type representing the value 80 for the `Value` trait. +pub struct _80; impl Value for _80 { const VALUE: u32 = 80; } +/// Type representing the value 81 for the `Value` trait. +pub struct _81; impl Value for _81 { const VALUE: u32 = 81; } +/// Type representing the value 82 for the `Value` trait. +pub struct _82; impl Value for _82 { const VALUE: u32 = 82; } +/// Type representing the value 83 for the `Value` trait. +pub struct _83; impl Value for _83 { const VALUE: u32 = 83; } +/// Type representing the value 84 for the `Value` trait. +pub struct _84; impl Value for _84 { const VALUE: u32 = 84; } +/// Type representing the value 85 for the `Value` trait. +pub struct _85; impl Value for _85 { const VALUE: u32 = 85; } +/// Type representing the value 86 for the `Value` trait. +pub struct _86; impl Value for _86 { const VALUE: u32 = 86; } +/// Type representing the value 87 for the `Value` trait. +pub struct _87; impl Value for _87 { const VALUE: u32 = 87; } +/// Type representing the value 88 for the `Value` trait. +pub struct _88; impl Value for _88 { const VALUE: u32 = 88; } +/// Type representing the value 89 for the `Value` trait. +pub struct _89; impl Value for _89 { const VALUE: u32 = 89; } +/// Type representing the value 90 for the `Value` trait. +pub struct _90; impl Value for _90 { const VALUE: u32 = 90; } +/// Type representing the value 91 for the `Value` trait. +pub struct _91; impl Value for _91 { const VALUE: u32 = 91; } +/// Type representing the value 92 for the `Value` trait. +pub struct _92; impl Value for _92 { const VALUE: u32 = 92; } +/// Type representing the value 93 for the `Value` trait. +pub struct _93; impl Value for _93 { const VALUE: u32 = 93; } +/// Type representing the value 94 for the `Value` trait. +pub struct _94; impl Value for _94 { const VALUE: u32 = 94; } +/// Type representing the value 95 for the `Value` trait. +pub struct _95; impl Value for _95 { const VALUE: u32 = 95; } +/// Type representing the value 96 for the `Value` trait. +pub struct _96; impl Value for _96 { const VALUE: u32 = 96; } +/// Type representing the value 97 for the `Value` trait. +pub struct _97; impl Value for _97 { const VALUE: u32 = 97; } +/// Type representing the value 98 for the `Value` trait. +pub struct _98; impl Value for _98 { const VALUE: u32 = 98; } +/// Type representing the value 99 for the `Value` trait. +pub struct _99; impl Value for _99 { const VALUE: u32 = 99; } +/// Type representing the value 100 for the `Value` trait. +pub struct _100; impl Value for _100 { const VALUE: u32 = 100; } +/// Type representing the value 112 for the `Value` trait. +pub struct _112; impl Value for _112 { const VALUE: u32 = 112; } +/// Type representing the value 128 for the `Value` trait. +pub struct _128; impl Value for _128 { const VALUE: u32 = 128; } +/// Type representing the value 160 for the `Value` trait. +pub struct _160; impl Value for _160 { const VALUE: u32 = 160; } +/// Type representing the value 192 for the `Value` trait. +pub struct _192; impl Value for _192 { const VALUE: u32 = 192; } +/// Type representing the value 224 for the `Value` trait. +pub struct _224; impl Value for _224 { const VALUE: u32 = 224; } +/// Type representing the value 256 for the `Value` trait. +pub struct _256; impl Value for _256 { const VALUE: u32 = 256; } +/// Type representing the value 384 for the `Value` trait. +pub struct _384; impl Value for _384 { const VALUE: u32 = 384; } +/// Type representing the value 512 for the `Value` trait. +pub struct _512; impl Value for _512 { const VALUE: u32 = 512; } + diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/uint.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/uint.rs new file mode 100644 index 00000000..ef1adc4a --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/uint.rs @@ -0,0 +1,100 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! An unsigned fixed-size integer. + +pub use primitive_types::{U256, U512}; + +#[cfg(test)] +mod tests { + use super::*; + use codec::{Encode, Decode}; + use sp_serializer as ser; + + macro_rules! test { + ($name: ident, $test_name: ident) => { + #[test] + fn $test_name() { + let tests = vec![ + ($name::from(0), "0x0"), + ($name::from(1), "0x1"), + ($name::from(2), "0x2"), + ($name::from(10), "0xa"), + ($name::from(15), "0xf"), + ($name::from(15), "0xf"), + ($name::from(16), "0x10"), + ($name::from(1_000), "0x3e8"), + ($name::from(100_000), "0x186a0"), + ($name::from(u64::max_value()), "0xffffffffffffffff"), + ($name::from(u64::max_value()) + $name::from(1), "0x10000000000000000"), + ]; + + for (number, expected) in tests { + assert_eq!(format!("{:?}", expected), ser::to_string_pretty(&number)); + assert_eq!(number, ser::from_str(&format!("{:?}", expected)).unwrap()); + } + + // Invalid examples + assert!(ser::from_str::<$name>("\"0x\"").unwrap_err().is_data()); + assert!(ser::from_str::<$name>("\"0xg\"").unwrap_err().is_data()); + assert!(ser::from_str::<$name>("\"\"").unwrap_err().is_data()); + assert!(ser::from_str::<$name>("\"10\"").unwrap_err().is_data()); + assert!(ser::from_str::<$name>("\"0\"").unwrap_err().is_data()); + } + } + } + + test!(U256, test_u256); + + #[test] + fn test_u256_codec() { + let res1 = vec![120, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0]; + let res2 = vec![0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; + + assert_eq!( + U256::from(120).encode(), + res1); + assert_eq!( + U256::max_value().encode(), + res2); + assert_eq!( + U256::decode(&mut &res1[..]), + Ok(U256::from(120))); + assert_eq!( + U256::decode(&mut &res2[..]), + Ok(U256::max_value())); + } + + #[test] + fn test_large_values() { + assert_eq!( + ser::to_string_pretty(&!U256::zero()), + "\"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"" + ); + assert!( + ser::from_str::("\"0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"") + .unwrap_err() + .is_data() + ); + } +} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/vrf.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/vrf.rs new file mode 100644 index 00000000..d392587c --- /dev/null +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/vrf.rs @@ -0,0 +1,99 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! VRF-specifc data types and helpers + +use codec::Encode; +use merlin::Transcript; +use schnorrkel::vrf::{VRFOutput, VRFProof}; +/// An enum whose variants represent possible +/// accepted values to construct the VRF transcript +#[derive(Clone, Encode)] +pub enum VRFTranscriptValue<'a> { + /// Value is an array of bytes + Bytes(&'a [u8]), + /// Value is a u64 integer + U64(u64), +} +/// VRF Transcript data +#[derive(Clone, Encode)] +pub struct VRFTranscriptData<'a> { + /// The transcript's label + pub label: &'static [u8], + /// Additional data to be registered into the transcript + pub items: Vec<(&'static str, VRFTranscriptValue<'a>)>, +} +/// VRF signature data +pub struct VRFSignature { + /// The VRFOutput serialized + pub output: VRFOutput, + /// The calculated VRFProof + pub proof: VRFProof, +} + +/// Construct a `Transcript` object from data. +/// +/// Returns `merlin::Transcript` +pub fn make_transcript(data: VRFTranscriptData) -> Transcript { + let mut transcript = Transcript::new(data.label); + for (label, value) in data.items.into_iter() { + match value { + VRFTranscriptValue::Bytes(bytes) => { + transcript.append_message(label.as_bytes(), &bytes); + }, + VRFTranscriptValue::U64(val) => { + transcript.append_u64(label.as_bytes(), val); + } + } + } + transcript +} + + +#[cfg(test)] +mod tests { + use super::*; + use crate::vrf::VRFTranscriptValue; + use rand::RngCore; + use rand_chacha::{ + rand_core::SeedableRng, + ChaChaRng, + }; + + #[test] + fn transcript_creation_matches() { + let mut orig_transcript = Transcript::new(b"My label"); + orig_transcript.append_u64(b"one", 1); + orig_transcript.append_message(b"two", "test".as_bytes()); + + let new_transcript = make_transcript(VRFTranscriptData { + label: b"My label", + items: vec![ + ("one", VRFTranscriptValue::U64(1)), + ("two", VRFTranscriptValue::Bytes("test".as_bytes())), + ], + }); + let test = |t: Transcript| -> [u8; 16] { + let mut b = [0u8; 16]; + t.build_rng() + .finalize(&mut ChaChaRng::from_seed([0u8;32])) + .fill_bytes(&mut b); + b + }; + debug_assert!(test(orig_transcript) == test(new_transcript)); + } +} From 91ae89446beeed00dff3951b40e8bce9ee7236c8 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Mon, 23 Aug 2021 23:47:26 -0400 Subject: [PATCH 03/13] using frame-metadata and updating to v14 --- Cargo.lock | 1 + core/Cargo.toml | 1 + core/src/decoder.rs | 4 +- core/src/decoder/metadata.rs | 39 +++++++++--- core/src/decoder/metadata/version_08.rs | 34 +++++------ core/src/decoder/metadata/version_09.rs | 36 +++++------ core/src/decoder/metadata/version_10.rs | 36 +++++------ core/src/decoder/metadata/version_11.rs | 30 ++++----- core/src/decoder/metadata/version_12.rs | 61 ++++++++++++++++--- core/src/decoder/storage.rs | 3 +- .../metadatav11/src/lib.rs | 5 +- 11 files changed, 156 insertions(+), 94 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 97a2d0d6..4ee64ebe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -591,6 +591,7 @@ dependencies = [ "pallet-democracy", "pallet-identity", "pallet-indices", + "parity-scale-codec 1.3.7", "parity-scale-codec 2.2.0", "pretty_env_logger", "serde", diff --git a/core/Cargo.toml b/core/Cargo.toml index 66c4688b..0f987772 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -9,6 +9,7 @@ repository = "https://github.com/paritytech/desub" log = "0.4" thiserror = "1.0.22" codec = { version = "2", package = "parity-scale-codec" } +codec1 = { version = "1", package = "parity-scale-codec" } serde = { version = "1", features = ["derive"] } serde_json = { version = "1", features = ["preserve_order"] } onig = { version = "5.0", default-features = false } diff --git a/core/src/decoder.rs b/core/src/decoder.rs index 1e63fbcc..6a3db698 100644 --- a/core/src/decoder.rs +++ b/core/src/decoder.rs @@ -33,8 +33,8 @@ pub use self::storage::{GenericStorage, StorageInfo, StorageKey, StorageKeyData, #[cfg(test)] pub use self::metadata::test_suite; -pub use self::metadata::{Metadata, MetadataError, ModuleIndex, StorageType}; -pub use runtime_metadata_latest::{StorageEntryModifier, StorageEntryType, StorageHasher}; +pub use self::metadata::{Metadata, MetadataError, ModuleIndex, StorageType, StorageHasher, StorageEntryModifier}; +pub use frame_metadata::v14::StorageEntryType; use crate::{ error::Error, diff --git a/core/src/decoder/metadata.rs b/core/src/decoder/metadata.rs index ea9e626a..a2846048 100644 --- a/core/src/decoder/metadata.rs +++ b/core/src/decoder/metadata.rs @@ -35,12 +35,15 @@ mod version_11; mod version_12; mod versions; +pub use frame_metadata::decode_different::DecodeDifferent; + use super::storage::{StorageInfo, StorageLookupTable}; use crate::RustTypeMarker; use codec::{Decode, Encode, EncodeAsRef, HasCompact}; +use codec1::Decode as Decode1; // use codec411::Decode as OldDecode; +use serde::{Serialize, Deserialize}; use primitives::{storage::StorageKey, twox_128}; -use runtime_metadata_latest::{StorageEntryModifier, StorageHasher}; use std::{ collections::{HashMap, HashSet}, @@ -150,35 +153,38 @@ impl Metadata { 0x08 => { log::debug!("Metadata V8"); let meta: runtime_metadata08::RuntimeMetadataPrefixed = - Decode::decode(&mut &*bytes).expect("Decode failed"); + Decode1::decode(&mut &*bytes).expect("Decode failed"); meta.try_into().expect("Conversion failed") } 0x09 => { log::debug!("Metadata V9"); let meta: runtime_metadata09::RuntimeMetadataPrefixed = - Decode::decode(&mut &*bytes).expect("Decode Failed"); + Decode1::decode(&mut &*bytes).expect("Decode Failed"); meta.try_into().expect("Conversion Failed") } 0xA => { log::debug!("Metadata V10"); let meta: runtime_metadata10::RuntimeMetadataPrefixed = - Decode::decode(&mut &*bytes).expect("Decode failed"); + Decode1::decode(&mut &*bytes).expect("Decode failed"); meta.try_into().expect("Conversion failed") } 0xB => { log::debug!("Metadata V11"); let meta: runtime_metadata11::RuntimeMetadataPrefixed = - Decode::decode(&mut &*bytes).expect("Decode failed"); + Decode1::decode(&mut &*bytes).expect("Decode failed"); meta.try_into().expect("Conversion failed") } 0xC => { log::debug!("Metadata V12"); - let meta: runtime_metadata_latest::RuntimeMetadataPrefixed = + let meta: frame_metadata::RuntimeMetadataPrefixed = Decode::decode(&mut &*bytes).expect("Decode failed"); meta.try_into().expect("Conversion failed") - } + }, + 0xD => todo!(), + 0xE => todo!(), + 0xF => todo!(), /* TODO remove panics */ - e => panic!("substrate metadata version {} is unknown, invalid or unsupported", e), + e => panic!("subPrefixedstrate metadata version {} is unknown, invalid or unsupported", e), } } @@ -421,6 +427,17 @@ impl fmt::Display for CallArgMetadata { } } +#[derive(Clone, Debug, PartialEq, Eq, Encode, Decode, Serialize, Deserialize)] +pub enum StorageHasher { + Blake2_128, + Blake2_256, + Blake2_128Concat, + Twox128, + Twox256, + Twox64Concat, + Identity, +} + #[derive(Clone, Debug, PartialEq)] pub enum StorageType { Plain(RustTypeMarker), @@ -439,6 +456,12 @@ pub enum StorageType { }, } +#[derive(Clone, Debug, PartialEq, Eq, Encode, Decode)] +pub enum StorageEntryModifier { + Optional, + Default +} + #[derive(Clone, Debug, PartialEq)] pub struct StorageMetadata { prefix: String, diff --git a/core/src/decoder/metadata/version_08.rs b/core/src/decoder/metadata/version_08.rs index 95419d79..58e9cdb8 100644 --- a/core/src/decoder/metadata/version_08.rs +++ b/core/src/decoder/metadata/version_08.rs @@ -19,7 +19,7 @@ use super::{ CallArgMetadata, CallMetadata, Error, EventArg, Metadata, ModuleEventMetadata, ModuleMetadata, StorageMetadata, - StorageType, + StorageType, StorageEntryModifier as DesubStorageEntryModifier, StorageHasher as DesubStorageHasher }; use crate::regex; use runtime_metadata08::{ @@ -32,7 +32,7 @@ use std::{ }; type DecodeDifferentStr = DecodeDifferent<&'static str, String>; -type LatestDecodeDifferentStr = runtime_metadata_latest::DecodeDifferent<&'static str, String>; +type LatestDecodeDifferentStr = frame_metadata::decode_different::DecodeDifferent<&'static str, String>; impl TryFrom for Metadata { type Error = Error; @@ -142,30 +142,30 @@ fn convert_entry(prefix: String, entry: runtime_metadata08::StorageEntryMetadata } /// Temporary struct for converting between `StorageEntryModifier` -/// and `runtime_metadata_latest::StorageEntryModifier` +/// and `DesubStorageEntryModifier` struct StorageEntryModifierTemp(StorageEntryModifier); -impl From for runtime_metadata_latest::StorageEntryModifier { - fn from(entry: StorageEntryModifierTemp) -> runtime_metadata_latest::StorageEntryModifier { +impl From for DesubStorageEntryModifier { + fn from(entry: StorageEntryModifierTemp) -> DesubStorageEntryModifier { let entry = entry.0; match entry { - StorageEntryModifier::Optional => runtime_metadata_latest::StorageEntryModifier::Optional, - StorageEntryModifier::Default => runtime_metadata_latest::StorageEntryModifier::Default, + StorageEntryModifier::Optional => DesubStorageEntryModifier::Optional, + StorageEntryModifier::Default => DesubStorageEntryModifier::Default, } } } /// Temprorary struct for converting between `StorageHasher` and -/// `runtime_metadata_latest::StorageHasher` +/// `DesubStorageHasher` struct TempStorageHasher(StorageHasher); -impl From for runtime_metadata_latest::StorageHasher { - fn from(hasher: TempStorageHasher) -> runtime_metadata_latest::StorageHasher { +impl From for DesubStorageHasher { + fn from(hasher: TempStorageHasher) -> DesubStorageHasher { let hasher = hasher.0; match hasher { - StorageHasher::Blake2_128 => runtime_metadata_latest::StorageHasher::Blake2_128, - StorageHasher::Blake2_256 => runtime_metadata_latest::StorageHasher::Blake2_256, - StorageHasher::Twox128 => runtime_metadata_latest::StorageHasher::Twox128, - StorageHasher::Twox256 => runtime_metadata_latest::StorageHasher::Twox256, - StorageHasher::Twox64Concat => runtime_metadata_latest::StorageHasher::Twox64Concat, + StorageHasher::Blake2_128 => DesubStorageHasher::Blake2_128, + StorageHasher::Blake2_256 => DesubStorageHasher::Blake2_256, + StorageHasher::Twox128 => DesubStorageHasher::Twox128, + StorageHasher::Twox256 => DesubStorageHasher::Twox256, + StorageHasher::Twox64Concat => DesubStorageHasher::Twox64Concat, } } } @@ -177,8 +177,8 @@ impl From for LatestDecodeDifferentStr { fn from(decode_str: TempDecodeDifferentStr) -> LatestDecodeDifferentStr { let decode_str = decode_str.0; match decode_str { - DecodeDifferent::Encode(b) => runtime_metadata_latest::DecodeDifferent::Encode(b), - DecodeDifferent::Decoded(o) => runtime_metadata_latest::DecodeDifferent::Decoded(o), + DecodeDifferent::Encode(b) => super::DecodeDifferent::Encode(b), + DecodeDifferent::Decoded(o) => super::DecodeDifferent::Decoded(o), } } } diff --git a/core/src/decoder/metadata/version_09.rs b/core/src/decoder/metadata/version_09.rs index 790e6fa8..f3728b38 100644 --- a/core/src/decoder/metadata/version_09.rs +++ b/core/src/decoder/metadata/version_09.rs @@ -19,7 +19,7 @@ use super::{ CallArgMetadata, CallMetadata, Error, EventArg, Metadata, ModuleEventMetadata, ModuleMetadata, StorageMetadata, - StorageType, + StorageType, StorageEntryModifier as DesubStorageEntryModifier, StorageHasher as DesubStorageHasher }; use crate::regex; use runtime_metadata09::{ @@ -32,7 +32,7 @@ use std::{ }; type DecodeDifferentStr = DecodeDifferent<&'static str, String>; -type LatestDecodeDifferentStr = runtime_metadata_latest::DecodeDifferent<&'static str, String>; +type LatestDecodeDifferentStr = super::DecodeDifferent<&'static str, String>; impl TryFrom for Metadata { type Error = Error; @@ -142,31 +142,31 @@ fn convert_entry(prefix: String, entry: runtime_metadata09::StorageEntryMetadata } /// Temporary struct for converting between `StorageEntryModifier` -/// and `runtime_metadata_latest::StorageEntryModifier` +/// and `DesubStorageEntryModifier` struct StorageEntryModifierTemp(StorageEntryModifier); -impl From for runtime_metadata_latest::StorageEntryModifier { - fn from(entry: StorageEntryModifierTemp) -> runtime_metadata_latest::StorageEntryModifier { +impl From for DesubStorageEntryModifier { + fn from(entry: StorageEntryModifierTemp) -> DesubStorageEntryModifier { let entry = entry.0; match entry { - StorageEntryModifier::Optional => runtime_metadata_latest::StorageEntryModifier::Optional, - StorageEntryModifier::Default => runtime_metadata_latest::StorageEntryModifier::Default, + StorageEntryModifier::Optional => DesubStorageEntryModifier::Optional, + StorageEntryModifier::Default => DesubStorageEntryModifier::Default, } } } /// Temprorary struct for converting between `StorageHasher` and -/// `runtime_metadata_latest::StorageHasher` +/// `DesubStorageHasher` struct TempStorageHasher(StorageHasher); -impl From for runtime_metadata_latest::StorageHasher { - fn from(hasher: TempStorageHasher) -> runtime_metadata_latest::StorageHasher { +impl From for DesubStorageHasher { + fn from(hasher: TempStorageHasher) -> DesubStorageHasher { let hasher = hasher.0; match hasher { - StorageHasher::Blake2_128 => runtime_metadata_latest::StorageHasher::Blake2_128, - StorageHasher::Blake2_256 => runtime_metadata_latest::StorageHasher::Blake2_256, - StorageHasher::Blake2_128Concat => runtime_metadata_latest::StorageHasher::Blake2_128Concat, - StorageHasher::Twox128 => runtime_metadata_latest::StorageHasher::Twox128, - StorageHasher::Twox256 => runtime_metadata_latest::StorageHasher::Twox256, - StorageHasher::Twox64Concat => runtime_metadata_latest::StorageHasher::Twox64Concat, + StorageHasher::Blake2_128 => DesubStorageHasher::Blake2_128, + StorageHasher::Blake2_256 => DesubStorageHasher::Blake2_256, + StorageHasher::Blake2_128Concat => DesubStorageHasher::Blake2_128Concat, + StorageHasher::Twox128 => DesubStorageHasher::Twox128, + StorageHasher::Twox256 => DesubStorageHasher::Twox256, + StorageHasher::Twox64Concat => DesubStorageHasher::Twox64Concat, } } } @@ -178,8 +178,8 @@ impl From for LatestDecodeDifferentStr { fn from(decode_str: TempDecodeDifferentStr) -> LatestDecodeDifferentStr { let decode_str = decode_str.0; match decode_str { - DecodeDifferent::Encode(b) => runtime_metadata_latest::DecodeDifferent::Encode(b), - DecodeDifferent::Decoded(o) => runtime_metadata_latest::DecodeDifferent::Decoded(o), + DecodeDifferent::Encode(b) => super::DecodeDifferent::Encode(b), + DecodeDifferent::Decoded(o) => super::DecodeDifferent::Decoded(o), } } } diff --git a/core/src/decoder/metadata/version_10.rs b/core/src/decoder/metadata/version_10.rs index 522aad9b..97ea2659 100644 --- a/core/src/decoder/metadata/version_10.rs +++ b/core/src/decoder/metadata/version_10.rs @@ -16,7 +16,7 @@ use super::{ CallArgMetadata, CallMetadata, Error, EventArg, Metadata, ModuleEventMetadata, ModuleMetadata, StorageMetadata, - StorageType, + StorageType, StorageEntryModifier as DesubStorageEntryModifier, StorageHasher as DesubStorageHasher }; use crate::regex; use runtime_metadata10::{ @@ -29,7 +29,7 @@ use std::{ }; type DecodeDifferentStr = DecodeDifferent<&'static str, String>; -type LatestDecodeDifferentStr = runtime_metadata_latest::DecodeDifferent<&'static str, String>; +type LatestDecodeDifferentStr = super::DecodeDifferent<&'static str, String>; impl TryFrom for Metadata { type Error = Error; @@ -138,31 +138,31 @@ fn convert_entry(prefix: String, entry: runtime_metadata10::StorageEntryMetadata } /// Temporary struct for converting between `StorageEntryModifier` -/// and `runtime_metadata_latest::StorageEntryModifier` +/// and `DesubStorageEntryModifier` struct StorageEntryModifierTemp(StorageEntryModifier); -impl From for runtime_metadata_latest::StorageEntryModifier { - fn from(entry: StorageEntryModifierTemp) -> runtime_metadata_latest::StorageEntryModifier { +impl From for DesubStorageEntryModifier { + fn from(entry: StorageEntryModifierTemp) -> DesubStorageEntryModifier { let entry = entry.0; match entry { - StorageEntryModifier::Optional => runtime_metadata_latest::StorageEntryModifier::Optional, - StorageEntryModifier::Default => runtime_metadata_latest::StorageEntryModifier::Default, + StorageEntryModifier::Optional => DesubStorageEntryModifier::Optional, + StorageEntryModifier::Default => DesubStorageEntryModifier::Default, } } } /// Temprorary struct for converting between `StorageHasher` and -/// `runtime_metadata_latest::StorageHasher` +/// `DesubStorageHasher` struct TempStorageHasher(StorageHasher); -impl From for runtime_metadata_latest::StorageHasher { - fn from(hasher: TempStorageHasher) -> runtime_metadata_latest::StorageHasher { +impl From for DesubStorageHasher { + fn from(hasher: TempStorageHasher) -> DesubStorageHasher { let hasher = hasher.0; match hasher { - StorageHasher::Blake2_128 => runtime_metadata_latest::StorageHasher::Blake2_128, - StorageHasher::Blake2_128Concat => runtime_metadata_latest::StorageHasher::Blake2_128, - StorageHasher::Blake2_256 => runtime_metadata_latest::StorageHasher::Blake2_256, - StorageHasher::Twox128 => runtime_metadata_latest::StorageHasher::Twox128, - StorageHasher::Twox256 => runtime_metadata_latest::StorageHasher::Twox256, - StorageHasher::Twox64Concat => runtime_metadata_latest::StorageHasher::Twox64Concat, + StorageHasher::Blake2_128 => DesubStorageHasher::Blake2_128, + StorageHasher::Blake2_128Concat => DesubStorageHasher::Blake2_128, + StorageHasher::Blake2_256 => DesubStorageHasher::Blake2_256, + StorageHasher::Twox128 => DesubStorageHasher::Twox128, + StorageHasher::Twox256 => DesubStorageHasher::Twox256, + StorageHasher::Twox64Concat => DesubStorageHasher::Twox64Concat, } } } @@ -174,8 +174,8 @@ impl From for LatestDecodeDifferentStr { fn from(decode_str: TempDecodeDifferentStr) -> LatestDecodeDifferentStr { let decode_str = decode_str.0; match decode_str { - DecodeDifferent::Encode(b) => runtime_metadata_latest::DecodeDifferent::Encode(b), - DecodeDifferent::Decoded(o) => runtime_metadata_latest::DecodeDifferent::Decoded(o), + DecodeDifferent::Encode(b) => super::DecodeDifferent::Encode(b), + DecodeDifferent::Decoded(o) => super::DecodeDifferent::Decoded(o), } } } diff --git a/core/src/decoder/metadata/version_11.rs b/core/src/decoder/metadata/version_11.rs index 4085a917..347bc022 100644 --- a/core/src/decoder/metadata/version_11.rs +++ b/core/src/decoder/metadata/version_11.rs @@ -31,7 +31,7 @@ use super::{ CallArgMetadata, CallMetadata, Error, EventArg, ExtrinsicMetadata, Metadata, ModuleEventMetadata, ModuleMetadata, - StorageMetadata, StorageType, + StorageMetadata, StorageType, StorageEntryModifier as DesubStorageEntryModifier, StorageHasher as DesubStorageHasher }; use crate::{regex, RustTypeMarker}; use runtime_metadata11::{ @@ -163,30 +163,30 @@ fn convert_entry(prefix: String, entry: runtime_metadata11::StorageEntryMetadata /// Temporary struct for converting between `StorageEntryModifier` /// and `runtime_metadata11::StorageEntryModifier` struct StorageEntryModifierTemp(StorageEntryModifier); -impl From for runtime_metadata_latest::StorageEntryModifier { - fn from(entry: StorageEntryModifierTemp) -> runtime_metadata_latest::StorageEntryModifier { +impl From for DesubStorageEntryModifier { + fn from(entry: StorageEntryModifierTemp) -> DesubStorageEntryModifier { let entry = entry.0; match entry { - StorageEntryModifier::Optional => runtime_metadata_latest::StorageEntryModifier::Optional, - StorageEntryModifier::Default => runtime_metadata_latest::StorageEntryModifier::Default, + StorageEntryModifier::Optional => DesubStorageEntryModifier::Optional, + StorageEntryModifier::Default => DesubStorageEntryModifier::Default, } } } /// Temprorary struct for converting between `StorageHasher` and -/// `runtime_metadata_latest::StorageHasher` +/// `DesubStorageHasher` struct TempStorageHasher(StorageHasher); -impl From for runtime_metadata_latest::StorageHasher { - fn from(hasher: TempStorageHasher) -> runtime_metadata_latest::StorageHasher { +impl From for DesubStorageHasher { + fn from(hasher: TempStorageHasher) -> DesubStorageHasher { let hasher = hasher.0; match hasher { - StorageHasher::Blake2_128 => runtime_metadata_latest::StorageHasher::Blake2_128, - StorageHasher::Blake2_128Concat => runtime_metadata_latest::StorageHasher::Blake2_128, - StorageHasher::Blake2_256 => runtime_metadata_latest::StorageHasher::Blake2_256, - StorageHasher::Twox128 => runtime_metadata_latest::StorageHasher::Twox128, - StorageHasher::Twox256 => runtime_metadata_latest::StorageHasher::Twox256, - StorageHasher::Twox64Concat => runtime_metadata_latest::StorageHasher::Twox64Concat, - StorageHasher::Identity => runtime_metadata_latest::StorageHasher::Identity, + StorageHasher::Blake2_128 => DesubStorageHasher::Blake2_128, + StorageHasher::Blake2_128Concat => DesubStorageHasher::Blake2_128, + StorageHasher::Blake2_256 => DesubStorageHasher::Blake2_256, + StorageHasher::Twox128 => DesubStorageHasher::Twox128, + StorageHasher::Twox256 => DesubStorageHasher::Twox256, + StorageHasher::Twox64Concat => DesubStorageHasher::Twox64Concat, + StorageHasher::Identity => DesubStorageHasher::Identity, } } } diff --git a/core/src/decoder/metadata/version_12.rs b/core/src/decoder/metadata/version_12.rs index ce936d38..c2dea799 100644 --- a/core/src/decoder/metadata/version_12.rs +++ b/core/src/decoder/metadata/version_12.rs @@ -31,11 +31,21 @@ use super::{ CallArgMetadata, CallMetadata, Error, EventArg, ExtrinsicMetadata, Metadata, ModuleEventMetadata, ModuleMetadata, - StorageMetadata, StorageType, + StorageMetadata, StorageType, StorageEntryModifier as DesubStorageEntryModifier, StorageHasher as + DesubStorageHasher, }; use crate::{regex, RustTypeMarker}; -use runtime_metadata_latest::{ - DecodeDifferent, RuntimeMetadata, RuntimeMetadataPrefixed, StorageEntryType, META_RESERVED, + +use frame_metadata::{ + v12::{ + StorageEntryType, META_RESERVED, + ModuleMetadata as ModuleMetadatav12, + EventMetadata as EventMetadatav12, + StorageEntryMetadata as StorageEntryMetadatav12, + StorageEntryModifier as StorageEntryModifierv12, StorageHasher as StorageHasherv12 + }, + decode_different::DecodeDifferent, + RuntimeMetadataPrefixed, RuntimeMetadata }; use std::{ @@ -92,7 +102,7 @@ fn convert(dd: DecodeDifferent) -> Result Result { +fn convert_module(index: usize, module: ModuleMetadatav12) -> Result { let mut storage_map = HashMap::new(); if let Some(storage) = module.storage { let storage = convert(storage)?; @@ -137,7 +147,7 @@ fn convert_module(index: usize, module: runtime_metadata_latest::ModuleMetadata) }) } -fn convert_event(event: runtime_metadata_latest::EventMetadata) -> Result { +fn convert_event(event: EventMetadatav12) -> Result { let name = convert(event.name)?; let mut arguments = HashSet::new(); for arg in convert(event.arguments)? { @@ -149,19 +159,50 @@ fn convert_event(event: runtime_metadata_latest::EventMetadata) -> Result Result { let default = convert(entry.default)?; let documentation = convert(entry.documentation)?; Ok(StorageMetadata { prefix, - modifier: entry.modifier, + modifier: StorageEntryModifierTemp(entry.modifier).into(), ty: entry.ty.try_into()?, default, documentation: documentation.iter().map(|s| s.to_string()).collect::>(), }) } +/// Temporary struct for converting between `StorageEntryModifier` +/// and `DesubStorageEntryModifier` +struct StorageEntryModifierTemp(StorageEntryModifierv12); +impl From for DesubStorageEntryModifier { + fn from(entry: StorageEntryModifierTemp) -> DesubStorageEntryModifier { + let entry = entry.0; + match entry { + StorageEntryModifierv12::Optional => DesubStorageEntryModifier::Optional, + StorageEntryModifierv12::Default => DesubStorageEntryModifier::Default, + } + } +} + +/// Temprorary struct for converting between `StorageHasher` and +/// `DesubStorageHasher` +struct TempStorageHasher(StorageHasherv12); +impl From for DesubStorageHasher { + fn from(hasher: TempStorageHasher) -> DesubStorageHasher { + let hasher = hasher.0; + match hasher { + StorageHasherv12::Blake2_128 => DesubStorageHasher::Blake2_128, + StorageHasherv12::Blake2_128Concat => DesubStorageHasher::Blake2_128, + StorageHasherv12::Blake2_256 => DesubStorageHasher::Blake2_256, + StorageHasherv12::Twox128 => DesubStorageHasher::Twox128, + StorageHasherv12::Twox256 => DesubStorageHasher::Twox256, + StorageHasherv12::Twox64Concat => DesubStorageHasher::Twox64Concat, + StorageHasherv12::Identity => DesubStorageHasher::Identity, + } + } +} + impl TryFrom for StorageType { type Error = Error; fn try_from(entry: StorageEntryType) -> Result { @@ -174,7 +215,7 @@ impl TryFrom for StorageType { let key = convert(key)?; let value = convert(value)?; StorageType::Map { - hasher, + hasher: TempStorageHasher(hasher).into(), key: regex::parse(&key).ok_or(Error::InvalidType(key))?, value: regex::parse(&value).ok_or(Error::InvalidType(value))?, unused, @@ -185,11 +226,11 @@ impl TryFrom for StorageType { let key2 = convert(key2)?; let value = convert(value)?; StorageType::DoubleMap { - hasher, + hasher: TempStorageHasher(hasher).into(), key1: regex::parse(&key1).ok_or(Error::InvalidType(key1))?, key2: regex::parse(&key2).ok_or(Error::InvalidType(key2))?, value: regex::parse(&value).ok_or(Error::InvalidType(value))?, - key2_hasher, + key2_hasher: TempStorageHasher(key2_hasher).into(), } } }; diff --git a/core/src/decoder/storage.rs b/core/src/decoder/storage.rs index a3b8d818..4138430d 100644 --- a/core/src/decoder/storage.rs +++ b/core/src/decoder/storage.rs @@ -14,9 +14,8 @@ // You should have received a copy of the GNU General Public License // along with substrate-desub. If not, see . -use super::metadata::{ModuleMetadata, StorageMetadata}; +use super::metadata::{ModuleMetadata, StorageMetadata, StorageHasher}; use crate::RustTypeMarker; -use runtime_metadata_latest::StorageHasher; use serde::Serialize; use std::collections::HashMap; use std::sync::Arc; diff --git a/substrate-metadata-versions/metadatav11/src/lib.rs b/substrate-metadata-versions/metadatav11/src/lib.rs index c0eeb76b..b9f82202 100644 --- a/substrate-metadata-versions/metadatav11/src/lib.rs +++ b/substrate-metadata-versions/metadatav11/src/lib.rs @@ -394,9 +394,6 @@ pub struct RuntimeMetadataV11 { pub extrinsic: ExtrinsicMetadata, } -/// The latest version of the metadata. -pub type RuntimeMetadataLastVersion = RuntimeMetadataV11; - /// All metadata about an runtime module. #[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] @@ -418,7 +415,7 @@ impl Into for RuntimeMetadataPrefixed { } } -impl Into for RuntimeMetadataLastVersion { +impl Into for RuntimeMetadataV11 { fn into(self) -> RuntimeMetadataPrefixed { RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V11(self)) } From f7e6dadc496b2e879ee2d6f38b2ca22464c2a2a9 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Thu, 26 Aug 2021 23:09:46 -0400 Subject: [PATCH 04/13] Remove StructUnitOrTuple Removal of this struct simplifies `RustTypeMarker`/`SubstrateType` --- core/src/decoder.rs | 94 +- core/src/lib.rs | 48 +- core/src/substrate_types.rs | 49 +- core/src/substrate_types/remote.rs | 6 +- extras/src/definitions/definitions.json | 2447 +++++++++++++++++++++-- extras/src/definitions/extrinsics.json | 6 +- extras/src/definitions/overrides.json | 786 ++++++-- extras/src/modules.rs | 76 +- extras/src/resolver.rs | 12 +- 9 files changed, 2985 insertions(+), 539 deletions(-) diff --git a/core/src/decoder.rs b/core/src/decoder.rs index 6a3db698..ef57591f 100644 --- a/core/src/decoder.rs +++ b/core/src/decoder.rs @@ -38,7 +38,7 @@ pub use frame_metadata::v14::StorageEntryType; use crate::{ error::Error, - substrate_types::{self, StructField, StructUnitOrTuple, SubstrateType}, + substrate_types::{self, StructField, SubstrateType}, CommonTypes, RustTypeMarker, TypeDetective, }; use codec::{Compact, CompactLen, Decode}; @@ -353,6 +353,7 @@ impl Decoder { self.decode_single(module, spec, new_type, data, cursor, is_compact)? } } + RustTypeMarker::Unit(u) => SubstrateType::Unit(u.to_string()), RustTypeMarker::Struct(v) => { log::trace!("Struct::cursor = {:?}", cursor); let ty = self.decode_structlike(v, module, spec, data, cursor, is_compact)?; @@ -380,18 +381,15 @@ impl Decoder { let index = data[*cursor]; *cursor += 1; let variant = &v[index as usize]; - match &variant.ty { - crate::StructUnitOrTuple::Struct(ref v) => { - let ty = self.decode_structlike(v, module, spec, data, cursor, is_compact)?; - SubstrateType::Enum(StructUnitOrTuple::Struct(ty)) - } - crate::StructUnitOrTuple::Unit(v) => SubstrateType::Enum(StructUnitOrTuple::Unit(v.clone())), - crate::StructUnitOrTuple::Tuple(ref v) => { - let ty = self.decode_single(module, spec, v, data, cursor, is_compact)?; - let name = variant.variant_name.as_ref().expect("Tuple Variant must have a name").clone(); - SubstrateType::Enum(StructUnitOrTuple::Tuple { name, ty: Box::new(ty) }) - } - } + let value = variant.value + .as_ref() + .map(|v| self.decode_single(module, spec, &v, data, cursor, is_compact)) + .transpose()?; + + SubstrateType::Enum(substrate_types::EnumField { + name: variant.name.clone(), + value: value.map(|v| Box::new(v)), + }) } RustTypeMarker::Array { size, ty } => { log::trace!("Array::cursor={}", *cursor); @@ -471,7 +469,10 @@ impl Decoder { log::trace!("Generic Type"); // disregard 'inner' type of a generic self.decode_single(module, spec, outer, data, cursor, is_compact)? - } + }, + RustTypeMarker::Number => { + panic!("number decoding not possible"); + }, RustTypeMarker::U8 => { let num: u8 = if is_compact { let num: Compact = Decode::decode(&mut &data[*cursor..])?; @@ -710,6 +711,7 @@ impl Decoder { ), ]))) } + /* "Data" => { log::trace!("Data::cursor={}", *cursor); let identity_data: pallet_identity::Data = Decode::decode(&mut &data[*cursor..])?; @@ -722,6 +724,7 @@ impl Decoder { *cursor += 1; Ok(Some(SubstrateType::Data(identity_data))) } + */ "Call" | "GenericCall" => { let types = self.decode_call(spec, data, cursor)?; Ok(Some(SubstrateType::Call(types))) @@ -861,7 +864,8 @@ fn decode_old_address(data: &[u8], cursor: &mut usize) -> Result. #[forbid(unsafe_code)] +#[deny(unused)] + pub mod decoder; mod error; pub mod regex; @@ -81,44 +83,19 @@ impl SetField { pub struct EnumField { /// name of the Variant /// if the variant is a Unit enum, it will not have a name - pub variant_name: Option, - pub ty: StructUnitOrTuple, + pub name: String, + pub value: Option } impl EnumField { - pub fn new(variant_name: Option, ty: StructUnitOrTuple) -> Self { - EnumField { variant_name, ty } - } -} - -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] -pub enum StructUnitOrTuple { - Struct(Vec), - Unit(String), - Tuple(RustTypeMarker), -} - -impl From for EnumField { - fn from(s: String) -> EnumField { - EnumField { variant_name: None, ty: StructUnitOrTuple::Unit(s) } + pub fn new(name: String, value: Option) -> Self { + EnumField { name, value } } } impl Display for EnumField { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut _enum = String::from("enum"); - match &self.ty { - StructUnitOrTuple::Struct(s) => { - for s in s.iter() { - _enum.push_str(&format!("{}, ", s)); - } - } - StructUnitOrTuple::Unit(u) => { - _enum.push_str(&format!("{}, ", u)); - } - StructUnitOrTuple::Tuple(v) => _enum.push_str(&format!("{} ", v)), - }; - write!(f, "{}", _enum) + write!(f, "enum[{}:{}]", self.name, self.value.as_ref().unwrap_or(&RustTypeMarker::Null)) } } @@ -180,6 +157,9 @@ pub enum RustTypeMarker { /// name of a type that exists elsewhere in type declarations TypePointer(String), + /// A unit type. A struct or the variant of an enum. + Unit(String), + /// Some Struct /// Field Name -> Field Type Struct(Vec), @@ -190,9 +170,7 @@ pub enum RustTypeMarker { /// A tuple type (max size 32) Tuple(Vec), - /// Some Enum - /// A Rust Enum that contains mixed "Struct" and Unit fields - /// will have unit fields as struct but with the type as "Null" + /// A Rust enum Enum(Vec), /// A sized array @@ -210,6 +188,8 @@ pub enum RustTypeMarker { /// A Generic Type, EX: HeartBeat /// Tuple of (OuterType, InnerType) Generic(Box, Box), + /// A Number for which the bit size is unknown + Number, /// primitive unsigned 8 bit integer U8, /// primitive unsigned 16 bit integer @@ -268,6 +248,7 @@ impl Display for RustTypeMarker { let mut type_marker = String::from(""); match self { RustTypeMarker::TypePointer(t) => type_marker.push_str(t), + RustTypeMarker::Unit(u) => type_marker.push_str(u), RustTypeMarker::Struct(t) => { for substring in t.iter() { type_marker.push_str(&format!("{}, ", substring)) @@ -289,6 +270,7 @@ impl Display for RustTypeMarker { RustTypeMarker::Array { size, ty } => type_marker.push_str(&format!("[{};{}], ", ty, size)), RustTypeMarker::Std(t) => type_marker.push_str(&t.to_string()), RustTypeMarker::Generic(outer, inner) => type_marker.push_str(&format!("{}<{}>", outer, inner)), + RustTypeMarker::Number => type_marker.push_str("number"), RustTypeMarker::U8 => type_marker.push_str("u8"), RustTypeMarker::U16 => type_marker.push_str("u16"), RustTypeMarker::U32 => type_marker.push_str("u32"), diff --git a/core/src/substrate_types.rs b/core/src/substrate_types.rs index b2742857..d9ee6978 100644 --- a/core/src/substrate_types.rs +++ b/core/src/substrate_types.rs @@ -31,7 +31,7 @@ use std::{convert::TryFrom, fmt}; pub type Address = runtime_primitives::MultiAddress; pub type Vote = pallet_democracy::Vote; pub type Conviction = pallet_democracy::Conviction; -pub type Data = pallet_identity::Data; +// pub type Data = pallet_identity::Data; /// A 'stateful' version of [RustTypeMarker](enum.RustTypeMarker.html). /// 'Std' variant is not here like in RustTypeMarker. @@ -58,13 +58,16 @@ pub enum SubstrateType { // u32 and [u8; 32] for its index/id #[serde(with = "RemoteAddress")] Address(Address), - +/* #[serde(with = "RemoteData")] Data(Data), - +*/ /// SignedExtension Type SignedExtra(String), + /// Rust unit type (Struct or enum variant) + Unit(String), + /// vectors, arrays, and tuples #[serde(serialize_with = "crate::util::as_hex")] Composite(Vec), @@ -72,7 +75,7 @@ pub enum SubstrateType { /// C-Like Enum Type Set(SetField), /// Enum - Enum(StructUnitOrTuple), + Enum(EnumField), /// Struct Type Struct(Vec), /// Option Type @@ -143,8 +146,9 @@ impl fmt::Display for SubstrateType { runtime_primitives::MultiAddress::Address32(ary) => write!(f, "Address32: {:?}", ary), runtime_primitives::MultiAddress::Address20(ary) => write!(f, "Address20: {:?}", ary), }, - SubstrateType::Data(d) => write!(f, "{:?}", d), + // SubstrateType::Data(d) => write!(f, "{:?}", d), SubstrateType::SignedExtra(v) => write!(f, "{}", v), + SubstrateType::Unit(u) => write!(f, "{}", u), SubstrateType::Composite(v) => { let mut s = String::from(""); for v in v.iter() { @@ -186,31 +190,22 @@ impl fmt::Display for SubstrateType { } #[derive(Debug, PartialEq, Clone, Serialize)] -#[serde(untagged)] -pub enum StructUnitOrTuple { - Struct(Vec), - Unit(String), - /// vector of variant name -> type - Tuple { - name: String, - ty: Box, - }, +pub struct EnumField { + /// name of the field. + pub name: String, + /// Optional field value. An enum field without a value are unit fields. + pub value: Option> } -impl fmt::Display for StructUnitOrTuple { +impl EnumField { + pub fn new(name: String, value: Option>) -> Self { + Self { name, value } + } +} + +impl fmt::Display for EnumField { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut _enum = String::from(" tuple[ "); - match self { - Self::Struct(v) => { - for val in v.iter() { - _enum.push_str(&format!("{}, ", val)) - } - } - Self::Unit(v) => _enum.push_str(&format!("{}, ", v)), - Self::Tuple { name, ty } => _enum.push_str(&format!(" {}:{} ", name, ty.to_string())), - } - _enum.push_str(" ]"); - write!(f, "{}", _enum) + write!(f, "enum[{}:{}]", self.name, self.value.as_ref().unwrap_or(&Box::new(SubstrateType::Null))) } } diff --git a/core/src/substrate_types/remote.rs b/core/src/substrate_types/remote.rs index 40dd66e3..0a54dc53 100644 --- a/core/src/substrate_types/remote.rs +++ b/core/src/substrate_types/remote.rs @@ -17,7 +17,7 @@ use primitives::crypto::AccountId32; use serde::{Deserialize, Serialize}; -use super::{Address, Conviction, Data, Vote}; +use super::{Address, Conviction, Vote}; // Data #[derive(Serialize, Deserialize)] #[serde(remote = "Address")] @@ -42,6 +42,7 @@ pub struct RemoteVote { pub conviction: Conviction, } +/* /// Either underlying data blob if it is at most 32 bytes, or a hash of it. If the data is greater /// than 32-bytes then it will be truncated when encoding. /// @@ -52,7 +53,7 @@ pub enum RemoteData { /// No data here. None, /// The data is stored directly. - Raw(Vec), + Raw(BoundedVec,), /// Only the Blake2 hash of the data is stored. The preimage of the hash may be retrieved /// through some hash-lookup service. BlakeTwo256([u8; 32]), @@ -66,6 +67,7 @@ pub enum RemoteData { /// through some hash-lookup service. ShaThree256([u8; 32]), } +*/ #[derive(Serialize, Deserialize)] #[serde(remote = "Conviction")] diff --git a/extras/src/definitions/definitions.json b/extras/src/definitions/definitions.json index 69fc50de..484e7d10 100644 --- a/extras/src/definitions/definitions.json +++ b/extras/src/definitions/definitions.json @@ -1,4 +1,49 @@ { + "assets": { + "types": { + "AssetApprovalKey": { + "owner": "AccountId", + "delegate": "AccountId" + }, + "AssetApproval": { + "amount": "TAssetBalance", + "deposit": "TAssetDepositBalance" + }, + "AssetBalance": { + "balance": "TAssetBalance", + "isFrozen": "bool", + "isSufficient": "bool" + }, + "AssetDestroyWitness": { + "accounts": "Compact", + "sufficients": "Compact", + "approvals": "Compact" + }, + "AssetDetails": { + "owner": "AccountId", + "issuer": "AccountId", + "admin": "AccountId", + "freezer": "AccountId", + "supply": "TAssetBalance", + "deposit": "TAssetDepositBalance", + "minBalance": "TAssetBalance", + "isSufficient": "bool", + "accounts": "u32", + "sufficients": "u32", + "approvals": "u32", + "isFrozen": "bool" + }, + "AssetMetadata": { + "deposit": "TAssetDepositBalance", + "name": "Vec", + "symbol": "Vec", + "decimals": "u8", + "isFrozen": "bool" + }, + "TAssetBalance": "u64", + "TAssetDepositBalance": "BalanceOf" + } + }, "attestations": { "types": { "BlockAttestations": { @@ -67,6 +112,10 @@ ] }, "BabeAuthorityWeight": "u64", + "BabeEpochConfiguration": { + "c": "(u64, u64)", + "allowedSlots": "AllowedSlots" + }, "BabeBlockWeight": "u32", "BabeEquivocationProof": { "offender": "AuthorityId", @@ -181,6 +230,11 @@ "All" ] }, + "ReserveData": { + "id": "ReserveIdentifier", + "amount": "Balance" + }, + "ReserveIdentifier": "[u8; 8]", "VestingSchedule": { "offset": "Balance", "perBlock": "Balance", @@ -197,6 +251,118 @@ } } }, + "beefy": { + "types": { + "BeefyCommitment": { + "payload": "BeefyPayload", + "blockNumber": "BlockNumber", + "validatorSetId": "ValidatorSetId" + }, + "BeefyId": "[u8; 33]", + "BeefySignedCommitment": { + "commitment": "BeefyCommitment", + "signatures": "Vec>" + }, + "BeefyNextAuthoritySet": { + "id": "u64", + "len": "u32", + "root": "H256" + }, + "BeefyPayload": "MmrRootHash", + "MmrRootHash": "H256", + "ValidatorSetId": "u64" + } + }, + "bridges": { + "types": { + "BridgedBlockHash": "H256", + "BridgedBlockNumber": "BlockNumber", + "BridgedHeader": "Header", + "CallOrigin": { + "_enum": { + "SourceRoot": "Null", + "TargetAccount": "(AccountId, MultiSigner, MultiSignature)", + "SourceAccount": "AccountId" + } + }, + "ChainId": "[u8; 4]", + "DeliveredMessages": { + "begin": "MessageNonce", + "end": "MessageNonce", + "dispatchResults": "BitVec" + }, + "DispatchFeePayment": { + "_enum": [ + "AtSourceChain", + "AtTargetChain" + ] + }, + "InboundLaneData": { + "relayers": "Vec", + "lastConfirmedNonce": "MessageNonce" + }, + "InboundRelayer": "AccountId", + "InitializationData": { + "header": "Header", + "authorityList": "AuthorityList", + "setId": "SetId", + "isHalted": "bool" + }, + "LaneId": "[u8; 4]", + "MessageData": { + "payload": "Bytes", + "fee": "Balance" + }, + "MessagesDeliveryProofOf": { + "bridgedHeaderHash": "BlockHash", + "storageProof": "Vec", + "lane": "LaneId" + }, + "MessageKey": { + "laneId": "LaneId", + "nonce": "MessageNonce" + }, + "MessageNonce": "u64", + "MessagesProofOf": { + "bridgedHeaderHash": "BridgedBlockHash", + "storageProof": "Vec", + "lane": "LaneId", + "noncesStart": "MessageNonce", + "noncesEnd": "MessageNonce" + }, + "OperatingMode": { + "_enum": [ + "Normal", + "RejectingOutboundMessages", + "Halted" + ] + }, + "OutboundLaneData": { + "latestGeneratedNonce": "MessageNonce", + "latestReceivedNonce": "MessageNonce", + "oldestUnprunedNonce": "MessageNonce" + }, + "OutboundMessageFee": "Balance", + "OutboundPayload": { + "specVersion": "u32", + "weight": "Weight", + "origin": "CallOrigin", + "dispatchFeePayment": "DispatchFeePayment", + "call": "Bytes" + }, + "Parameter": "Null", + "RelayerId": "AccountId", + "UnrewardedRelayer": { + "relayer": "RelayerId", + "messages": "DeliveredMessages" + }, + "UnrewardedRelayersState": { + "unrewardedRelayer_Entries": "MessageNonce", + "messagesInOldestEntry": "MessageNonce", + "totalMessages": "MessageNonce" + } + } + }, "chain": { "types": { "BlockHash": "Hash" @@ -254,12 +420,13 @@ "AliveContractInfo": { "trieId": "TrieId", "storageSize": "u32", - "emptyPairCount": "u32", - "totalPairCount": "u32", + "pairCount": "u32", "codeHash": "CodeHash", "rentAllowance": "Balance", + "rentPaid": "Balance", "deductBlock": "BlockNumber", - "lastWrite": "Option" + "lastWrite": "Option", + "_reserved": "Option" }, "CodeHash": "Hash", "ContractCallRequest": { @@ -313,8 +480,14 @@ "Err": "ContractExecResultErr" } }, + "ContractExecResultTo267": { + "gasConsumed": "u64", + "debugMessage": "Text", + "result": "ContractExecResultResult" + }, "ContractExecResult": { "gasConsumed": "u64", + "gasRequired": "u64", "debugMessage": "Text", "result": "ContractExecResultResult" }, @@ -325,8 +498,16 @@ } }, "ContractStorageKey": "[u8; 32]", + "DeletedContract": { + "pairCount": "u32", + "trieId": "TrieId" + }, + "ExecReturnValue": { + "flags": "u32", + "data": "Bytes" + }, "Gas": "u64", - "HostFnWeights": { + "HostFnWeightsTo264": { "caller": "Weight", "address": "Weight", "gasLeft": "Weight", @@ -373,6 +554,79 @@ "hashBlake2128": "Weight", "hashBlake2128PerByte": "Weight" }, + "HostFnWeights": { + "caller": "Weight", + "address": "Weight", + "gasLeft": "Weight", + "balance": "Weight", + "valueTransferred": "Weight", + "minimumBalance": "Weight", + "tombstoneDeposit": "Weight", + "rentAllowance": "Weight", + "blockNumber": "Weight", + "now": "Weight", + "weightToFee": "Weight", + "gas": "Weight", + "input": "Weight", + "inputPerByte": "Weight", + "return": "Weight", + "returnPerByte": "Weight", + "terminate": "Weight", + "terminatePerCodeByte": "Weight", + "restoreTo": "Weight", + "restoreToPerCallerCodeByte": "Weight", + "restoreToPerTombstoneCodeByte": "Weight", + "restoreToPerDelta": "Weight", + "random": "Weight", + "depositEvent": "Weight", + "depositEventPerTopic": "Weight", + "depositEventPerByte": "Weight", + "setRentAllowance": "Weight", + "setStorage": "Weight", + "setStoragePerByte": "Weight", + "clearStorage": "Weight", + "getStorage": "Weight", + "getStoragePerByte": "Weight", + "transfer": "Weight", + "call": "Weight", + "callPerCodeByte": "Weight", + "callTransferSurcharge": "Weight", + "callPerInputByte": "Weight", + "callPerOutputByte": "Weight", + "instantiate": "Weight", + "instantiatePerCodeByte": "Weight", + "instantiatePerInputByte": "Weight", + "instantiatePerOutputByte": "Weight", + "instantiatePerSaltByte": "Weight", + "hashSha2256": "Weight", + "hashSha2256PerByte": "Weight", + "hashKeccak256": "Weight", + "hashKeccak256PerByte": "Weight", + "hashBlake2256": "Weight", + "hashBlake2256PerByte": "Weight", + "hashBlake2128": "Weight", + "hashBlake2128PerByte": "Weight", + "rentParams": "Weight" + }, + "InstantiateRequest": { + "origin": "AccountId", + "endowment": "Balance", + "gasLimit": "Gas", + "code": "Bytes", + "data": "Bytes", + "salt": "Bytes" + }, + "ContractInstantiateResult": { + "_enum": { + "Ok": "InstantiateReturnValue", + "Err": "Null" + } + }, + "InstantiateReturnValue": { + "result": "ExecReturnValue", + "accountId": "AccountId", + "rentProjection": "Option" + }, "InstructionWeights": { "i64const": "u32", "i64load": "u32", @@ -426,7 +680,7 @@ "i64rotl": "u32", "i64rotr": "u32" }, - "Limits": { + "LimitsTo264": { "eventTopics": "u32", "stackHeight": "u32", "globals": "u32", @@ -437,14 +691,31 @@ "subjectLen": "u32", "codeSize": "u32" }, + "Limits": { + "eventTopics": "u32", + "stackHeight": "u32", + "globals": "u32", + "parameters": "u32", + "memoryPages": "u32", + "tableSize": "u32", + "brTableSize": "u32", + "subjectLen": "u32" + }, "PrefabWasmModule": { "scheduleVersion": "Compact", "initial": "Compact", "maximum": "Compact", - "_reserved": "PrefabWasmModuleReserved", - "code": "Bytes" + "refcount": "Compact", + "_reserved": "Option", + "code": "Bytes", + "originalCodeLen": "u32" + }, + "RentProjection": { + "_enum": { + "EvictionAt": "BlockNumber", + "NoEviction": "Null" + } }, - "PrefabWasmModuleReserved": "Option", "ScheduleTo212": { "version": "u32", "putCodePerByteCost": "Gas", @@ -480,6 +751,13 @@ "enablePrintln": "bool", "maxSubjectLen": "u32" }, + "ScheduleTo264": { + "version": "u32", + "enablePrintln": "bool", + "limits": "LimitsTo264", + "instructionWeights": "InstructionWeights", + "hostFnWeights": "HostFnWeightsTo264" + }, "Schedule": { "version": "u32", "enablePrintln": "bool", @@ -510,7 +788,7 @@ }, "ContractLayoutCell": { "key": "ContractLayoutKey", - "ty": "SiLookupTypeId" + "ty": "Si0LookupTypeId" }, "ContractLayoutEnum": { "dispatchKey": "ContractLayoutKey", @@ -555,7 +833,7 @@ "events": "Vec", "docs": "Vec" }, - "ContractDisplayName": "SiPath", + "ContractDisplayName": "Si0Path", "ContractEventParamSpec": { "name": "Text", "indexed": "bool", @@ -582,34 +860,80 @@ }, "ContractSelector": "[u8; 4]", "ContractTypeSpec": { - "type": "SiLookupTypeId", + "type": "Si0LookupTypeId", "displayName": "ContractDisplayName" }, "ContractProject": { "metadataVersion": "Text", "source": "ContractProjectSource", "contract": "ContractProjectContract", - "types": "Vec", + "types": "Vec", "spec": "ContractContractSpec" }, "ContractProjectContract": { + "_alias": { + "docs": "documentation" + }, "name": "Text", "version": "Text", "authors": "Vec", "description": "Option", - "documentation": "Option", + "docs": "Option", "repository": "Option", "homepage": "Option", "license": "Option" }, "ContractProjectSource": { - "hash": "[u8; 32]", + "_alias": { + "wasmHash": "hash" + }, + "wasmHash": "[u8; 32]", "language": "Text", "compiler": "Text", "wasm": "Raw" } } }, + "crowdloan": { + "types": { + "FundIndex": "u32", + "LastContribution": { + "_enum": { + "Never": "Null", + "PreEnding": "u32", + "Ending": "BlockNumber" + } + }, + "FundInfo": { + "depositor": "AccountId", + "verifier": "Option", + "deposit": "Balance", + "raised": "Balance", + "end": "BlockNumber", + "cap": "Balance", + "lastContribution": "LastContribution", + "firstPeriod": "LeasePeriod", + "lastPeriod": "LeasePeriod", + "trieIndex": "TrieIndex" + }, + "TrieIndex": "u32" + } + }, + "cumulus": { + "types": { + "ConfigData": { + "maxIndividual": "Weight" + }, + "MessageId": "[u8; 32]", + "OverweightIndex": "u64", + "PageCounter": "u32", + "PageIndexData": { + "beginUsed": "PageCounter", + "endUsed": "PageCounter", + "overweightCount": "OverweightIndex" + } + } + }, "democracy": { "types": { "AccountVote": { @@ -762,26 +1086,316 @@ } } }, - "ethereum": { + "eth": { "types": { "EthereumAccountId": "GenericEthereumAccountId", - "EthereumLookupSource": "GenericEthereumLookupSource" + "EthereumLookupSource": "GenericEthereumLookupSource", + "EthereumSignature": "[u8; 65]", + "EthAccount": { + "address": "H160", + "balance": "U256", + "nonce": "U256", + "codeHash": "H256", + "storageHash": "H256", + "accountProof": "Vec", + "storageProof": "Vec" + }, + "EthBlock": { + "header": "EthHeader", + "transactions": "Vec", + "ommers": "Vec" + }, + "EthHeader": { + "parentHash": "H256", + "ommersHash": "H256", + "beneficiary": "H160", + "stateRoot": "H256", + "transactionsRoot": "H256", + "receiptsRoot": "H256", + "logsBloom": "EthBloom", + "difficulty": "U256", + "number": "U256", + "gasLimit": "U256", + "gasUsed": "U256", + "timestamp": "u64", + "extraData": "Bytes", + "mixMash": "H256", + "nonce": "H64" + }, + "EthRichBlock": { + "_alias": { + "blockHash": "hash", + "blockSize": "size" + }, + "blockHash": "Option", + "parentHash": "H256", + "sha3Uncles": "H256", + "author": "H160", + "miner": "H160", + "stateRoot": "H256", + "transactionsRoot": "H256", + "receiptsRoot": "H256", + "number": "Option", + "gasUsed": "U256", + "gasLimit": "U256", + "extraData": "Bytes", + "logsBloom": "EthBloom", + "timestamp": "U256", + "difficulty": "U256", + "totalDifficulty": "Option", + "sealFields": "Vec", + "uncles": "Vec", + "transactions": "Vec", + "blockSize": "Option" + }, + "EthBloom": "H2048", + "EthCallRequest": { + "from": "Option", + "to": "Option", + "gasPrice": "Option", + "gas": "Option", + "value": "Option", + "data": "Option", + "nonce": "Option" + }, + "EthFilter": { + "fromBlock": "Option", + "toBlock": "Option", + "blockHash": "Option", + "address": "Option", + "topics": "Option" + }, + "EthFilterAddress": { + "_enum": { + "Single": "H160", + "Multiple": "Vec", + "Null": "Null" + } + }, + "EthFilterChanges": { + "_enum": { + "Logs": "Vec", + "Hashes": "Vec", + "Empty": "Null" + } + }, + "EthFilterTopic": { + "_enum": { + "Single": "EthFilterTopicInner", + "Multiple": "Vec", + "Null": "Null" + } + }, + "EthFilterTopicEntry": "Option", + "EthFilterTopicInner": { + "_enum": { + "Single": "EthFilterTopicEntry", + "Multiple": "Vec", + "Null": "Null" + } + }, + "EthRichHeader": { + "_alias": { + "blockHash": "hash", + "blockSize": "size" + }, + "blockHash": "Option", + "parentHash": "H256", + "sha3Uncles": "H256", + "author": "H160", + "miner": "H160", + "stateRoot": "H256", + "transactionsRoot": "H256", + "receiptsRoot": "H256", + "number": "Option", + "gasUsed": "U256", + "gasLimit": "U256", + "extraData": "Bytes", + "logsBloom": "EthBloom", + "timestamp": "U256", + "difficulty": "U256", + "sealFields": "Vec", + "blockSize": "Option" + }, + "EthLog": { + "address": "H160", + "topics": "Vec", + "data": "Bytes", + "blockHash": "Option", + "blockNumber": "Option", + "transactionHash": "Option", + "transactionIndex": "Option", + "logIndex": "Option", + "transactionLogIndex": "Option", + "removed": "bool" + }, + "EthReceipt": { + "transactionHash": "Option", + "transactionIndex": "Option", + "blockHash": "Option", + "from": "Option", + "to": "Option", + "blockNumber": "Option", + "cumulativeGasUsed": "U256", + "gasUsed": "Option", + "contractAddress": "Option", + "logs": "Vec", + "root": "Option", + "logsBloom": "EthBloom", + "statusCode": "Option" + }, + "EthStorageProof": { + "key": "U256", + "value": "U256", + "proof": "Vec" + }, + "EthSubKind": { + "_enum": [ + "newHeads", + "logs", + "newPendingTransactions", + "syncing" + ] + }, + "EthSubParams": { + "_enum": { + "None": "Null", + "Logs": "EthFilter" + } + }, + "EthSubResult": { + "_enum": { + "Header": "EthRichHeader", + "Log": "EthLog", + "TransactionHash": "H256", + "SyncState": "EthSyncStatus" + } + }, + "EthSyncInfo": { + "startingBlock": "U256", + "currentBlock": "U256", + "highestBlock": "U256", + "warpChunksAmount": "Option", + "warpChunksProcessed": "Option" + }, + "EthSyncStatus": { + "_enum": { + "Info": "EthSyncInfo", + "None": "Null" + } + }, + "EthTransaction": { + "nonce": "U256", + "gasPrice": "U256", + "gasLimit": "U256", + "action": "EthTransactionAction", + "value": "U256", + "input": "Bytes", + "signature": "EthTransactionSignature" + }, + "EthTransactionSignature": { + "v": "u64", + "r": "H256", + "s": "H256" + }, + "EthTransactionAction": { + "_enum": { + "Call": "H160", + "Create": "Null" + } + }, + "EthTransactionCondition": { + "_enum": { + "block": "u64", + "time": "u64" + } + }, + "EthTransactionRequest": { + "from": "Option", + "to": "Option", + "gasPrice": "Option", + "gas": "Option", + "value": "Option", + "data": "Option", + "nonce": "Option" + }, + "EthTransactionStatus": { + "transactionHash": "H256", + "transactionIndex": "u32", + "from": "H160", + "to": "Option", + "contractAddress": "Option", + "logs": "Vec", + "logsBloom": "EthBloom" + }, + "EthWork": { + "powHash": "H256", + "seedHash": "H256", + "target": "H256", + "number": "Option" + } } }, "evm": { "types": { - "Account": { + "EvmAccount": { "nonce": "u256", "balance": "u256" }, - "Log": { + "EvmLog": { "address": "H160", "topics": "Vec", "data": "Bytes" }, - "Vicinity": { + "EvmVicinity": { "gasPrice": "u256", "origin": "H160" + }, + "ExitError": { + "_enum": { + "StackUnderflow": "Null", + "StackOverflow": "Null", + "InvalidJump": "Null", + "InvalidRange": "Null", + "DesignatedInvalid": "Null", + "CallTooDeep": "Null", + "CreateCollision": "Null", + "CreateContractLimit": "Null", + "OutOfOffset": "Null", + "OutOfGas": "Null", + "OutOfFund": "Null", + "PCUnderflow": "Null", + "CreateEmpty": "Null", + "Other": "Text" + } + }, + "ExitFatal": { + "_enum": { + "NotSupported": "Null", + "UnhandledInterrupt": "Null", + "CallErrorAsFatal": "ExitError", + "Other": "Text" + } + }, + "ExitReason": { + "_enum": { + "Succeed": "ExitSucceed", + "Error": "ExitError", + "Revert": "ExitRevert", + "Fatal": "ExitFatal" + } + }, + "ExitRevert": { + "_enum": [ + "Reverted" + ] + }, + "ExitSucceed": { + "_enum": [ + "Stopped", + "Returned", + "Suicided" + ] } } }, @@ -796,6 +1410,7 @@ "ExtrinsicSignatureV4": "GenericExtrinsicSignatureV4", "ExtrinsicUnknown": "GenericExtrinsicUnknown", "ExtrinsicPayloadUnknown": "GenericExtrinsicPayloadUnknown", + "Era": "ExtrinsicEra", "ImmortalEra": "GenericImmortalEra", "MortalEra": "GenericMortalEra", "AnySignature": "H512", @@ -838,11 +1453,60 @@ "PermissionLatest": "PermissionsV1" } }, + "gilt": { + "types": { + "ActiveGilt": { + "proportion": "Perquintill", + "amount": "Balance", + "who": "AccountId", + "expiry": "BlockNumber" + }, + "ActiveGiltsTotal": { + "frozen": "Balance", + "proportion": "Perquintill", + "index": "ActiveIndex", + "target": "Perquintill" + }, + "ActiveIndex": "u32", + "GiltBid": { + "amount": "Balance", + "who": "AccountId" + } + } + }, "grandpa": { "types": { "AuthorityIndex": "u64", "AuthorityList": "Vec", + "AuthoritySet": { + "currentAuthorities": "AuthorityList", + "setId": "u64", + "pendingStandardChanges": "ForkTreePendingChange", + "pendingForcedChanges": "Vec", + "authoritySetChanges": "AuthoritySetChanges" + }, + "ForkTreePendingChange": { + "roots": "Vec", + "bestFinalizedNumber": "Option" + }, + "ForkTreePendingChangeNode": { + "hash": "BlockHash", + "number": "BlockNumber", + "data": "PendingChange", + "children": "Vec" + }, + "AuthoritySetChange": "(U64, BlockNumber)", + "AuthoritySetChanges": "Vec", "AuthorityWeight": "u64", + "DelayKind": { + "_enum": { + "Finalized": "Null", + "Best": "DelayKindBest" + } + }, + "DelayKindBest": { + "medianLastFinalized": "BlockNumber" + }, "EncodedFinalityProofs": "Bytes", "GrandpaEquivocation": { "_enum": { @@ -864,9 +1528,35 @@ "targetHash": "Hash", "targetNumber": "BlockNumber" }, + "GrandpaCommit": { + "targetHash": "BlockHash", + "targetNumber": "BlockNumber", + "precommits": "Vec" + }, + "GrandpaPrecommit": { + "targetHash": "BlockHash", + "targetNumber": "BlockNumber" + }, + "GrandpaSignedPrecommit": { + "precommit": "GrandpaPrecommit", + "signature": "AuthoritySignature", + "id": "AuthorityId" + }, + "GrandpaJustification": { + "round": "u64", + "commit": "GrandpaCommit", + "votesAncestries": "Vec
" + }, "JustificationNotification": "Bytes", "KeyOwnerProof": "MembershipProof", "NextAuthority": "(AuthorityId, AuthorityWeight)", + "PendingChange": { + "nextAuthorities": "AuthorityList", + "delay": "BlockNumber", + "canonHeight": "BlockNumber", + "canonHash": "BlockHash", + "delayKind": "DelayKind" + }, "PendingPause": { "scheduledAt": "BlockNumber", "delay": "BlockNumber" @@ -988,23 +1678,28 @@ } } }, + "lottery": { + "types": { + "CallIndex": "(u8, u8)", + "LotteryConfig": { + "price": "Balance", + "start": "BlockNumber", + "length": "BlockNumber", + "delay": "BlockNumber", + "repeat": "bool" + } + } + }, "metadata": { "types": { - "DoubleMapTypeV9": { - "hasher": "StorageHasherV9", - "key1": "Type", - "key2": "Type", - "value": "Type", - "key2Hasher": "StorageHasherV9" - }, "ErrorMetadataV9": { "name": "Text", - "documentation": "Vec" + "docs": "Vec" }, "EventMetadataV9": { "name": "Text", "args": "Vec", - "documentation": "Vec" + "docs": "Vec" }, "FunctionArgumentMetadataV9": { "name": "Text", @@ -1013,13 +1708,7 @@ "FunctionMetadataV9": { "name": "Text", "args": "Vec", - "documentation": "Vec" - }, - "MapTypeV9": { - "hasher": "StorageHasherV9", - "key": "Type", - "value": "Type", - "linked": "bool" + "docs": "Vec" }, "MetadataV9": { "modules": "Vec" @@ -1028,7 +1717,7 @@ "name": "Text", "type": "Type", "value": "Bytes", - "documentation": "Vec" + "docs": "Vec" }, "ModuleMetadataV9": { "name": "Text", @@ -1043,7 +1732,7 @@ "modifier": "StorageEntryModifierV9", "type": "StorageEntryTypeV9", "fallback": "Bytes", - "documentation": "Vec" + "docs": "Vec" }, "StorageEntryModifierV9": { "_enum": [ @@ -1055,8 +1744,19 @@ "StorageEntryTypeV9": { "_enum": { "Plain": "Type", - "Map": "MapTypeV9", - "DoubleMap": "DoubleMapTypeV9" + "Map": { + "hasher": "StorageHasherV9", + "key": "Type", + "value": "Type", + "linked": "bool" + }, + "DoubleMap": { + "hasher": "StorageHasherV9", + "key1": "Type", + "key2": "Type", + "value": "Type", + "key2Hasher": "StorageHasherV9" + } } }, "StorageHasherV9": { @@ -1072,23 +1772,10 @@ "prefix": "Text", "items": "Vec" }, - "DoubleMapTypeV10": { - "hasher": "StorageHasherV10", - "key1": "Type", - "key2": "Type", - "value": "Type", - "key2Hasher": "StorageHasherV10" - }, "ErrorMetadataV10": "ErrorMetadataV9", "EventMetadataV10": "EventMetadataV9", "FunctionArgumentMetadataV10": "FunctionArgumentMetadataV9", "FunctionMetadataV10": "FunctionMetadataV9", - "MapTypeV10": { - "hasher": "StorageHasherV10", - "key": "Type", - "value": "Type", - "linked": "bool" - }, "MetadataV10": { "modules": "Vec" }, @@ -1107,13 +1794,24 @@ "modifier": "StorageEntryModifierV10", "type": "StorageEntryTypeV10", "fallback": "Bytes", - "documentation": "Vec" + "docs": "Vec" }, "StorageEntryTypeV10": { "_enum": { "Plain": "Type", - "Map": "MapTypeV10", - "DoubleMap": "DoubleMapTypeV10" + "Map": { + "hasher": "StorageHasherV10", + "key": "Type", + "value": "Type", + "linked": "bool" + }, + "DoubleMap": { + "hasher": "StorageHasherV10", + "key1": "Type", + "key2": "Type", + "value": "Type", + "key2Hasher": "StorageHasherV10" + } } }, "StorageMetadataV10": { @@ -1130,13 +1828,6 @@ "Twox64Concat": null } }, - "DoubleMapTypeV11": { - "hasher": "StorageHasherV11", - "key1": "Type", - "key2": "Type", - "value": "Type", - "key2Hasher": "StorageHasherV11" - }, "ErrorMetadataV11": "ErrorMetadataV10", "EventMetadataV11": "EventMetadataV10", "ExtrinsicMetadataV11": { @@ -1145,12 +1836,6 @@ }, "FunctionArgumentMetadataV11": "FunctionArgumentMetadataV10", "FunctionMetadataV11": "FunctionMetadataV10", - "MapTypeV11": { - "hasher": "StorageHasherV11", - "key": "Type", - "value": "Type", - "linked": "bool" - }, "MetadataV11": { "modules": "Vec", "extrinsic": "ExtrinsicMetadataV11" @@ -1170,13 +1855,24 @@ "modifier": "StorageEntryModifierV11", "type": "StorageEntryTypeV11", "fallback": "Bytes", - "documentation": "Vec" + "docs": "Vec" }, "StorageEntryTypeV11": { "_enum": { "Plain": "Type", - "Map": "MapTypeV11", - "DoubleMap": "DoubleMapTypeV11" + "Map": { + "hasher": "StorageHasherV11", + "key": "Type", + "value": "Type", + "linked": "bool" + }, + "DoubleMap": { + "hasher": "StorageHasherV11", + "key1": "Type", + "key2": "Type", + "value": "Type", + "key2Hasher": "StorageHasherV11" + } } }, "StorageMetadataV11": { @@ -1194,13 +1890,11 @@ "Identity": null } }, - "DoubleMapTypeV12": "DoubleMapTypeV11", "ErrorMetadataV12": "ErrorMetadataV11", "EventMetadataV12": "EventMetadataV11", "ExtrinsicMetadataV12": "ExtrinsicMetadataV11", "FunctionArgumentMetadataV12": "FunctionArgumentMetadataV11", "FunctionMetadataV12": "FunctionMetadataV11", - "MapTypeV12": "MapTypeV11", "MetadataV12": { "modules": "Vec", "extrinsic": "ExtrinsicMetadataV12" @@ -1220,47 +1914,207 @@ "StorageEntryTypeV12": "StorageEntryTypeV11", "StorageMetadataV12": "StorageMetadataV11", "StorageHasherV12": "StorageHasherV11", - "DoubleMapTypeLatest": "DoubleMapTypeV12", - "EventMetadataLatest": "EventMetadataV12", - "ExtrinsicMetadataLatest": "ExtrinsicMetadataV12", - "FunctionArgumentMetadataLatest": "FunctionArgumentMetadataV12", - "FunctionMetadataLatest": "FunctionMetadataV12", - "MapTypeLatest": "MapTypeV12", - "MetadataLatest": "MetadataV12", - "ModuleConstantMetadataLatest": "ModuleConstantMetadataV12", - "ModuleMetadataLatest": "ModuleMetadataV12", - "StorageEntryMetadataLatest": "StorageEntryMetadataV12", - "StorageEntryModifierLatest": "StorageEntryModifierV12", - "StorageEntryTypeLatest": "StorageEntryTypeV12", - "StorageMetadataLatest": "StorageMetadataV12", - "StorageHasher": "StorageHasherV12", - "MetadataAll": { + "ErrorMetadataV13": "ErrorMetadataV12", + "EventMetadataV13": "EventMetadataV12", + "ExtrinsicMetadataV13": "ExtrinsicMetadataV12", + "FunctionArgumentMetadataV13": "FunctionArgumentMetadataV12", + "FunctionMetadataV13": "FunctionMetadataV12", + "MetadataV13": { + "modules": "Vec", + "extrinsic": "ExtrinsicMetadataV13" + }, + "ModuleConstantMetadataV13": "ModuleConstantMetadataV12", + "ModuleMetadataV13": { + "name": "Text", + "storage": "Option", + "calls": "Option>", + "events": "Option>", + "constants": "Vec", + "errors": "Vec", + "index": "u8" + }, + "StorageEntryModifierV13": "StorageEntryModifierV12", + "StorageEntryMetadataV13": { + "name": "Text", + "modifier": "StorageEntryModifierV13", + "type": "StorageEntryTypeV13", + "fallback": "Bytes", + "docs": "Vec" + }, + "StorageEntryTypeV13": { "_enum": { - "V0": "DoNotConstruct", - "V1": "DoNotConstruct", - "V2": "DoNotConstruct", - "V3": "DoNotConstruct", - "V4": "DoNotConstruct", - "V5": "DoNotConstruct", - "V6": "DoNotConstruct", - "V7": "DoNotConstruct", - "V8": "DoNotConstruct", - "V9": "MetadataV9", - "V10": "MetadataV10", - "V11": "MetadataV11", - "V12": "MetadataV12" + "Plain": "Type", + "Map": { + "hasher": "StorageHasherV13", + "key": "Type", + "value": "Type", + "linked": "bool" + }, + "DoubleMap": { + "hasher": "StorageHasherV13", + "key1": "Type", + "key2": "Type", + "value": "Type", + "key2Hasher": "StorageHasherV13" + }, + "NMap": { + "keyVec": "Vec", + "hashers": "Vec", + "value": "Type" + } } + }, + "StorageMetadataV13": { + "prefix": "Text", + "items": "Vec" + }, + "StorageHasherV13": "StorageHasherV12", + "PortableRegistry": "GenericPortableRegistry", + "PortableType": { + "id": "SiLookupTypeId", + "type": "SiType" + }, + "ErrorMetadataV14": { + "name": "Text", + "fields": "Vec", + "index": "u8", + "docs": "Vec", + "args": "Vec" + }, + "EventMetadataV14": { + "name": "Text", + "fields": "Vec", + "index": "u8", + "docs": "Vec", + "args": "Vec" + }, + "FunctionArgumentMetadataV14": "FunctionArgumentMetadataV13", + "FunctionMetadataV14": { + "name": "Text", + "fields": "Vec", + "index": "u8", + "docs": "Vec", + "args": "Vec" + }, + "ExtrinsicMetadataV14": { + "type": "SiLookupTypeId", + "version": "u8", + "signedExtensions": "Vec" + }, + "MetadataV14": { + "lookup": "PortableRegistry", + "pallets": "Vec", + "extrinsic": "ExtrinsicMetadataV14" + }, + "PalletCallMetadataV14": { + "type": "SiLookupTypeId" + }, + "PalletConstantMetadataV14": { + "name": "Text", + "type": "SiLookupTypeId", + "value": "Bytes", + "docs": "Vec" + }, + "PalletErrorMetadataV14": { + "type": "SiLookupTypeId" + }, + "PalletEventMetadataV14": { + "type": "SiLookupTypeId" + }, + "PalletMetadataV14": { + "name": "Text", + "storage": "Option", + "calls": "Option", + "events": "Option", + "constants": "Vec", + "errors": "Option", + "index": "u8" + }, + "PalletStorageMetadataV14": { + "prefix": "Text", + "items": "Vec" + }, + "SignedExtensionMetadataV14": { + "identifier": "Text", + "type": "SiLookupTypeId", + "additionalSigned": "SiLookupTypeId" + }, + "StorageEntryMetadataV14": { + "name": "Text", + "modifier": "StorageEntryModifierV14", + "type": "StorageEntryTypeV14", + "fallback": "Bytes", + "docs": "Vec" + }, + "StorageEntryModifierV14": "StorageEntryModifierV13", + "StorageEntryTypeV14": { + "_enum": { + "Plain": "SiLookupTypeId", + "Map": { + "hashers": "Vec", + "key": "SiLookupTypeId", + "value": "SiLookupTypeId" + } + } + }, + "StorageHasherV14": "StorageHasherV13", + "PalletCallMetadataLatest": "PalletCallMetadataV14", + "PalletConstantMetadataLatest": "PalletConstantMetadataV14", + "PalletErrorMetadataLatest": "PalletErrorMetadataV14", + "PalletEventMetadataLatest": "PalletEventMetadataV14", + "PalletMetadataLatest": "PalletMetadataV14", + "PalletStorageMetadataLatest": "PalletStorageMetadataV14", + "SignedExtensionMetadataLatest": "SignedExtensionMetadataV14", + "ErrorMetadataLatest": "ErrorMetadataV13", + "EventMetadataLatest": "EventMetadataV13", + "ExtrinsicMetadataLatest": "ExtrinsicMetadataV13", + "FunctionArgumentMetadataLatest": "FunctionArgumentMetadataV13", + "FunctionMetadataLatest": "FunctionMetadataV13", + "MetadataLatest": "MetadataV13", + "ModuleConstantMetadataLatest": "ModuleConstantMetadataV13", + "ModuleMetadataLatest": "ModuleMetadataV13", + "StorageEntryMetadataLatest": "StorageEntryMetadataV13", + "StorageEntryModifierLatest": "StorageEntryModifierV13", + "StorageEntryTypeLatest": "StorageEntryTypeV13", + "StorageMetadataLatest": "StorageMetadataV13", + "StorageHasher": "StorageHasherV13", + "MetadataAll": { + "_enum": { + "V0": "DoNotConstruct", + "V1": "DoNotConstruct", + "V2": "DoNotConstruct", + "V3": "DoNotConstruct", + "V4": "DoNotConstruct", + "V5": "DoNotConstruct", + "V6": "DoNotConstruct", + "V7": "DoNotConstruct", + "V8": "DoNotConstruct", + "V9": "MetadataV9", + "V10": "MetadataV10", + "V11": "MetadataV11", + "V12": "MetadataV12", + "V13": "MetadataV13", + "V14": "MetadataV14" + } + } + } + }, + "mmr": { + "types": { + "MmrLeafProof": { + "blockHash": "BlockHash", + "leaf": "Bytes", + "proof": "Bytes" } } }, "offchain": { "types": { "StorageKind": { - "_enum": [ - "__UNUSED", - "PERSISTENT", - "LOCAL" - ] + "_enum": { + "PERSISTENT": 1, + "LOCAL": 2 + } } } }, @@ -1280,18 +2134,93 @@ }, "parachains": { "types": { + "ServiceQuality": { + "_enum": [ + "Ordered", + "Fast" + ] + }, + "HrmpChannel": { + "maxCapacity": "u32", + "maxTotalSize": "u32", + "maxMessageSize": "u32", + "msgCount": "u32", + "totalSize": "u32", + "mqcHead": "Option", + "senderDeposit": "Balance", + "recipientDeposit": "Balance" + }, + "HrmpChannelId": { + "sender": "u32", + "receiver": "u32" + }, + "HrmpOpenChannelRequest": { + "confirmed": "bool", + "age": "SessionIndex", + "senderDeposit": "Balance", + "maxMessageSize": "u32", + "maxCapacity": "u32", + "maxTotalSize": "u32" + }, "ParachainProposal": { "proposer": "AccountId", - "validationFunction": "ValidationCode", - "initialHeadState": "HeadData", + "genesisHead": "HeadData", "validators": "Vec", - "name": "Vec", + "name": "Bytes", "balance": "Balance" }, "RegisteredParachainInfo": { "validators": "Vec", "proposer": "AccountId" }, + "Bidder": { + "_enum": { + "New": "NewBidder", + "Existing": "ParaId" + } + }, + "IncomingParachain": { + "_enum": { + "Unset": "NewBidder", + "Fixed": "IncomingParachainFixed", + "Deploy": "IncomingParachainDeploy" + } + }, + "IncomingParachainDeploy": { + "code": "ValidationCode", + "initialHeadData": "HeadData" + }, + "IncomingParachainFixed": { + "codeHash": "Hash", + "codeSize": "u32", + "initialHeadData": "HeadData" + }, + "NewBidder": { + "who": "AccountId", + "sub": "SubId" + }, + "SubId": "u32", + "AuctionIndex": "u32", + "LeasePeriod": "BlockNumber", + "LeasePeriodOf": "BlockNumber", + "SlotRange": { + "_enum": [ + "ZeroZero", + "ZeroOne", + "ZeroTwo", + "ZeroThree", + "OneOne", + "OneTwo", + "OneThree", + "TwoTwo", + "TwoThree", + "ThreeThree" + ] + }, + "WinningData": "[WinningDataEntry; 10]", + "WinningDataEntry": "Option<(AccountId, ParaId, BalanceOf)>", + "WinnersData": "Vec", + "WinnersDataTuple": "(AccountId, ParaId, BalanceOf, SlotRange)", "AbridgedCandidateReceipt": { "parachainIndex": "ParaId", "relayParent": "Hash", @@ -1301,22 +2230,53 @@ "povBlockHash": "Hash", "commitments": "CandidateCommitments" }, + "AbridgedHostConfiguration": { + "maxCodeSize": "u32", + "maxHeadDataSize": "u32", + "maxUpwardQueueCount": "u32", + "maxUpwardQueueSize": "u32", + "maxUpwardMessageSize": "u32", + "maxUpwardMessageNumPerCandidate": "u32", + "hrmpMaxMessageNumPerCandidate": "u32", + "validationUpgradeFrequency": "BlockNumber", + "validationUpgradeDelay": "BlockNumber" + }, + "AbridgedHrmpChannel": { + "maxCapacity": "u32", + "maxTotalSize": "u32", + "maxMessageSize": "u32", + "msgCount": "u32", + "totalSize": "u32", + "mqcHead": "Option" + }, + "AssignmentId": "AccountId", + "AssignmentKind": { + "_enum": { + "Parachain": "Null", + "Parathread": "(CollatorId, u32)" + } + }, "AttestedCandidate": { "candidate": "AbridgedCandidateReceipt", "validityVotes": "Vec", "validatorIndices": "BitVec" }, - "AuctionIndex": "u32", + "AuthorityDiscoveryId": "AccountId", + "AvailabilityBitfield": "BitVec", + "AvailabilityBitfieldRecord": { + "bitfield": "AvailabilityBitfield", + "submittedTt": "BlockNumber" + }, "BackedCandidate": { "candidate": "CommittedCandidateReceipt", "validityVotes": "Vec", "validatorIndices": "BitVec" }, - "Bidder": { - "_enum": { - "New": "NewBidder", - "Existing": "ParaId" - } + "BufferedSessionChange": { + "applyAt": "BlockNumber", + "validators": "Vec", + "queued": "Vec", + "sessionIndex": "SessionIndex" }, "CandidateCommitments": { "upwardMessages": "Vec", @@ -1327,31 +2287,89 @@ "hrmpWatermark": "BlockNumber" }, "CandidateDescriptor": { - "paraId": "u32", - "relayParent": "Hash", - "collatorId": "Hash", + "paraId": "ParaId", + "relayParent": "RelayChainHash", + "collatorId": "CollatorId", "persistedValidationDataHash": "Hash", "povHash": "Hash", "erasureRoot": "Hash", - "signature": "Signature" + "signature": "CollatorSignature", + "paraHead": "Hash", + "validationCodeHash": "ValidationCodeHash" }, - "CandidatePendingAvailablility": { - "core": "u32", + "CandidateHash": "Hash", + "CandidateInfo": { + "who": "AccountId", + "deposit": "Balance" + }, + "CandidatePendingAvailability": { + "core": "CoreIndex", + "hash": "CandidateHash", "descriptor": "CandidateDescriptor", "availabilityVotes": "BitVec", + "backers": "BitVec", "relayParentNumber": "BlockNumber", - "backedInNumber": "BlockNumber" + "backedInNumber": "BlockNumber", + "backingGroup": "GroupIndex" }, "CandidateReceipt": { "descriptor": "CandidateDescriptor", "commitmentsHash": "Hash" }, - "CollatorId": "[u8; 32]", + "GlobalValidationData": { + "maxCodeSize": "u32", + "maxHeadDataSize": "u32", + "blockNumber": "BlockNumber" + }, + "CollatorId": "H256", "CollatorSignature": "Signature", "CommittedCandidateReceipt": { "descriptor": "CandidateDescriptor", "commitments": "CandidateCommitments" }, + "CoreAssignment": { + "core": "CoreIndex", + "paraId": "ParaId", + "kind": "AssignmentKind", + "groupIdx": "GroupIndex" + }, + "CoreIndex": "u32", + "CoreOccupied": { + "_enum": { + "Parathread": "ParathreadEntry", + "Parachain": "Null" + } + }, + "DisputeStatementSet": { + "candidateHash": "CandidateHash", + "session": "SessionIndex", + "statements": "Vec<(DisputeStatement, ParaValidatorIndex, ValidatorSignature)>" + }, + "MultiDisputeStatementSet": "Vec", + "DisputeStatement": { + "_enum": { + "Valid": "ValidDisputeStatementKind", + "Invalid": "InvalidDisputeStatementKind" + } + }, + "ValidDisputeStatementKind": { + "_enum": { + "Explicit": "Null", + "BackingSeconded": "Hash", + "BackingValid": "Hash", + "ApprovalChecking": "Null" + } + }, + "InvalidDisputeStatementKind": { + "_enum": [ + "Explicit" + ] + }, + "ExplicitDisputeStatement": { + "valid": "bool", + "candidateHash": "CandidateHash", + "session": "SessionIndex" + }, "DoubleVoteReport": { "identity": "ValidatorId", "first": "(Statement, ValidatorSignature)", @@ -1359,49 +2377,75 @@ "proof": "MembershipProof", "signingContext": "SigningContext" }, - "DownwardMessage": { - "_enum": { - "TransferInto": "(AccountId, Balance, Remark)", - "Opaque": "Vec" - } - }, + "DownwardMessage": "Bytes", + "GroupIndex": "u32", "GlobalValidationSchedule": { "maxCodeSize": "u32", "maxHeadDataSize": "u32", "blockNumber": "BlockNumber" }, "HeadData": "Bytes", - "HrmpChannelId": { - "sender": "u32", - "receiver": "u32" - }, - "IncomingParachain": { - "_enum": { - "Unset": "NewBidder", - "Fixed": "IncomingParachainFixed", - "Deploy": "IncomingParachainDeploy" - } - }, - "IncomingParachainFixed": { - "codeHash": "Hash", - "codeSize": "u32", - "initialHeadData": "HeadData" - }, - "IncomingParachainDeploy": { - "code": "ValidationCode", - "initialHeadData": "HeadData" + "HostConfiguration": { + "maxCodeSize": "u32", + "maxHeadDataSize": "u32", + "maxUpwardQueueCount": "u32", + "maxUpwardQueueSize": "u32", + "maxUpwardMessageSize": "u32", + "maxUpwardMessageNumPerCandidate": "u32", + "hrmpMaxMessageNumPerCandidate": "u32", + "validationUpgradeFrequency": "BlockNumber", + "validationUpgradeDelay": "BlockNumber", + "maxPovSize": "u32", + "maxDownwardMessageSize": "u32", + "preferredDispatchableUpwardMessagesStepWeight": "Weight", + "hrmpMaxParachainOutboundChannels": "u32", + "hrmpMaxParathreadOutboundChannels": "u32", + "hrmpOpenRequestTtl": "u32", + "hrmpSenderDeposit": "Balance", + "hrmpRecipientDeposit": "Balance", + "hrmpChannelMaxCapacity": "u32", + "hrmpChannelMaxTotalSize": "u32", + "hrmpMaxParachainInboundChannels": "u32", + "hrmpMaxParathreadInboundChannels": "u32", + "hrmpChannelMaxMessageSize": "u32", + "codeRetentionPeriod": "BlockNumber", + "parathreadCores": "u32", + "parathreadRetries": "u32", + "groupRotationFrequency": "BlockNumber", + "chainAvailabilityPeriod": "BlockNumber", + "threadAvailabilityPeriod": "BlockNumber", + "schedulingLookahead": "u32", + "maxValidatorsPerCore": "Option", + "maxValidators": "Option", + "disputePeriod": "SessionIndex", + "disputePostConclusionAcceptancePeriod": "BlockNumber", + "disputeMaxSpamSlots": "u32", + "disputeConclusionByTimeOutPeriod": "BlockNumber", + "noShowSlots": "u32", + "nDelayTranches": "u32", + "zerothDelayTrancheWidth": "u32", + "neededApprovals": "u32", + "relayVrfModuloSamples": "u32" + }, + "InboundDownwardMessage": { + "pubSentAt": "BlockNumber", + "pubMsg": "DownwardMessage" + }, + "InboundHrmpMessage": { + "sentAt": "BlockNumber", + "data": "Bytes" }, - "LeasePeriod": "BlockNumber", - "LeasePeriodOf": "LeasePeriod", + "InboundHrmpMessages": "Vec", "LocalValidationData": { "parentHead": "HeadData", "balance": "Balance", "codeUpgradeAllowed": "Option" }, - "NewBidder": { - "who": "AccountId", - "sub": "SubId" + "MessageIngestionType": { + "downwardMessages": "Vec", + "horizontalMessages": "BTreeMap" }, + "MessageQueueChain": "RelayChainHash", "OutboundHrmpMessage": { "recipient": "u32", "data": "Bytes" @@ -1413,12 +2457,42 @@ "Root" ] }, + "ParachainInherentData": { + "validationData": "PersistedValidationData", + "relayChainState": "StorageProof", + "downwardMessages": "Vec", + "horizontalMessages": "BTreeMap" + }, + "ParachainsInherentData": { + "bitfields": "SignedAvailabilityBitfields", + "backedCandidates": "Vec", + "disputes": "MultiDisputeStatementSet", + "parentHeader": "Header" + }, + "ParaGenesisArgs": { + "genesisHead": "Bytes", + "validationCode": "Bytes", + "parachain": "bool" + }, "ParaId": "u32", "ParaInfo": { - "scheduling": "Scheduling" + "manager": "AccountId", + "deposit": "Balance", + "locked": "bool" + }, + "ParaLifecycle": { + "_enum": [ + "Onboarding", + "Parathread", + "Parachain", + "UpgradingToParachain", + "DowngradingToParathread", + "OutgoingParathread", + "OutgoingParachain" + ] }, "ParaPastCodeMeta": { - "upgradeTimes": "Vec", + "upgradeTimes": "Vec", "lastPruned": "Option" }, "ParaScheduling": { @@ -1427,8 +2501,35 @@ "Dynamic" ] }, - "RelayChainBlockNumber": "BlockNumber", + "ParathreadClaim": "(ParaId, CollatorId)", + "ParathreadClaimQueue": { + "queue": "Vec", + "nextCoreOffset": "u32" + }, + "ParathreadEntry": { + "claim": "ParathreadClaim", + "retries": "u32" + }, + "ParaValidatorIndex": "u32", + "PersistedValidationData": { + "parentHead": "HeadData", + "relayParentNumber": "RelayChainBlockNumber", + "relayParentStorageRoot": "Hash", + "maxPovSize": "u32" + }, + "QueuedParathread": { + "claim": "ParathreadEntry", + "coreOffset": "u32" + }, + "RelayBlockNumber": "u32", + "RelayChainBlockNumber": "RelayBlockNumber", + "RelayHash": "Hash", + "RelayChainHash": "RelayHash", "Remark": "[u8; 32]", + "ReplacementTimes": { + "expectedAt": "BlockNumber", + "activatedAt": "BlockNumber" + }, "Retriable": { "_enum": { "Never": "Null", @@ -1441,30 +2542,29 @@ "Dynamic" ] }, + "SessionInfo": { + "validators": "Vec", + "discoveryKeys": "Vec", + "assignmentKeys": "Vec", + "validatorGroups": "Vec", + "nCores": "u32", + "zerothDelayTrancheWidth": "u32", + "relayVrfModuloSamples": "u32", + "nDelayTranches": "u32", + "noShowSlots": "u32", + "neededApprovals": "u32" + }, + "SessionInfoValidatorGroup": "Vec", "SignedAvailabilityBitfield": { "payload": "BitVec", - "validatorIndex": "u32", - "signature": "Signature" + "validatorIndex": "ParaValidatorIndex", + "signature": "ValidatorSignature" }, "SignedAvailabilityBitfields": "Vec", "SigningContext": { "sessionIndex": "SessionIndex", "parentHash": "Hash" }, - "SlotRange": { - "_enum": [ - "ZeroZero", - "ZeroOne", - "ZeroTwo", - "ZeroThree", - "OneOne", - "OneTwo", - "OneThree", - "TwoTwo", - "TwoThree", - "ThreeThree" - ] - }, "Statement": { "_enum": { "Never": "Null", @@ -1473,7 +2573,24 @@ "Invalid": "Hash" } }, - "SubId": "u32", + "TransientValidationData": { + "maxCodeSize": "u32", + "maxHeadDataSize": "u32", + "balance": "Balance", + "codeUpgradeAllowed": "Option", + "dmqLength": "u32" + }, + "UpgradeGoAhead": { + "_enum": [ + "Abort", + "GoAhead" + ] + }, + "UpgradeRestriction": { + "_enum": [ + "Present" + ] + }, "UpwardMessage": "Bytes", "ValidationFunctionParams": { "maxCodeSize": "u32", @@ -1481,6 +2598,15 @@ "codeUpgradeAllowed": "Option" }, "ValidationCode": "Bytes", + "ValidationCodeHash": "Hash", + "ValidationData": { + "persisted": "PersistedValidationData", + "transient": "TransientValidationData" + }, + "ValidationDataType": { + "validationData": "ValidationData", + "relayChainState": "Vec" + }, "ValidatorSignature": "Signature", "ValidityAttestation": { "_enum": { @@ -1489,12 +2615,25 @@ "Explicit": "ValidatorSignature" } }, - "WinningData": "[WinningDataEntry; 10]", - "WinningDataEntry": "Option" + "MessagingStateSnapshot": { + "relayDispatchQueueSize": "(u32, u32)", + "egressChannels": "Vec" + }, + "MessagingStateSnapshotEgressEntry": "(ParaId, AbridgedHrmpChannel)", + "SystemInherentData": "ParachainInherentData", + "VecInboundHrmpMessage": "Vec" } }, "payment": { "types": { + "FeeDetails": { + "inclusionFee": "Option" + }, + "InclusionFee": { + "baseFee": "Balance", + "lenFee": "Balance", + "adjustedWeightFee": "Balance" + }, "RuntimeDispatchInfo": { "weight": "Weight", "class": "DispatchClass", @@ -1588,15 +2727,19 @@ "Percent": "UInt<8, Percent>", "Permill": "UInt<32, Permill>", "Perquintill": "UInt<64, Perquintill>", - "AccountId": "GenericAccountId", + "AccountId": "AccountId32", + "AccountId20": "GenericEthereumAccountId", + "AccountId32": "GenericAccountId", "AccountIdOf": "AccountId", "AccountIndex": "GenericAccountIndex", - "Address": "LookupSource", + "Address": "MultiAddress", "AssetId": "u32", "Balance": "UInt<128, Balance>", "BalanceOf": "Balance", "Block": "GenericBlock", "BlockNumber": "u32", + "BlockNumberFor": "BlockNumber", + "BlockNumberOf": "BlockNumber", "Call": "GenericCall", "CallHash": "Hash", "CallHashOf": "CallHash", @@ -1604,7 +2747,13 @@ "digestInterval": "u32", "digestLevels": "u32" }, + "ChangesTrieSignal": { + "_enum": { + "NewConfiguration": "Option" + } + }, "ConsensusEngineId": "GenericConsensusEngineId", + "CodecHash": "Hash", "Digest": { "logs": "Vec" }, @@ -1616,16 +2765,22 @@ "SealV0": "SealV0", "Consensus": "Consensus", "Seal": "Seal", - "PreRuntime": "PreRuntime" + "PreRuntime": "PreRuntime", + "ChangesTrieSignal": "ChangesTrieSignal" } }, "ExtrinsicsWeight": { "normal": "Weight", "operational": "Weight" }, + "H32": "[u8; 4; H32]", + "H64": "[u8; 8; H64]", + "H128": "[u8; 16; H128]", "H160": "[u8; 20; H160]", "H256": "[u8; 32; H256]", "H512": "[u8; 64; H512]", + "H1024": "[u8; 128; H1024]", + "H2048": "[u8; 256; H2048]", "Hash": "H256", "Header": { "parentHash": "Hash", @@ -1634,17 +2789,30 @@ "extrinsicsRoot": "Hash", "digest": "Digest" }, + "HeaderPartial": { + "parentHash": "Hash", + "number": "BlockNumber" + }, "IndicesLookupSource": "GenericLookupSource", "Index": "u32", - "Justification": "Bytes", + "Justification": "(ConsensusEngineId, EncodedJustification)", + "EncodedJustification": "Bytes", + "Justifications": "Vec", "KeyValue": "(StorageKey, StorageData)", "KeyTypeId": "u32", "LockIdentifier": "[u8; 8]", - "LookupSource": "IndicesLookupSource", + "LookupSource": "MultiAddress", "LookupTarget": "AccountId", "ModuleId": "LockIdentifier", "MultiAddress": "GenericMultiAddress", - "Moment": "u64", + "MultiSigner": { + "_enum": { + "Ed25519": "[u8; 32]", + "Sr25519": "[u8; 32]", + "Ecdsa": "[u8; 33]" + } + }, + "Moment": "UInt<64, Moment>", "OpaqueCall": "Bytes", "Origin": "DoNotConstruct", "OriginCaller": { @@ -1652,6 +2820,7 @@ "System": "SystemOrigin" } }, + "PalletId": "LockIdentifier", "PalletsOrigin": "OriginCaller", "PalletVersion": { "major": "u16", @@ -1684,13 +2853,36 @@ "read": "Weight", "write": "Weight" }, - "SignedBlock": { + "SignedBlock": "SignedBlockWithJustifications", + "SignedBlockWithJustification": { + "block": "Block", + "justification": "Option" + }, + "SignedBlockWithJustifications": { "block": "Block", - "justification": "Justification" + "justifications": "Option" }, + "Slot": "u64", "StorageData": "Bytes", + "StorageProof": { + "trieNodes": "Vec" + }, "TransactionPriority": "u64", + "TransactionInfo": { + "_alias": { + "dataSize": "size" + }, + "chunkRoot": "H256", + "contentHash": "H256", + "dataSize": "u32", + "blockChunks": "u32" + }, + "TransactionStorageProof": { + "chunk": "Vec", + "proof": "Vec>" + }, "ValidatorId": "AccountId", + "ValidatorIdOf": "ValidatorId", "Weight": "u64", "WeightMultiplier": "Fixed64", "PreRuntime": "(ConsensusEngineId, Bytes)", @@ -1702,16 +2894,97 @@ }, "scaleinfo": { "types": { + "Si0Field": { + "name": "Option", + "type": "Si0LookupTypeId", + "typeName": "Option", + "docs": "Vec" + }, + "Si0LookupTypeId": "u32", + "Si0Path": "Vec", + "Si0Type": { + "path": "Si0Path", + "params": "Vec", + "def": "Si0TypeDef" + }, + "Si0TypeDef": { + "_enum": { + "Composite": "Si0TypeDefComposite", + "Variant": "Si0TypeDefVariant", + "Sequence": "Si0TypeDefSequence", + "Array": "Si0TypeDefArray", + "Tuple": "Si0TypeDefTuple", + "Primitive": "Si0TypeDefPrimitive", + "Compact": "Si0TypeDefCompact", + "Phantom": "Si0TypeDefPhantom", + "BitSequence": "Si0TypeDefBitSequence" + } + }, + "Si0TypeDefArray": { + "len": "u32", + "type": "Si0LookupTypeId" + }, + "Si0TypeDefBitSequence": { + "bitStoreType": "Si0LookupTypeId", + "bitOrderType": "Si0LookupTypeId" + }, + "Si0TypeDefCompact": { + "type": "Si0LookupTypeId" + }, + "Si0TypeDefComposite": { + "fields": "Vec" + }, + "Si0TypeDefPhantom": "Null", + "Si0TypeDefVariant": { + "variants": "Vec" + }, + "Si0TypeDefPrimitive": { + "_enum": [ + "Bool", + "Char", + "Str", + "U8", + "U16", + "U32", + "U64", + "U128", + "U256", + "I8", + "I16", + "I32", + "I64", + "I128", + "I256" + ] + }, + "Si0TypeDefSequence": { + "type": "Si0LookupTypeId" + }, + "Si0TypeDefTuple": "Vec", + "Si0TypeParameter": { + "name": "Text", + "type": "Option" + }, + "Si0Variant": { + "name": "Text", + "fields": "Vec", + "index": "Option", + "discriminant": "Option", + "docs": "Vec" + }, "SiField": { "name": "Option", - "type": "SiLookupTypeId" + "type": "SiLookupTypeId", + "typeName": "Option", + "docs": "Vec" }, - "SiLookupTypeId": "u32", + "SiLookupTypeId": "Compact", "SiPath": "Vec", "SiType": { "path": "SiPath", - "params": "Vec", - "def": "SiTypeDef" + "params": "Vec", + "def": "SiTypeDef", + "docs": "Vec" }, "SiTypeDef": { "_enum": { @@ -1720,19 +2993,27 @@ "Sequence": "SiTypeDefSequence", "Array": "SiTypeDefArray", "Tuple": "SiTypeDefTuple", - "Primitive": "SiTypeDefPrimitive" + "Primitive": "SiTypeDefPrimitive", + "Compact": "SiTypeDefCompact", + "BitSequence": "SiTypeDefBitSequence", + "Range": "SiTypeDefRange", + "HistoricMetaCompat": "Type" } }, "SiTypeDefArray": { - "len": "u16", + "len": "u32", + "type": "SiLookupTypeId" + }, + "SiTypeDefBitSequence": { + "bitStoreType": "SiLookupTypeId", + "bitOrderType": "SiLookupTypeId" + }, + "SiTypeDefCompact": { "type": "SiLookupTypeId" }, "SiTypeDefComposite": { "fields": "Vec" }, - "SiTypeDefVariant": { - "variants": "Vec" - }, "SiTypeDefPrimitive": { "_enum": [ "Bool", @@ -1752,14 +3033,27 @@ "I256" ] }, + "SiTypeDefRange": { + "start": "SiLookupTypeId", + "end": "SiLookupTypeId", + "inclusive": "bool" + }, "SiTypeDefSequence": { "type": "SiLookupTypeId" }, "SiTypeDefTuple": "Vec", + "SiTypeParameter": { + "name": "Text", + "type": "Option" + }, + "SiTypeDefVariant": { + "variants": "Vec" + }, "SiVariant": { "name": "Text", "fields": "Vec", - "discriminant": "Option" + "index": "u8", + "docs": "Vec" } } }, @@ -1787,6 +3081,7 @@ }, "session": { "types": { + "BeefyKey": "[u8; 33]", "Keys": "SessionKeys4", "SessionKeys1": "(AccountId)", "SessionKeys2": "(AccountId, AccountId)", @@ -1794,6 +3089,15 @@ "SessionKeys4": "(AccountId, AccountId, AccountId, AccountId)", "SessionKeys5": "(AccountId, AccountId, AccountId, AccountId, AccountId)", "SessionKeys6": "(AccountId, AccountId, AccountId, AccountId, AccountId, AccountId)", + "SessionKeys6B": "(AccountId, AccountId, AccountId, AccountId, AccountId, BeefyKey)", + "SessionKeys7": "(AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, AccountId)", + "SessionKeys7B": "(AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, BeefyKey)", + "SessionKeys8": "(AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, AccountId)", + "SessionKeys8B": "(AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, BeefyKey)", + "SessionKeys9": "(AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, AccountId)", + "SessionKeys9B": "(AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, BeefyKey)", + "SessionKeys10": "(AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, AccountId)", + "SessionKeys10B": "(AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, AccountId, BeefyKey)", "FullIdentification": "Exposure", "IdentificationTuple": "(ValidatorId, FullIdentification)", "MembershipProof": { @@ -1848,11 +3152,8 @@ "total": "Points", "individual": "Vec" }, - "ActiveEraInfo": { - "index": "EraIndex", - "start": "Option" - }, - "CompactAssignments": { + "CompactAssignments": "CompactAssignmentsWith16", + "CompactAssignmentsWith16": { "votes1": "Vec<(NominatorIndexCompact, ValidatorIndexCompact)>", "votes2": "Vec<(NominatorIndexCompact, CompactScoreCompact, ValidatorIndexCompact)>", "votes3": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 2], ValidatorIndexCompact)>", @@ -1870,6 +3171,33 @@ "votes15": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 14], ValidatorIndexCompact)>", "votes16": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 15], ValidatorIndexCompact)>" }, + "CompactAssignmentsWith24": { + "votes1": "Vec<(NominatorIndexCompact, ValidatorIndexCompact)>", + "votes2": "Vec<(NominatorIndexCompact, CompactScoreCompact, ValidatorIndexCompact)>", + "votes3": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 2], ValidatorIndexCompact)>", + "votes4": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 3], ValidatorIndexCompact)>", + "votes5": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 4], ValidatorIndexCompact)>", + "votes6": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 5], ValidatorIndexCompact)>", + "votes7": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 6], ValidatorIndexCompact)>", + "votes8": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 7], ValidatorIndexCompact)>", + "votes9": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 8], ValidatorIndexCompact)>", + "votes10": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 9], ValidatorIndexCompact)>", + "votes11": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 10], ValidatorIndexCompact)>", + "votes12": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 11], ValidatorIndexCompact)>", + "votes13": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 12], ValidatorIndexCompact)>", + "votes14": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 13], ValidatorIndexCompact)>", + "votes15": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 14], ValidatorIndexCompact)>", + "votes16": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 15], ValidatorIndexCompact)>", + "votes17": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 16], ValidatorIndexCompact)>", + "votes18": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 17], ValidatorIndexCompact)>", + "votes19": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 18], ValidatorIndexCompact)>", + "votes20": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 19], ValidatorIndexCompact)>", + "votes21": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 20], ValidatorIndexCompact)>", + "votes22": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 21], ValidatorIndexCompact)>", + "votes23": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 22], ValidatorIndexCompact)>", + "votes24": "Vec<(NominatorIndexCompact, [CompactScoreCompact; 23], ValidatorIndexCompact)>" + }, + "CompactAssignmentsTo265": "CompactAssignmentsWith16", "CompactAssignmentsTo257": { "votes1": "Vec<(NominatorIndex, [CompactScore; 0], ValidatorIndex)>", "votes2": "Vec<(NominatorIndex, [CompactScore; 1], ValidatorIndex)>", @@ -1894,9 +3222,17 @@ "_enum": [ "OnChain", "Signed", - "Authority" + "Unsigned" ] }, + "ElectionPhase": { + "_enum": { + "Off": null, + "Signed": null, + "Unsigned": "(bool, BlockNumber)", + "Emergency": null + } + }, "ElectionResult": { "compute": "ElectionCompute", "slotStake": "Balance", @@ -1914,6 +3250,67 @@ "Open": "BlockNumber" } }, + "ExtendedBalance": "u128", + "RawSolution": "RawSolutionWith16", + "RawSolutionWith16": { + "compact": "CompactAssignmentsWith16", + "score": "ElectionScore", + "round": "u32" + }, + "RawSolutionWith24": { + "compact": "CompactAssignmentsWith24", + "score": "ElectionScore", + "round": "u32" + }, + "RawSolutionTo265": "RawSolutionWith16", + "ReadySolution": { + "supports": "SolutionSupports", + "score": "ElectionScore", + "compute": "ElectionCompute" + }, + "RoundSnapshot": { + "voters": "Vec<(AccountId, VoteWeight, Vec)>", + "targets": "Vec" + }, + "SeatHolder": { + "who": "AccountId", + "stake": "Balance", + "deposit": "Balance" + }, + "SignedSubmission": { + "_fallback": "SignedSubmissionTo276", + "who": "AccountId", + "deposit": "Balance", + "solution": "RawSolution", + "reward": "Balance" + }, + "SignedSubmissionTo276": { + "who": "AccountId", + "deposit": "Balance", + "solution": "RawSolution" + }, + "SignedSubmissionOf": "SignedSubmission", + "SolutionOrSnapshotSize": { + "voters": "Compact", + "targets": "Compact" + }, + "SolutionSupport": { + "total": "ExtendedBalance", + "voters": "Vec<(AccountId, ExtendedBalance)>" + }, + "SolutionSupports": "Vec<(AccountId, SolutionSupport)>", + "Supports": "SolutionSupports", + "SubmissionIndicesOf": "BTreeMap", + "Voter": { + "votes": "Vec", + "stake": "Balance", + "deposit": "Balance" + }, + "VoteWeight": "u64", + "ActiveEraInfo": { + "index": "EraIndex", + "start": "Option" + }, "EraIndex": "u32", "EraRewardPoints": { "total": "RewardPoint", @@ -1957,16 +3354,10 @@ "Staked": "Null", "Stash": "Null", "Controller": "Null", - "Account": "AccountId" + "Account": "AccountId", + "None": "Null" } }, - "RewardDestinationTo257": { - "_enum": [ - "Staked", - "Stash", - "Controller" - ] - }, "RewardPoint": "u32", "SlashJournalEntry": { "who": "AccountId", @@ -2023,9 +3414,14 @@ }, "ValidatorIndex": "u16", "ValidatorIndexCompact": "Compact", - "ValidatorPrefs": { + "ValidatorPrefs": "ValidatorPrefsWithBlocked", + "ValidatorPrefsWithCommission": { "commission": "Compact" }, + "ValidatorPrefsWithBlocked": { + "commission": "Compact", + "blocked": "bool" + }, "ValidatorPrefsTo196": { "validatorPayment": "Compact" }, @@ -2038,6 +3434,29 @@ "state": { "types": { "ApiId": "[u8; 8]", + "BlockTrace": { + "blockHash": "Text", + "parentHash": "Text", + "tracingTargets": "Text", + "storageKeys": "Text", + "spans": "Vec", + "events": "Vec" + }, + "BlockTraceEvent": { + "target": "Text", + "data": "BlockTraceEventData", + "parentId": "Option" + }, + "BlockTraceEventData": { + "stringValues": "HashMap" + }, + "BlockTraceSpan": { + "id": "u64", + "parentId": "Option", + "name": "Text", + "target": "Text", + "wasm": "bool" + }, "KeyValueOption": "(StorageKey, Option)", "ReadProof": { "at": "Hash", @@ -2053,9 +3472,22 @@ "apis": "Vec", "transactionVersion": "u32" }, + "RuntimeVersionPartial": { + "specName": "Text", + "specVersion": "u32" + }, "StorageChangeSet": { "block": "Hash", "changes": "Vec" + }, + "TraceBlockResponse": { + "_enum": { + "TraceError": "TraceError", + "BlockTrace": "BlockTrace" + } + }, + "TraceError": { + "error": "Text" } } }, @@ -2074,17 +3506,51 @@ }, "system": { "types": { - "AccountInfo": { + "AccountInfo": "AccountInfoWithTripleRefCount", + "AccountInfoWithRefCountU8": { + "nonce": "Index", + "refcount": "u8", + "data": "AccountData" + }, + "AccountInfoWithRefCount": { + "_fallback": "AccountInfoWithRefCountU8", "nonce": "Index", "refcount": "RefCount", "data": "AccountData" }, + "AccountInfoWithDualRefCount": { + "_fallback": "AccountInfoWithRefCount", + "nonce": "Index", + "consumers": "RefCount", + "providers": "RefCount", + "data": "AccountData" + }, + "AccountInfoWithProviders": "AccountInfoWithDualRefCount", + "AccountInfoWithTripleRefCount": { + "_fallback": "AccountInfoWithDualRefCount", + "nonce": "Index", + "consumers": "RefCount", + "providers": "RefCount", + "sufficients": "RefCount", + "data": "AccountData" + }, "ApplyExtrinsicResult": "Result", - "ChainProperties": { - "ss58Format": "Option", - "tokenDecimals": "Option", - "tokenSymbol": "Option" + "ArithmeticError": { + "_enum": [ + "Underflow", + "Overflow", + "DivisionByZero" + ] }, + "BlockLength": { + "max": "PerDispatchClassU32" + }, + "BlockWeights": { + "baseBlock": "Weight", + "maxBlock": "Weight", + "perClass": "PerDispatchClassWeightsPerClass" + }, + "ChainProperties": "GenericChainProperties", "ChainType": { "_enum": { "Development": "Null", @@ -2093,6 +3559,7 @@ "Custom": "Text" } }, + "ConsumedWeight": "PerDispatchClassWeight", "DigestOf": "Digest", "DispatchClass": { "_enum": [ @@ -2106,7 +3573,11 @@ "Other": "Null", "CannotLookup": "Null", "BadOrigin": "Null", - "Module": "DispatchErrorModule" + "Module": "DispatchErrorModule", + "ConsumerRemaining": "Null", + "NoProviders": "Null", + "Token": "TokenError", + "Arithmetic": "ArithmeticError" } }, "DispatchErrorModule": { @@ -2228,6 +3699,21 @@ "bestHash": "Hash", "bestNumber": "BlockNumber" }, + "PerDispatchClassU32": { + "normal": "u32", + "operational": "u32", + "mandatory": "u32" + }, + "PerDispatchClassWeight": { + "normal": "Weight", + "operational": "Weight", + "mandatory": "Weight" + }, + "PerDispatchClassWeightsPerClass": { + "normal": "WeightPerClass", + "operational": "WeightPerClass", + "mandatory": "WeightPerClass" + }, "Phase": { "_enum": { "ApplyExtrinsic": "u32", @@ -2250,6 +3736,18 @@ "highestBlock": "Option" }, "SystemOrigin": "RawOrigin", + "TokenError": { + "_enum": [ + "NoFunds", + "WouldDie", + "BelowMinimum", + "CannotCreate", + "UnknownAsset", + "Frozen", + "Underflow", + "Overflow" + ] + }, "TransactionValidityError": { "_enum": { "Invalid": "InvalidTransaction", @@ -2262,6 +3760,12 @@ "NoUnsignedValidator": "Null", "Custom": "u8" } + }, + "WeightPerClass": { + "baseExtrinsic": "Weight", + "maxExtrinsic": "Weight", + "maxTotal": "Option", + "reserved": "Option" } } }, @@ -2329,6 +3833,47 @@ "Multiplier": "Fixed128" } }, + "uniques": { + "types": { + "ClassId": "u32", + "InstanceId": "u32", + "DepositBalance": "Balance", + "DepositBalanceOf": "Balance", + "ClassDetails": { + "owner": "AccountId", + "issuer": "AccountId", + "admin": "AccountId", + "freezer": "AccountId", + "totalDeposit": "DepositBalance", + "freeHolding": "bool", + "instances": "u32", + "instanceMetadatas": "u32", + "attributes": "u32", + "isFrozen": "bool" + }, + "DestroyWitness": { + "instances": "Compact", + "instanceMetadatas": "Compact", + "attributes": "Compact" + }, + "InstanceDetails": { + "owner": "AccountId", + "approved": "Option", + "isFrozen": "bool", + "deposit": "DepositBalance" + }, + "ClassMetadata": { + "deposit": "DepositBalance", + "data": "Vec", + "isFrozen": "bool" + }, + "InstanceMetadata": { + "deposit": "DepositBalance", + "data": "Vec", + "isFrozen": "bool" + } + } + }, "utility": { "types": { "Multisig": { @@ -2351,5 +3896,479 @@ "startingBlock": "BlockNumber" } } + }, + "xcm": { + "types": { + "BodyId": { + "_enum": { + "Unit": "Null", + "Named": "Vec", + "Index": "Compact", + "Executive": "Null", + "Technical": "Null", + "Legislative": "Null", + "Judicial": "Null" + } + }, + "BodyPart": { + "_enum": { + "Voice": "Null", + "Members": "Compact", + "Fraction": { + "nom": "Compact", + "denom": "Compact" + }, + "AtLeastProportion": { + "nom": "Compact", + "denom": "Compact" + }, + "MoreThanProportion": { + "nom": "Compact", + "denom": "Compact" + } + } + }, + "Junction": { + "_enum": { + "Parent": "Null", + "Parachain": "Compact", + "AccountId32": { + "network": "NetworkId", + "id": "AccountId" + }, + "AccountIndex64": { + "network": "NetworkId", + "index": "Compact" + }, + "AccountKey20": { + "network": "NetworkId", + "key": "[u8; 20]" + }, + "PalletInstance": "u8", + "GeneralIndex": "Compact", + "GeneralKey": "Vec", + "OnlyChild": "Null", + "Plurality": { + "id": "BodyId", + "part": "BodyPart" + } + } + }, + "NetworkId": { + "_enum": { + "Any": "Null", + "Named": "Vec", + "Polkadot": "Null", + "Kusama": "Null" + } + }, + "XcmAssetId": { + "_enum": { + "Concrete": "MultiLocation", + "Abstract": "Bytes" + } + }, + "AssetInstance": "AssetInstanceV1", + "AssetInstanceV0": { + "_enum": { + "Undefined": "Null", + "Index8": "u8", + "Index16": "Compact", + "Index32": "Compact", + "Index64": "Compact", + "Index128": "Compact", + "Array4": "[u8; 4]", + "Array8": "[u8; 8]", + "Array16": "[u8; 16]", + "Array32": "[u8; 32]", + "Blob": "Vec" + } + }, + "AssetInstanceV1": { + "_enum": { + "Undefined": "Null", + "Index": "Compact", + "Array4": "[u8; 4]", + "Array8": "[u8; 8]", + "Array16": "[u8; 16]", + "Array32": "[u8; 32]", + "Blob": "Bytes" + } + }, + "Fungibility": { + "_enum": { + "Fungible": "u128", + "NonFungible": "AssetInstance" + } + }, + "InboundStatus": { + "_enum": [ + "Ok", + "Suspended" + ] + }, + "OutboundStatus": { + "_enum": [ + "Ok", + "Suspended" + ] + }, + "MultiAssetFilter": "MultiAssetFilterV1", + "MultiAssetFilterV1": { + "_enum": { + "Definite": "MultiAssetsV1", + "Wild": "WildMultiAssetV1" + } + }, + "MultiAsset": "MultiAssetV1", + "MultiAssetV0": { + "_enum": { + "None": "Null", + "All": "Null", + "AllFungible": "Null", + "AllNonFungible": "Null", + "AllAbstractFungible": "Vec", + "AllAbstractNonFungible": "Vec", + "AllConcreteFungible": "MultiLocation", + "AllConcreteNonFungible": "MultiLocation", + "AbstractFungible": { + "id": "Vec", + "instance": "Compact" + }, + "AbstractNonFungible": { + "class": "Vec", + "instance": "AssetInstance" + }, + "ConcreteFungible": { + "id": "MultiLocation", + "amount": "Compact" + }, + "ConcreteNonFungible": { + "class": "MultiLocation", + "instance": "AssetInstance" + } + } + }, + "MultiAssetV1": { + "id": "XcmAssetId", + "fungibility": "Fungibility" + }, + "MultiAssets": "Vec", + "MultiAssetsV1": "Vec", + "WildFungibility": { + "_enum": [ + "Fungible", + "NonFungible" + ] + }, + "WildMultiAsset": "WildMultiAssetV1", + "WildMultiAssetV1": { + "_enum": { + "All": "Null", + "AllOf": { + "id": "XcmAssetId", + "fungibility": "WildFungibility" + } + } + }, + "XcmOrigin": { + "_enum": { + "Xcm": "MultiLocation" + } + }, + "Xcm": "XcmV1", + "XcmV0": { + "_enum": { + "WithdrawAsset": { + "assets": "Vec", + "effects": "Vec" + }, + "ReserveAssetDeposit": { + "assets": "Vec", + "effects": "Vec" + }, + "ReceiveTeleportedAsset": { + "assets": "Vec", + "effects": "Vec" + }, + "QueryResponse": { + "queryId": "Compact", + "response": "XcmResponse" + }, + "TransferAsset": { + "assets": "Vec", + "dest": "MultiLocationV0" + }, + "TransferReserveAsset": { + "assets": "Vec", + "dest": "MultiLocationV0", + "effects": "Vec" + }, + "Transact": { + "originType": "XcmOriginKind", + "requireWeightAtMost": "u64", + "call": "DoubleEncodedCall" + }, + "HrmpNewChannelOpenRequest": { + "sender": "Compact", + "maxMessageSize": "Compact", + "maxCapacity": "Compact" + }, + "HrmpChannelAccepted": { + "recipient": "Compact" + }, + "HrmpChannelClosing": { + "initiator": "Compact", + "sender": "Compact", + "recipient": "Compact" + }, + "RelayedFrom": { + "who": "MultiLocationV0", + "message": "XcmV0" + } + } + }, + "XcmV1": { + "_enum": { + "WithdrawAsset": { + "Vassets": "MultiAssetsV1", + "effects": "Vec" + }, + "ReserveAssetDeposit": { + "Vassets": "MultiAssetsV1", + "effects": "Vec" + }, + "ReceiveTeleportedAsset": { + "Vassets": "MultiAssetsV1", + "effects": "Vec" + }, + "QueryResponse": { + "queryId": "Compact", + "response": "XcmResponse" + }, + "TransferAsset": { + "Vassets": "MultiAssetsV1", + "dest": "MultiLocationV1" + }, + "TransferReserveAsset": { + "Vassets": "MultiAssetsV1", + "dest": "MultiLocationV1", + "effects": "Vec" + }, + "Transact": { + "originType": "XcmOriginKind", + "requireWeightAtMost": "u64", + "call": "DoubleEncodedCall" + }, + "HrmpNewChannelOpenRequest": { + "sender": "Compact", + "maxMessageSize": "Compact", + "maxCapacity": "Compact" + }, + "HrmpChannelAccepted": { + "recipient": "Compact" + }, + "HrmpChannelClosing": { + "initiator": "Compact", + "sender": "Compact", + "recipient": "Compact" + }, + "RelayedFrom": { + "who": "MultiLocationV1", + "message": "XcmV1" + } + } + }, + "XcmpMessageFormat": { + "_enum": [ + "ConcatenatedVersionedXcm", + "ConcatenatedEncodedBlob", + "Signals" + ] + }, + "XcmOrder": "XcmOrderV1", + "XcmOrderV0": { + "_enum": { + "Null": "Null", + "DepositAsset": { + "assets": "Vec", + "dest": "MultiLocationV0" + }, + "DepositReserveAsset": { + "assets": "Vec", + "dest": "MultiLocationV0", + "effects": "Vec" + }, + "ExchangeAsset": { + "give": "Vec", + "receive": "Vec" + }, + "InitiateReserveWithdraw": { + "assets": "Vec", + "reserve": "MultiLocationV0", + "effects": "Vec" + }, + "InitiateTeleport": { + "assets": "Vec", + "dest": "MultiLocationV0", + "effects": "Vec" + }, + "QueryHolding": { + "queryId": "Compact", + "dest": "MultiLocationV0", + "assets": "Vec" + }, + "BuyExecution": { + "fees": "MultiAsset", + "weight": "u64", + "debt": "u64", + "haltOnError": "bool", + "xcm": "Vec" + } + } + }, + "XcmOrderV1": { + "_enum": { + "Noop": "Null", + "DepositAsset": { + "assets": "MultiAssetFilterV1", + "maxAssets": "u32", + "beneficiary": "MultiLocationV1" + }, + "DepositReserveAsset": { + "assets": "MultiAssetFilterV1", + "maxAssets": "u32", + "dest": "MultiLocationV1", + "effects": "Vec" + }, + "ExchangeAsset": { + "give": "MultiAssetFilterV1", + "receive": "MultiAssetsV1" + }, + "InitiateReserveWithdraw": { + "assets": "MultiAssetFilterV1", + "reserve": "MultiLocationV1", + "effects": "Vec" + }, + "InitiateTeleport": { + "assets": "MultiAssetFilterV1", + "dest": "MultiLocationV1", + "effects": "Vec" + }, + "QueryHolding": { + "queryId": "Compact", + "dest": "MultiLocationV1", + "assets": "MultiAssetFilterV1" + }, + "BuyExecution": { + "fees": "MultiAsset", + "weight": "u64", + "debt": "u64", + "haltOnError": "bool", + "orders": "Vec", + "instructions": "Vec" + } + } + }, + "DoubleEncodedCall": { + "encoded": "Vec" + }, + "XcmOriginKind": { + "_enum": [ + "Native", + "SovereignAccount", + "Superuser", + "Xcm" + ] + }, + "XcmResponse": { + "_enum": { + "Assets": "Vec" + } + }, + "XcmError": { + "_enum": { + "Undefined": "Null", + "Overflow": "Null", + "Unimplemented": "Null", + "UnhandledXcmVersion": "Null", + "UnhandledXcmMessage": "Null", + "UnhandledEffect": "Null", + "EscalationOfPrivilege": "Null", + "UntrustedReserveLocation": "Null", + "UntrustedTeleportLocation": "Null", + "DestinationBufferOverflow": "Null", + "SendFailed": "Null", + "CannotReachDestination": "(MultiLocation, Xcm)", + "MultiLocationFull": "Null", + "FailedToDecode": "Null", + "BadOrigin": "Null", + "ExceedsMaxMessageSize": "Null", + "FailedToTransactAsset": "Null", + "WeightLimitReached": "Weight", + "Wildcard": "Null", + "TooMuchWeightRequired": "Null", + "NotHoldingFees": "Null", + "WeightNotComputable": "Null", + "Barrier": "Null", + "NotWithdrawable": "Null", + "LocationCannotHold": "Null", + "TooExpensive": "Null" + } + }, + "MultiLocationV0": "MultiLocation", + "MultiLocationV1": "MultiLocation", + "MultiLocation": { + "_enum": { + "Here": "Null", + "X1": "Junction", + "X2": "(Junction, Junction)", + "X3": "(Junction, Junction, Junction)", + "X4": "(Junction, Junction, Junction, Junction)", + "X5": "(Junction, Junction, Junction, Junction, Junction)", + "X6": "(Junction, Junction, Junction, Junction, Junction, Junction)", + "X7": "(Junction, Junction, Junction, Junction, Junction, Junction, Junction)", + "X8": "(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction)" + } + }, + "Outcome": { + "_enum": { + "Complete": "Weight", + "Incomplete": "(Weight, XcmError)", + "Error": "XcmError" + } + }, + "QueueConfigData": { + "suspendThreshold": "u32", + "dropThreshold": "u32", + "resumeThreshold": "u32", + "thresholdWeight": "Weight", + "weightRestrictDecay": "Weight" + }, + "VersionedMultiAsset": { + "_enum": { + "V0": "MultiAssetV0", + "V1": "MultiAssetV1" + } + }, + "VersionedMultiAssets": { + "_enum": { + "V0": "Vec", + "V1": "MultiAssetsV1" + } + }, + "VersionedMultiLocation": { + "_enum": { + "V0": "MultiLocationV0", + "V1": "MultiLocationV1" + } + }, + "VersionedXcm": { + "_enum": { + "V0": "XcmV0", + "V1": "XcmV1" + } + } + } } } diff --git a/extras/src/definitions/extrinsics.json b/extras/src/definitions/extrinsics.json index f1710713..0d9998a7 100644 --- a/extras/src/definitions/extrinsics.json +++ b/extras/src/definitions/extrinsics.json @@ -24,7 +24,7 @@ "GenericAddress": "LookupSource" }, "kusama": [ - { + { "minmax": [ 0, 1006 @@ -35,7 +35,7 @@ "AnySignature": "H512", "TakeFees": "empty_extra", "SignedExtra": "(OnlyStakingAndClaims, CheckSpecVersion, CheckGenesis, CheckEra, CheckNonce, CheckWeight, TakeFees)" - } + } }, { "minmax": [ @@ -51,7 +51,7 @@ { "minmax": [ 1046, - null + null ], "types": { "Address": "AccountId", diff --git a/extras/src/definitions/overrides.json b/extras/src/definitions/overrides.json index 11d7f2be..f7ea1321 100644 --- a/extras/src/definitions/overrides.json +++ b/extras/src/definitions/overrides.json @@ -1,14 +1,38 @@ { "TYPES_MODULES": { + "assets": { + "Approval": "AssetApproval", + "ApprovalKey": "AssetApprovalKey", + "Balance": "TAssetBalance", + "DestroyWitness": "AssetDestroyWitness" + }, "babe": { "EquivocationProof": "BabeEquivocationProof" }, "balances": { "Status": "BalanceStatus" }, + "beefy": { + "AuthorityId": "BeefyId" + }, "contracts": { "StorageKey": "ContractStorageKey" }, + "electionProviderMultiPhase": { + "Phase": "ElectionPhase" + }, + "ethereum": { + "Block": "EthBlock", + "Header": "EthHeader", + "Receipt": "EthReceipt", + "Transaction": "EthTransaction", + "TransactionStatus": "EthTransactionStatus" + }, + "evm": { + "Account": "EvmAccount", + "Log": "EvmLog", + "Vicinity": "EvmVicinity" + }, "grandpa": { "Equivocation": "GrandpaEquivocation", "EquivocationProof": "GrandpaEquivocationProof" @@ -16,15 +40,42 @@ "identity": { "Judgement": "IdentityJudgement" }, + "inclusion": { + "ValidatorIndex": "ParaValidatorIndex" + }, + "paraInclusion": { + "ValidatorIndex": "ParaValidatorIndex" + }, + "paraScheduler": { + "ValidatorIndex": "ParaValidatorIndex" + }, + "paraShared": { + "ValidatorIndex": "ParaValidatorIndex" + }, "parachains": { "Id": "ParaId" }, + "parasInclusion": { + "ValidatorIndex": "ParaValidatorIndex" + }, + "parasScheduler": { + "ValidatorIndex": "ParaValidatorIndex" + }, + "parasShared": { + "ValidatorIndex": "ParaValidatorIndex" + }, "proposeParachain": { "Proposal": "ParachainProposal" }, "proxy": { "Announcement": "ProxyAnnouncement" }, + "scheduler": { + "ValidatorIndex": "ParaValidatorIndex" + }, + "shared": { + "ValidatorIndex": "ParaValidatorIndex" + }, "society": { "Judgement": "SocietyJudgement", "Vote": "SocietyVote" @@ -34,25 +85,32 @@ }, "treasury": { "Proposal": "TreasuryProposal" + }, + "xcm": { + "AssetId": "XcmAssetId" + }, + "xcmPallet": { + "AssetId": "XcmAssetId" } }, "TYPES_SPEC": { "centrifuge-chain": [ { "minmax": [ - 229, - 234 + 240, + 999 ], "types": { - "Address": "LookupSource", - "LookupSource": "IndicesLookupSource", "AnchorData": { "anchoredBlock": "u64", "docRoot": "H256", "id": "H256" }, - "ChainId": "u8", - "DepositNonce": "u64", + "PreCommitData": { + "expirationBlock": "u64", + "identity": "H256", + "signingRoot": "H256" + }, "Fee": { "key": "Hash", "price": "Balance" @@ -63,39 +121,61 @@ "signatories": "Vec", "threshold": "u16" }, - "Multiplier": "Fixed64", - "PreCommitData": { - "expirationBlock": "u64", - "identity": "H256", - "signingRoot": "H256" + "ChainId": "u8", + "DepositNonce": "u64", + "ResourceId": "[u8; 32]", + "chainbridge::ChainId": "u8", + "RegistryId": "H160", + "TokenId": "U256", + "AssetId": { + "registryId": "RegistryId", + "tokenId": "TokenId" + }, + "AssetInfo": { + "metadata": "Bytes" + }, + "MintInfo": { + "anchorId": "Hash", + "proofs": "Vec", + "staticHashes": "[Hash; 3]" }, "Proof": { "leafHash": "H256", "sortedHashes": "H256" }, - "ResourceId": "[u8; 32]", - "chainbridge::ChainId": "u8", - "RefCount": "RefCountTo259", - "ReferendumInfo": "ReferendumInfoTo239", - "StakingLedger": "StakingLedgerTo240", - "Weight": "u32" + "ProofMint": { + "hashes": "Vec", + "property": "Bytes", + "salt": "[u8; 32]", + "value": "Bytes" + }, + "RegistryInfo": { + "fields": "Vec", + "ownerCanBurn": "bool" + }, + "AccountInfo": "AccountInfoWithRefCount", + "Address": "LookupSource", + "LookupSource": "IndicesLookupSource", + "Multiplier": "Fixed64", + "RefCount": "RefCountTo259" } }, { "minmax": [ - 235, + 1000, null ], "types": { - "Address": "LookupSource", - "LookupSource": "IndicesLookupSource", "AnchorData": { "anchoredBlock": "u64", "docRoot": "H256", "id": "H256" }, - "ChainId": "u8", - "DepositNonce": "u64", + "PreCommitData": { + "expirationBlock": "u64", + "identity": "H256", + "signingRoot": "H256" + }, "Fee": { "key": "Hash", "price": "Balance" @@ -106,19 +186,38 @@ "signatories": "Vec", "threshold": "u16" }, - "Multiplier": "Fixed64", - "PreCommitData": { - "expirationBlock": "u64", - "identity": "H256", - "signingRoot": "H256" + "ChainId": "u8", + "DepositNonce": "u64", + "ResourceId": "[u8; 32]", + "chainbridge::ChainId": "u8", + "RegistryId": "H160", + "TokenId": "U256", + "AssetId": { + "registryId": "RegistryId", + "tokenId": "TokenId" + }, + "AssetInfo": { + "metadata": "Bytes" + }, + "MintInfo": { + "anchorId": "Hash", + "proofs": "Vec", + "staticHashes": "[Hash; 3]" }, "Proof": { "leafHash": "H256", "sortedHashes": "H256" }, - "ResourceId": "[u8; 32]", - "chainbridge::ChainId": "u8", - "RefCount": "RefCountTo259" + "ProofMint": { + "hashes": "Vec", + "property": "Bytes", + "salt": "[u8; 32]", + "value": "Bytes" + }, + "RegistryInfo": { + "fields": "Vec", + "ownerCanBurn": "bool" + } } } ], @@ -129,18 +228,21 @@ 1031 ], "types": { + "AccountInfo": "AccountInfoWithRefCount", "Address": "LookupSource", - "BalanceLock": "BalanceLockTo212", "CompactAssignments": "CompactAssignmentsTo257", - "DispatchError": "DispatchErrorTo198", - "DispatchInfo": "DispatchInfoTo244", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", "LookupSource": "IndicesLookupSource", + "ValidatorPrefs": "ValidatorPrefsWithCommission", + "BalanceLock": "BalanceLockTo212", + "DispatchError": "DispatchErrorTo198", + "DispatchInfo": "DispatchInfoTo244", + "Heartbeat": "HeartbeatTo244", "Multiplier": "Fixed64", "OpenTip": "OpenTipTo225", "RefCount": "RefCountTo259", "ReferendumInfo": "ReferendumInfoTo239", - "RewardDestination": "RewardDestinationTo257", "SlashingSpans": "SlashingSpansTo204", "StakingLedger": "StakingLedgerTo223", "Votes": "VotesTo230", @@ -153,17 +255,20 @@ 1042 ], "types": { + "AccountInfo": "AccountInfoWithRefCount", "Address": "LookupSource", - "BalanceLock": "BalanceLockTo212", "CompactAssignments": "CompactAssignmentsTo257", - "DispatchInfo": "DispatchInfoTo244", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", "LookupSource": "IndicesLookupSource", + "ValidatorPrefs": "ValidatorPrefsWithCommission", + "BalanceLock": "BalanceLockTo212", + "DispatchInfo": "DispatchInfoTo244", + "Heartbeat": "HeartbeatTo244", "Multiplier": "Fixed64", "OpenTip": "OpenTipTo225", "RefCount": "RefCountTo259", "ReferendumInfo": "ReferendumInfoTo239", - "RewardDestination": "RewardDestinationTo257", "SlashingSpans": "SlashingSpansTo204", "StakingLedger": "StakingLedgerTo223", "Votes": "VotesTo230", @@ -176,17 +281,20 @@ 1045 ], "types": { + "AccountInfo": "AccountInfoWithRefCount", "Address": "LookupSource", - "BalanceLock": "BalanceLockTo212", "CompactAssignments": "CompactAssignmentsTo257", - "DispatchInfo": "DispatchInfoTo244", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", "LookupSource": "IndicesLookupSource", + "ValidatorPrefs": "ValidatorPrefsWithCommission", + "BalanceLock": "BalanceLockTo212", + "DispatchInfo": "DispatchInfoTo244", + "Heartbeat": "HeartbeatTo244", "Multiplier": "Fixed64", "OpenTip": "OpenTipTo225", "RefCount": "RefCountTo259", "ReferendumInfo": "ReferendumInfoTo239", - "RewardDestination": "RewardDestinationTo257", "StakingLedger": "StakingLedgerTo223", "Votes": "VotesTo230", "Weight": "u32" @@ -198,25 +306,29 @@ 1054 ], "types": { - "Address": "AccountId", + "CompactAssignments": "CompactAssignmentsTo257", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", - "LookupSource": "AccountId", "ProxyType": { "_enum": [ "Any", "NonTransfer", "Governance", "Staking", - "IdentityJudgement" + "IdentityJudgement", + "CancelProxy" ] }, - "CompactAssignments": "CompactAssignmentsTo257", + "AccountInfo": "AccountInfoWithRefCount", + "Address": "AccountId", + "LookupSource": "AccountId", + "ValidatorPrefs": "ValidatorPrefsWithCommission", "DispatchInfo": "DispatchInfoTo244", + "Heartbeat": "HeartbeatTo244", "Multiplier": "Fixed64", "OpenTip": "OpenTipTo225", "RefCount": "RefCountTo259", "ReferendumInfo": "ReferendumInfoTo239", - "RewardDestination": "RewardDestinationTo257", "StakingLedger": "StakingLedgerTo240", "Weight": "u32" } @@ -227,24 +339,28 @@ 1056 ], "types": { - "Address": "AccountId", + "CompactAssignments": "CompactAssignmentsTo257", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", - "LookupSource": "AccountId", "ProxyType": { "_enum": [ "Any", "NonTransfer", "Governance", "Staking", - "IdentityJudgement" + "IdentityJudgement", + "CancelProxy" ] }, - "CompactAssignments": "CompactAssignmentsTo257", + "AccountInfo": "AccountInfoWithRefCount", + "Address": "AccountId", + "LookupSource": "AccountId", + "ValidatorPrefs": "ValidatorPrefsWithCommission", "DispatchInfo": "DispatchInfoTo244", + "Heartbeat": "HeartbeatTo244", "Multiplier": "Fixed64", "OpenTip": "OpenTipTo225", "RefCount": "RefCountTo259", - "RewardDestination": "RewardDestinationTo257", "StakingLedger": "StakingLedgerTo240", "Weight": "u32" } @@ -255,23 +371,27 @@ 1061 ], "types": { - "Address": "AccountId", + "CompactAssignments": "CompactAssignmentsTo257", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", - "LookupSource": "AccountId", "ProxyType": { "_enum": [ "Any", "NonTransfer", "Governance", "Staking", - "IdentityJudgement" + "IdentityJudgement", + "CancelProxy" ] }, - "CompactAssignments": "CompactAssignmentsTo257", + "AccountInfo": "AccountInfoWithRefCount", + "Address": "AccountId", + "LookupSource": "AccountId", + "ValidatorPrefs": "ValidatorPrefsWithCommission", "DispatchInfo": "DispatchInfoTo244", + "Heartbeat": "HeartbeatTo244", "OpenTip": "OpenTipTo225", - "RefCount": "RefCountTo259", - "RewardDestination": "RewardDestinationTo257" + "RefCount": "RefCountTo259" } }, { @@ -280,22 +400,25 @@ 2012 ], "types": { - "Address": "AccountId", + "CompactAssignments": "CompactAssignmentsTo257", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", - "LookupSource": "AccountId", "ProxyType": { "_enum": [ "Any", "NonTransfer", "Governance", "Staking", - "IdentityJudgement" + "IdentityJudgement", + "CancelProxy" ] }, - "CompactAssignments": "CompactAssignmentsTo257", + "AccountInfo": "AccountInfoWithRefCount", + "Address": "AccountId", + "LookupSource": "AccountId", + "ValidatorPrefs": "ValidatorPrefsWithCommission", "OpenTip": "OpenTipTo225", - "RefCount": "RefCountTo259", - "RewardDestination": "RewardDestinationTo257" + "RefCount": "RefCountTo259" } }, { @@ -304,21 +427,24 @@ 2022 ], "types": { - "Address": "AccountId", + "CompactAssignments": "CompactAssignmentsTo257", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", - "LookupSource": "AccountId", "ProxyType": { "_enum": [ "Any", "NonTransfer", "Governance", "Staking", - "IdentityJudgement" + "IdentityJudgement", + "CancelProxy" ] }, - "CompactAssignments": "CompactAssignmentsTo257", - "RefCount": "RefCountTo259", - "RewardDestination": "RewardDestinationTo257" + "AccountInfo": "AccountInfoWithRefCount", + "Address": "AccountId", + "LookupSource": "AccountId", + "ValidatorPrefs": "ValidatorPrefsWithCommission", + "RefCount": "RefCountTo259" } }, { @@ -327,74 +453,136 @@ 2024 ], "types": { - "Address": "AccountId", + "CompactAssignments": "CompactAssignmentsWith16", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", - "LookupSource": "AccountId", "ProxyType": { "_enum": [ "Any", "NonTransfer", "Governance", "Staking", - "IdentityJudgement" + "IdentityJudgement", + "CancelProxy" ] }, + "AccountInfo": "AccountInfoWithRefCount", + "Address": "AccountId", + "LookupSource": "AccountId", + "ValidatorPrefs": "ValidatorPrefsWithCommission", "RefCount": "RefCountTo259" } }, { "minmax": [ 2025, - null + 2027 ], "types": { - "Address": "AccountId", + "CompactAssignments": "CompactAssignmentsWith16", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", + "ProxyType": { + "_enum": [ + "Any", + "NonTransfer", + "Governance", + "Staking", + "IdentityJudgement", + "CancelProxy" + ] + }, + "AccountInfo": "AccountInfoWithRefCount", + "Address": "AccountId", "LookupSource": "AccountId", + "ValidatorPrefs": "ValidatorPrefsWithCommission" + } + }, + { + "minmax": [ + 2028, + 2029 + ], + "types": { + "CompactAssignments": "CompactAssignmentsWith16", + "RawSolution": "RawSolutionWith16", + "Keys": "SessionKeys6", "ProxyType": { "_enum": [ "Any", "NonTransfer", "Governance", "Staking", - "IdentityJudgement" + "IdentityJudgement", + "CancelProxy" ] - } + }, + "AccountInfo": "AccountInfoWithDualRefCount" } - } - ], - "node": [ + }, { "minmax": [ - 0, - 259 + 2030, + 9000 ], "types": { - "Address": "LookupSource", - "LookupSource": "IndicesLookupSource" + "CompactAssignments": "CompactAssignmentsWith16", + "RawSolution": "RawSolutionWith16", + "Keys": "SessionKeys6", + "ProxyType": { + "_enum": [ + "Any", + "NonTransfer", + "Governance", + "Staking", + "IdentityJudgement", + "CancelProxy" + ] + } } }, { "minmax": [ - 260, + 9010, null ], "types": { - "Address": "MultiAddress", - "LookupSource": "MultiAddress" + "CompactAssignments": "CompactAssignmentsWith24", + "RawSolution": "RawSolutionWith24", + "Keys": "SessionKeys6", + "ProxyType": { + "_enum": [ + "Any", + "NonTransfer", + "Governance", + "Staking", + "IdentityJudgement", + "CancelProxy" + ] + }, + "AssetInstance": "AssetInstanceV0", + "MultiAsset": "MultiAssetV0", + "Xcm": "XcmV0", + "XcmOrder": "XcmOrderV0" } } ], + "node": [ + { + "minmax": [ + 0, + null + ], + "types": {} + } + ], "node-template": [ { "minmax": [ 0, null ], - "types": { - "Address": "AccountId", - "LookupSource": "AccountId" - } + "types": {} } ], "polkadot": [ @@ -404,23 +592,26 @@ 12 ], "types": { - "Address": "AccountId", + "CompactAssignments": "CompactAssignmentsTo257", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", - "LookupSource": "AccountId", "ProxyType": { - "_enum": [ - "Any", - "NonTransfer", - "Governance", - "Staking", - "Unused", - "IdentityJudgement" - ] + "_enum": { + "Any": 0, + "NonTransfer": 1, + "Governance": 2, + "Staking": 3, + "UnusedSudoBalances": 4, + "IdentityJudgement": 5, + "CancelProxy": 6 + } }, - "CompactAssignments": "CompactAssignmentsTo257", + "AccountInfo": "AccountInfoWithRefCount", + "Address": "AccountId", + "LookupSource": "AccountId", + "ValidatorPrefs": "ValidatorPrefsWithCommission", "OpenTip": "OpenTipTo225", - "RefCount": "RefCountTo259", - "RewardDestination": "RewardDestinationTo257" + "RefCount": "RefCountTo259" } }, { @@ -429,22 +620,25 @@ 22 ], "types": { - "Address": "AccountId", + "CompactAssignments": "CompactAssignmentsTo257", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", - "LookupSource": "AccountId", "ProxyType": { - "_enum": [ - "Any", - "NonTransfer", - "Governance", - "Staking", - "Unused", - "IdentityJudgement" - ] + "_enum": { + "Any": 0, + "NonTransfer": 1, + "Governance": 2, + "Staking": 3, + "UnusedSudoBalances": 4, + "IdentityJudgement": 5, + "CancelProxy": 6 + } }, - "CompactAssignments": "CompactAssignmentsTo257", - "RefCount": "RefCountTo259", - "RewardDestination": "RewardDestinationTo257" + "AccountInfo": "AccountInfoWithRefCount", + "Address": "AccountId", + "LookupSource": "AccountId", + "ValidatorPrefs": "ValidatorPrefsWithCommission", + "RefCount": "RefCountTo259" } }, { @@ -453,40 +647,95 @@ 24 ], "types": { - "Address": "AccountId", + "CompactAssignments": "CompactAssignmentsWith16", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", - "LookupSource": "AccountId", "ProxyType": { - "_enum": [ - "Any", - "NonTransfer", - "Governance", - "Staking", - "Unused", - "IdentityJudgement" - ] + "_enum": { + "Any": 0, + "NonTransfer": 1, + "Governance": 2, + "Staking": 3, + "UnusedSudoBalances": 4, + "IdentityJudgement": 5, + "CancelProxy": 6 + } }, + "AccountInfo": "AccountInfoWithRefCount", + "Address": "AccountId", + "LookupSource": "AccountId", + "ValidatorPrefs": "ValidatorPrefsWithCommission", "RefCount": "RefCountTo259" } }, { "minmax": [ 25, - null + 27 ], "types": { - "Address": "AccountId", + "CompactAssignments": "CompactAssignmentsWith16", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", + "ProxyType": { + "_enum": { + "Any": 0, + "NonTransfer": 1, + "Governance": 2, + "Staking": 3, + "UnusedSudoBalances": 4, + "IdentityJudgement": 5, + "CancelProxy": 6 + } + }, + "AccountInfo": "AccountInfoWithRefCount", + "Address": "AccountId", "LookupSource": "AccountId", + "ValidatorPrefs": "ValidatorPrefsWithCommission" + } + }, + { + "minmax": [ + 28, + 29 + ], + "types": { + "CompactAssignments": "CompactAssignmentsWith16", + "RawSolution": "RawSolutionWith16", + "Keys": "SessionKeys6", "ProxyType": { - "_enum": [ - "Any", - "NonTransfer", - "Governance", - "Staking", - "Unused", - "IdentityJudgement" - ] + "_enum": { + "Any": 0, + "NonTransfer": 1, + "Governance": 2, + "Staking": 3, + "UnusedSudoBalances": 4, + "IdentityJudgement": 5, + "CancelProxy": 6 + } + }, + "AccountInfo": "AccountInfoWithDualRefCount" + } + }, + { + "minmax": [ + 30, + null + ], + "types": { + "CompactAssignments": "CompactAssignmentsWith16", + "RawSolution": "RawSolutionWith16", + "Keys": "SessionKeys6", + "ProxyType": { + "_enum": { + "Any": 0, + "NonTransfer": 1, + "Governance": 2, + "Staking": 3, + "UnusedSudoBalances": 4, + "IdentityJudgement": 5, + "CancelProxy": 6 + } } } } @@ -495,31 +744,110 @@ { "minmax": [ 0, - 9 + 200 ], "types": { + "FullIdentification": "()", + "Keys": "SessionKeys7B", + "AccountInfo": "AccountInfoWithDualRefCount", "Address": "AccountId", - "Keys": "SessionKeys5", - "LookupSource": "AccountId", - "CompactAssignments": "CompactAssignmentsTo257", - "RefCount": "RefCountTo259", - "RewardDestination": "RewardDestinationTo257" + "LookupSource": "AccountId" + } + }, + { + "minmax": [ + 201, + 214 + ], + "types": { + "FullIdentification": "()", + "Keys": "SessionKeys7B", + "AccountInfo": "AccountInfoWithDualRefCount" + } + }, + { + "minmax": [ + 215, + 228 + ], + "types": { + "FullIdentification": "()", + "Keys": "SessionKeys6" } }, { "minmax": [ - 10, + 229, null ], "types": { - "Address": "AccountId", - "Keys": "SessionKeys5", - "LookupSource": "AccountId", - "ParaGenesisArgs": { - "genesisHead": "Bytes", - "validationCode": "Bytes", - "parachain": "bool" - } + "FullIdentification": "()", + "Keys": "SessionKeys7B", + "AssetInstance": "AssetInstanceV0", + "MultiAsset": "MultiAssetV0", + "Xcm": "XcmV0", + "XcmOrder": "XcmOrderV0" + } + } + ], + "shell": [ + { + "minmax": [ + 0, + null + ], + "types": {} + } + ], + "statemine": [ + { + "minmax": [ + 0, + null + ], + "types": { + "TAssetBalance": "u128", + "ProxyType": { + "_enum": [ + "Any", + "NonTransfer", + "CancelProxy", + "Assets", + "AssetOwner", + "AssetManager", + "Staking" + ] + }, + "AssetInstance": "AssetInstanceV0", + "MultiAsset": "MultiAssetV0", + "Xcm": "XcmV0", + "XcmOrder": "XcmOrderV0" + } + } + ], + "statemint": [ + { + "minmax": [ + 0, + null + ], + "types": { + "TAssetBalance": "u128", + "ProxyType": { + "_enum": [ + "Any", + "NonTransfer", + "CancelProxy", + "Assets", + "AssetOwner", + "AssetManager", + "Staking" + ] + }, + "AssetInstance": "AssetInstanceV0", + "MultiAsset": "MultiAssetV0", + "Xcm": "XcmV0", + "XcmOrder": "XcmOrderV0" } } ], @@ -530,23 +858,28 @@ 2 ], "types": { - "Address": "AccountId", + "CompactAssignments": "CompactAssignmentsTo257", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", - "LookupSource": "AccountId", "ProxyType": { "_enum": [ "Any", "NonTransfer", "Staking", - "Unused", - "IdentityJudgement" + "SudoBalances", + "IdentityJudgement", + "CancelProxy" ] }, - "CompactAssignments": "CompactAssignmentsTo257", + "AccountInfo": "AccountInfoWithRefCount", + "Address": "AccountId", + "LookupSource": "AccountId", + "ValidatorPrefs": "ValidatorPrefsWithCommission", + "DispatchInfo": "DispatchInfoTo244", + "Heartbeat": "HeartbeatTo244", "Multiplier": "Fixed64", "OpenTip": "OpenTipTo225", "RefCount": "RefCountTo259", - "RewardDestination": "RewardDestinationTo257", "Weight": "u32" } }, @@ -556,22 +889,27 @@ 22 ], "types": { - "Address": "AccountId", + "CompactAssignments": "CompactAssignmentsTo257", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", - "LookupSource": "AccountId", "ProxyType": { "_enum": [ "Any", "NonTransfer", "Staking", - "Unused", - "IdentityJudgement" + "SudoBalances", + "IdentityJudgement", + "CancelProxy" ] }, - "CompactAssignments": "CompactAssignmentsTo257", + "AccountInfo": "AccountInfoWithRefCount", + "Address": "AccountId", + "LookupSource": "AccountId", + "ValidatorPrefs": "ValidatorPrefsWithCommission", + "DispatchInfo": "DispatchInfoTo244", + "Heartbeat": "HeartbeatTo244", "OpenTip": "OpenTipTo225", - "RefCount": "RefCountTo259", - "RewardDestination": "RewardDestinationTo257" + "RefCount": "RefCountTo259" } }, { @@ -580,21 +918,26 @@ 42 ], "types": { - "Address": "AccountId", + "CompactAssignments": "CompactAssignmentsTo257", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", - "LookupSource": "AccountId", "ProxyType": { "_enum": [ "Any", "NonTransfer", "Staking", - "Unused", - "IdentityJudgement" + "SudoBalances", + "IdentityJudgement", + "CancelProxy" ] }, - "CompactAssignments": "CompactAssignmentsTo257", - "RefCount": "RefCountTo259", - "RewardDestination": "RewardDestinationTo257" + "AccountInfo": "AccountInfoWithRefCount", + "Address": "AccountId", + "LookupSource": "AccountId", + "ValidatorPrefs": "ValidatorPrefsWithCommission", + "DispatchInfo": "DispatchInfoTo244", + "Heartbeat": "HeartbeatTo244", + "RefCount": "RefCountTo259" } }, { @@ -603,39 +946,124 @@ 44 ], "types": { - "Address": "AccountId", + "CompactAssignments": "CompactAssignmentsWith16", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", - "LookupSource": "AccountId", "ProxyType": { "_enum": [ "Any", "NonTransfer", "Staking", - "Unused", - "IdentityJudgement" + "SudoBalances", + "IdentityJudgement", + "CancelProxy" ] }, + "AccountInfo": "AccountInfoWithRefCount", + "Address": "AccountId", + "LookupSource": "AccountId", + "ValidatorPrefs": "ValidatorPrefsWithCommission", + "DispatchInfo": "DispatchInfoTo244", + "Heartbeat": "HeartbeatTo244", "RefCount": "RefCountTo259" } }, { "minmax": [ 45, - null + 47 ], "types": { - "Address": "AccountId", + "CompactAssignments": "CompactAssignmentsWith16", + "RawSolution": "RawSolutionWith16", "Keys": "SessionKeys5", + "ProxyType": { + "_enum": [ + "Any", + "NonTransfer", + "Staking", + "SudoBalances", + "IdentityJudgement", + "CancelProxy" + ] + }, + "AccountInfo": "AccountInfoWithRefCount", + "Address": "AccountId", "LookupSource": "AccountId", + "ValidatorPrefs": "ValidatorPrefsWithCommission" + } + }, + { + "minmax": [ + 48, + 49 + ], + "types": { + "CompactAssignments": "CompactAssignmentsWith16", + "RawSolution": "RawSolutionWith16", + "Keys": "SessionKeys6", "ProxyType": { "_enum": [ "Any", "NonTransfer", "Staking", - "Unused", - "IdentityJudgement" + "SudoBalances", + "IdentityJudgement", + "CancelProxy" ] - } + }, + "AccountInfo": "AccountInfoWithDualRefCount" + } + }, + { + "minmax": [ + 50, + null + ], + "types": { + "CompactAssignments": "CompactAssignmentsWith16", + "RawSolution": "RawSolutionWith16", + "Keys": "SessionKeys6", + "ProxyType": { + "_enum": [ + "Any", + "NonTransfer", + "Staking", + "SudoBalances", + "IdentityJudgement", + "CancelProxy" + ] + }, + "AssetInstance": "AssetInstanceV0", + "MultiAsset": "MultiAssetV0", + "Xcm": "XcmV0", + "XcmOrder": "XcmOrderV0" + } + } + ], + "westmint": [ + { + "minmax": [ + 0, + null + ], + "types": { + "TAssetBalance": "u128", + "ProxyType": { + "_enum": [ + "Any", + "NonTransfer", + "CancelProxy", + "Assets", + "AssetOwner", + "AssetManager", + "Staking" + ] + }, + "AssetInstance": "AssetInstanceV0", + "MultiAsset": "MultiAssetV0", + "Xcm": "XcmV0", + "XcmOrder": "XcmOrderV0" } } ] diff --git a/extras/src/modules.rs b/extras/src/modules.rs index 0567f692..5cb34c0c 100644 --- a/extras/src/modules.rs +++ b/extras/src/modules.rs @@ -13,7 +13,7 @@ // along with substrate-desub. If not, see . use crate::error::Error; -use core::{regex, EnumField, RustTypeMarker, SetField, StructField, StructUnitOrTuple}; +use core::{regex, EnumField, RustTypeMarker, SetField, StructField}; use serde::{ de::{Deserializer, MapAccess, Visitor}, Deserialize, Serialize, @@ -200,30 +200,44 @@ fn parse_set(obj: &serde_json::map::Map) -> RustTypeM /// internal api to convert a serde value to str /// /// # Panics -fn parse_enum(obj: &serde_json::Value) -> RustTypeMarker { - if obj.is_array() { - let arr = obj.as_array().expect("checked before cast; qed"); - let mut rust_enum = Vec::new(); - for unit in arr.iter() { - // if an enum is an array, it's a unit enum (stateless) - rust_enum.push(unit.as_str().expect("Will be string according to polkadot-js defs").to_string()) - } - let rust_enum = rust_enum.into_iter().map(|f| f.into()).collect::>(); +fn parse_enum(value: &serde_json::Value) -> RustTypeMarker { + println!("{:?}", value); + if value.is_array() { + let arr = value.as_array().expect("checked before cast; qed"); + let rust_enum = arr.iter().map(|u| { + let name = u.as_str().expect("Will be string according to polkadot-js defs").to_string(); + EnumField::new(name, None) + }).collect::>(); RustTypeMarker::Enum(rust_enum) - // all enum 'objects' in polkadot.js definitions are tuple-enums - } else if obj.is_object() { - let obj = obj.as_object().expect("Checked before casting; qed"); - let mut rust_enum = Vec::new(); - for (key, value) in obj.iter() { - let value = if value.is_null() { "null" } else { value.as_str().expect("will be str; qed") }; - let field = - EnumField::new(Some(key.into()), StructUnitOrTuple::Tuple(regex::parse(value).expect("Not a type"))); - rust_enum.push(field); - } + } else if value.is_object() { + let value = value.as_object().expect("Checked before casting; qed"); + + + // If all the values are numbers then we need to order the enum according to those numbers. + // Some types like `ProxyType` in the runtime may vary from runtime-to-runtime. + // So afaik Polkadot-Js types solve this by attaching a number to each variant according to index. + let rust_enum = if value.values().fold(true, |_, v| v.is_number()) { + let mut tuples = value.values() + .map(|v| v.as_u64().expect("Must be u64")) + .zip( + value.keys().map(|k| EnumField::new(k.into(), None)) + ) + .collect::>(); + tuples.sort_by_key(|(num, _)| *num); + tuples.into_iter().map(|t| t.1).collect::>() + } else { + value.iter().map(|(k, v)| { + let value = regex::parse(v + .as_str() + .expect("Types must be strings")) + .expect(&format!("Could not parse type {}", v)); + EnumField::new(k.into(), Some(value)) + }).collect::>() + }; RustTypeMarker::Enum(rust_enum) // so far, polkadot.js does not define any struct-like enums } else { - panic!("Unnaccounted type") + panic!("Unkown type") } } @@ -233,7 +247,7 @@ mod tests { use crate::error::Error; use crate::ModuleTypes; - use core::{EnumField, RustTypeMarker, SetField, StructField, StructUnitOrTuple}; + use core::{EnumField, RustTypeMarker, SetField, StructField}; use std::collections::HashMap; const RAW_JSON: &'static str = r#" { @@ -306,25 +320,25 @@ mod tests { "MultiSignature".to_string(), RustTypeMarker::Enum(vec![ EnumField { - variant_name: Some("Ed25519".to_string()), - ty: StructUnitOrTuple::Tuple(RustTypeMarker::TypePointer("Ed25519Signature".to_string())), + name: "Ed25519".to_string(), + value: Some(RustTypeMarker::TypePointer("Ed25519Signature".to_string())), }, EnumField { - variant_name: Some("Sr25519".to_string()), - ty: StructUnitOrTuple::Tuple(RustTypeMarker::TypePointer("Sr25519Signature".to_string())), + name: "Sr25519".to_string(), + value: Some(RustTypeMarker::TypePointer("Sr25519Signature".to_string())), }, EnumField { - variant_name: Some("Ecdsa".to_string()), - ty: StructUnitOrTuple::Tuple(RustTypeMarker::TypePointer("EcdsaSignature".to_string())), + name: "Ecdsa".to_string(), + value: Some(RustTypeMarker::TypePointer("EcdsaSignature".to_string())), }, ]), ); types.insert( "Reasons".to_string(), RustTypeMarker::Enum(vec![ - EnumField { variant_name: None, ty: StructUnitOrTuple::Unit("Fee".to_string()) }, - EnumField { variant_name: None, ty: StructUnitOrTuple::Unit("Misc".to_string()) }, - EnumField { variant_name: None, ty: StructUnitOrTuple::Unit("All".to_string()) }, + EnumField { name: "TestField".into(), value: Some(RustTypeMarker::Unit("Fee".to_string())) }, + EnumField { name: "TestField1".into(), value: Some(RustTypeMarker::Unit("Misc".to_string())) }, + EnumField { name: "TestField2".into(), value: Some(RustTypeMarker::Unit("All".to_string())) }, ]), ); types.insert( diff --git a/extras/src/resolver.rs b/extras/src/resolver.rs index e44f9ae6..60eb0583 100644 --- a/extras/src/resolver.rs +++ b/extras/src/resolver.rs @@ -207,17 +207,17 @@ impl TypeDetective for TypeResolver { mod tests { use super::default::*; use super::*; - use core::{EnumField, StructField, StructUnitOrTuple}; + use core::{EnumField, StructField}; #[test] fn should_get_type_from_module() -> Result<()> { let post_1031_dispatch_error = RustTypeMarker::Enum(vec![ - EnumField::new(Some("Other".into()), StructUnitOrTuple::Tuple(RustTypeMarker::Null)), - EnumField::new(Some("CannotLookup".into()), StructUnitOrTuple::Tuple(RustTypeMarker::Null)), - EnumField::new(Some("BadOrigin".into()), StructUnitOrTuple::Tuple(RustTypeMarker::Null)), + EnumField::new("Other".into(), Some(RustTypeMarker::Null)), + EnumField::new("CannotLookup".into(), Some(RustTypeMarker::Null)), + EnumField::new("BadOrigin".into(), Some(RustTypeMarker::Null)), EnumField::new( - Some("Module".into()), - StructUnitOrTuple::Tuple(RustTypeMarker::TypePointer("DispatchErrorModule".to_string())), + "Module".into(), + Some(RustTypeMarker::TypePointer("DispatchErrorModule".to_string())), ), ]); let types = TypeResolver::default(); From 5be1741bf41f6ea26f9642a5fe7954c7effb339b Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Fri, 27 Aug 2021 21:27:25 -0400 Subject: [PATCH 05/13] Make translating from Json to Desub more flexible - Json Objects/arrays/Null fields are seperated based on tuple/struct/enum representation - add better error handling --- Cargo.lock | 2 +- extras/src/error.rs | 12 +++- extras/src/modules.rs | 111 +++++++++++++++++++++++------ extras/src/resolver.rs | 10 +-- integration_tests/Cargo.toml | 2 +- integration_tests/tests/storage.rs | 4 +- 6 files changed, 107 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4ee64ebe..b7874a7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1319,7 +1319,7 @@ dependencies = [ "hex", "log", "pallet-balances", - "parity-scale-codec 1.3.7", + "parity-scale-codec 2.2.0", "paste", "pretty_env_logger", "serde", diff --git a/extras/src/error.rs b/extras/src/error.rs index eec71c15..a0fa249a 100644 --- a/extras/src/error.rs +++ b/extras/src/error.rs @@ -22,6 +22,14 @@ pub type Result = std::result::Result; pub enum Error { #[error("Decode {0}")] Decode(#[from] serde_json::Error), - #[error("{0} Not Found")] - NotFound(String), + #[error("Could not parse {0} into type")] + TypeError(String), + #[error("type is not possible in the context of rust")] + UnexpectedType, +} + +impl From for Error { + fn from(err: String) -> Error { + Error::TypeError(err) + } } diff --git a/extras/src/modules.rs b/extras/src/modules.rs index 5cb34c0c..6031aad9 100644 --- a/extras/src/modules.rs +++ b/extras/src/modules.rs @@ -147,13 +147,14 @@ impl<'de> Visitor<'de> for ModuleTypeVisitor { } } +// FIXME: This whole function should return a Result<_,_> fn parse_mod_types(module_types: &mut HashMap, key: &str, val: &serde_json::Value) { if val.is_string() { module_types.insert(key.to_string(), regex::parse(val.as_str().expect("Checked; qed")).expect("not a type")); } else if val.is_object() { let obj = val.as_object().expect("checked for object before unwrap; qed"); if obj.contains_key("_enum") { - module_types.insert(key.to_string(), parse_enum(&obj["_enum"])); + module_types.insert(key.to_string(), parse_enum(&obj["_enum"]).unwrap()); // FIXME } else if obj.contains_key("_set") { let obj = obj["_set"].as_object().expect("_set is a map"); module_types.insert(key.to_string(), parse_set(obj)); @@ -187,6 +188,19 @@ fn val_to_str(v: &serde_json::Value) -> String { v.as_str().expect("will be string").to_string() } +/* +/// In Polkadot-JS Definitions, an object can be: +/// - Struct (no identifier), +/// - Enum (`_enum` identifier) +/// - Set (`_set`) +/// This functions decides which is what and dispatches a call +/// to the appropriate parse fn. +fn deliberate_object(_obj: serde_json::Map) -> Result { + todo!(); +} +*/ + +// TODO: Account for 'bitlength' in _set fn parse_set(obj: &serde_json::map::Map) -> RustTypeMarker { let mut set_vec = Vec::new(); for (key, value) in obj.iter() { @@ -197,26 +211,24 @@ fn parse_set(obj: &serde_json::map::Map) -> RustTypeM RustTypeMarker::Set(set_vec) } -/// internal api to convert a serde value to str +/// Process the enum and return the representation as a Rust Type /// /// # Panics -fn parse_enum(value: &serde_json::Value) -> RustTypeMarker { - println!("{:?}", value); +fn parse_enum(value: &serde_json::Value) -> Result { + // println!("{:?}", value); if value.is_array() { let arr = value.as_array().expect("checked before cast; qed"); let rust_enum = arr.iter().map(|u| { let name = u.as_str().expect("Will be string according to polkadot-js defs").to_string(); EnumField::new(name, None) }).collect::>(); - RustTypeMarker::Enum(rust_enum) + Ok(RustTypeMarker::Enum(rust_enum)) } else if value.is_object() { let value = value.as_object().expect("Checked before casting; qed"); - - // If all the values are numbers then we need to order the enum according to those numbers. - // Some types like `ProxyType` in the runtime may vary from runtime-to-runtime. - // So afaik Polkadot-Js types solve this by attaching a number to each variant according to index. - let rust_enum = if value.values().fold(true, |_, v| v.is_number()) { + // Some types like `ProxyType` in the runtime may vary from chain-to-chain. + // So afaict Polkadot-Js types solve this by attaching a number to each variant according to index. + let rust_enum = if value.values().fold(true, |_, v| v.is_number()) { // TODO: TEST THIS AGAINST PROXYTYPE let mut tuples = value.values() .map(|v| v.as_u64().expect("Must be u64")) .zip( @@ -226,21 +238,74 @@ fn parse_enum(value: &serde_json::Value) -> RustTypeMarker { tuples.sort_by_key(|(num, _)| *num); tuples.into_iter().map(|t| t.1).collect::>() } else { - value.iter().map(|(k, v)| { - let value = regex::parse(v - .as_str() - .expect("Types must be strings")) - .expect(&format!("Could not parse type {}", v)); - EnumField::new(k.into(), Some(value)) - }).collect::>() + let mut rust_enum = Vec::new(); + for (key, value) in value.iter() { + match value { + serde_json::Value::Null => rust_enum.push(EnumField::new(key.into(), Some(RustTypeMarker::Null))), + serde_json::Value::String(s) => { + let field = regex::parse(s).ok_or(Error::from(s.to_string()))?; + rust_enum.push(EnumField::new(key.into(), Some(field))); + }, + serde_json::Value::Object(o) => { + let rust_struct = parse_struct(o)?; + rust_enum.push(EnumField::new(key.into(), Some(rust_struct))); + }, + _ => return Err(Error::UnexpectedType), + }; + } + rust_enum }; - RustTypeMarker::Enum(rust_enum) - // so far, polkadot.js does not define any struct-like enums + Ok(RustTypeMarker::Enum(rust_enum)) } else { panic!("Unkown type") } } +/// Parses a rust struct representation from a JSON Map. +fn parse_struct(rust_struct: &serde_json::Map) -> Result { + let mut fields = Vec::new(); + for (key, value) in rust_struct.iter() { + match value { + serde_json::Value::Null => { + let field = StructField::new(key, RustTypeMarker::Null); + fields.push(field); + }, + serde_json::Value::String(s) => { // points to some other type + let ty = regex::parse(s).ok_or(s.to_string())?; + let field = StructField::new(key, ty); + fields.push(field); + }, + serde_json::Value::Object(o) => { // struct-within-a-struct + let inner_struct = parse_struct(o)?; + let field = StructField::new(key, inner_struct); + fields.push(field); + }, + serde_json::Value::Array(a) => { + let tuples = parse_tuple(a)?; + let field = StructField::new(key, tuples); + fields.push(field); + }, + _ => return Err(Error::UnexpectedType), + } + } + Ok(RustTypeMarker::Null) +} + +fn parse_tuple(json_tuple: &[serde_json::Value]) -> Result { + let mut tuple = Vec::new(); + for value in json_tuple.iter() { + match value { + serde_json::Value::Null => tuple.push(RustTypeMarker::Null), + serde_json::Value::String(s) => { + let ty = regex::parse(s).ok_or(s.to_string())?; + tuple.push(ty); + }, + _ => return Err(Error::UnexpectedType) + } + } + Ok(RustTypeMarker::Tuple(tuple)) +} + #[cfg(test)] mod tests { use super::Modules; @@ -294,7 +359,7 @@ mod tests { "#; #[test] - fn should_deserialize_correctly() -> Result<(), Error> { + fn should_deserialize_modules() -> Result<(), Error> { let deser_dot_types = Modules::new(RAW_JSON)?; let mut modules = HashMap::new(); let mut types = HashMap::new(); @@ -336,9 +401,9 @@ mod tests { types.insert( "Reasons".to_string(), RustTypeMarker::Enum(vec![ - EnumField { name: "TestField".into(), value: Some(RustTypeMarker::Unit("Fee".to_string())) }, - EnumField { name: "TestField1".into(), value: Some(RustTypeMarker::Unit("Misc".to_string())) }, - EnumField { name: "TestField2".into(), value: Some(RustTypeMarker::Unit("All".to_string())) }, + EnumField { name: "Fee".into(), value: None }, + EnumField { name: "Misc".into(), value: None }, + EnumField { name: "All".into(), value: None }, ]), ); types.insert( diff --git a/extras/src/resolver.rs b/extras/src/resolver.rs index 60eb0583..fc865830 100644 --- a/extras/src/resolver.rs +++ b/extras/src/resolver.rs @@ -215,11 +215,13 @@ mod tests { EnumField::new("Other".into(), Some(RustTypeMarker::Null)), EnumField::new("CannotLookup".into(), Some(RustTypeMarker::Null)), EnumField::new("BadOrigin".into(), Some(RustTypeMarker::Null)), - EnumField::new( - "Module".into(), - Some(RustTypeMarker::TypePointer("DispatchErrorModule".to_string())), - ), + EnumField::new("Module".into(), Some(RustTypeMarker::TypePointer("DispatchErrorModule".to_string()))), + EnumField::new("ConsumerRemaining".into(), Some(RustTypeMarker::Null)), + EnumField::new("NoProviders".into(), Some(RustTypeMarker::Null)), + EnumField::new("Token".into(), Some(RustTypeMarker::TypePointer("TokenError".to_string()))), + EnumField::new("Arithmetic".into(), Some(RustTypeMarker::TypePointer("ArithmeticError".to_string()))), ]); + let types = TypeResolver::default(); let t = types.get("kusama", 1040, "system", "DispatchError").unwrap(); assert_eq!(t, &post_1031_dispatch_error); diff --git a/integration_tests/Cargo.toml b/integration_tests/Cargo.toml index 9fd073c4..09999bdc 100644 --- a/integration_tests/Cargo.toml +++ b/integration_tests/Cargo.toml @@ -12,7 +12,7 @@ desub-core = { path = "../core", package = "desub-core" } extras = { path = "../extras", package = "desub-extras" } serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0", features = ["preserve_order"] } -codec = { version = "1", package = "parity-scale-codec" } +codec = { version = "2", package = "parity-scale-codec" } primitives = { package = "sp-core", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } diff --git a/integration_tests/tests/storage.rs b/integration_tests/tests/storage.rs index e1932b46..2d3b04d8 100644 --- a/integration_tests/tests/storage.rs +++ b/integration_tests/tests/storage.rs @@ -8,12 +8,10 @@ use frame_system::AccountInfo; use pallet_balances::AccountData; use primitives::twox_128; -// hex(encoded): 010000000864000000000000000000000000000000c80000000000000000000000000000002c01000000000000000000000000000090010000000000000000000000000000 fn mock_account_info() -> AccountInfo> { let mock_account_data: AccountData = AccountData { free: 100, reserved: 200, misc_frozen: 300, fee_frozen: 400 }; - let mock_account_info: AccountInfo> = - AccountInfo { nonce: 1, refcount: 8, data: mock_account_data }; + let mock_account_info: AccountInfo> = AccountInfo::default(); mock_account_info } From 05fa52def068d8ed7d68eec432cfdf3e0ff826c9 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Fri, 27 Aug 2021 21:48:24 -0400 Subject: [PATCH 06/13] improve error handling in parse_mod_types --- extras/src/modules.rs | 102 ++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 49 deletions(-) diff --git a/extras/src/modules.rs b/extras/src/modules.rs index 6031aad9..ac724805 100644 --- a/extras/src/modules.rs +++ b/extras/src/modules.rs @@ -15,9 +15,10 @@ use crate::error::Error; use core::{regex, EnumField, RustTypeMarker, SetField, StructField}; use serde::{ - de::{Deserializer, MapAccess, Visitor}, + de::{self, Deserializer, MapAccess, Visitor}, Deserialize, Serialize, }; +use serde_json::Value; use std::{collections::HashMap, fmt}; /// Types for each substrate Module @@ -130,16 +131,15 @@ impl<'de> Visitor<'de> for ModuleTypeVisitor { // skip over "types" key, this encapsulates the types we actually care // about "types" => { - let val: serde_json::Value = map.next_value()?; + let val: Value = map.next_value()?; let val = val.as_object().expect("Types must refer to an object"); for (key, val) in val.iter() { - parse_mod_types(&mut module_types, key, val); + parse_mod_types(&mut module_types, key, val).map_err(de::Error::custom)?; } } m => { - let val: serde_json::Value = map.next_value()?; - //let val = val.as_object().expect("Types must refer to an object"); - parse_mod_types(&mut module_types, m, &val); + let val: Value = map.next_value()?; + parse_mod_types(&mut module_types, m, &val).map_err(de::Error::custom)?; } } } @@ -148,43 +148,47 @@ impl<'de> Visitor<'de> for ModuleTypeVisitor { } // FIXME: This whole function should return a Result<_,_> -fn parse_mod_types(module_types: &mut HashMap, key: &str, val: &serde_json::Value) { - if val.is_string() { - module_types.insert(key.to_string(), regex::parse(val.as_str().expect("Checked; qed")).expect("not a type")); - } else if val.is_object() { - let obj = val.as_object().expect("checked for object before unwrap; qed"); - if obj.contains_key("_enum") { - module_types.insert(key.to_string(), parse_enum(&obj["_enum"]).unwrap()); // FIXME - } else if obj.contains_key("_set") { - let obj = obj["_set"].as_object().expect("_set is a map"); - module_types.insert(key.to_string(), parse_set(obj)); - } else if obj.contains_key("_alias") { - let mut fields = Vec::new(); - for (key, val) in obj.iter() { - if key == "_alias" { - continue; - } else { - let field = StructField::new(key, regex::parse(&val_to_str(val)).expect("Not a type")); - fields.push(field); +fn parse_mod_types(module_types: &mut HashMap, key: &str, val: &Value) -> Result<(), Error> { + match val { + Value::String(s) => { + module_types.insert(key.to_string(), regex::parse(s).ok_or(Error::from(s.to_string()))?); + }, + Value::Object(obj) => { + if obj.contains_key("_enum") { + let rust_enum = parse_enum(&obj["_enum"])?; + module_types.insert(key.to_string(), rust_enum); + } else if obj.contains_key("_set") { + let obj = obj["_set"].as_object().expect("_set is a map"); + module_types.insert(key.to_string(), parse_set(obj)); + } else if obj.contains_key("_alias") { + let mut fields = Vec::new(); + for (key, val) in obj.iter() { + if key == "_alias" { + continue; + } else { + let field = StructField::new(key, regex::parse(&val_to_str(val)).expect("Not a type")); + fields.push(field); + } } + module_types.insert(key.to_string(), RustTypeMarker::Struct(fields)); + } else { // is just a struct + let rust_struct = parse_struct(obj)?; + module_types.insert(key.to_string(), rust_struct); } - module_types.insert(key.to_string(), RustTypeMarker::Struct(fields)); - } else { - let mut fields = Vec::new(); - for (key, val) in obj.iter() { - let field = StructField::new(key, regex::parse(&val_to_str(val)).expect("Not a type")); - fields.push(field); - } - module_types.insert(key.to_string(), RustTypeMarker::Struct(fields)); - } + }, + Value::Null => { + module_types.insert(key.to_string(), RustTypeMarker::Null); + }, + _ => return Err(Error::UnexpectedType), } + Ok(()) } /// internal api to convert a serde value to str /// /// # Panics /// panics if the value is not a string -fn val_to_str(v: &serde_json::Value) -> String { +fn val_to_str(v: &Value) -> String { v.as_str().expect("will be string").to_string() } @@ -195,13 +199,13 @@ fn val_to_str(v: &serde_json::Value) -> String { /// - Set (`_set`) /// This functions decides which is what and dispatches a call /// to the appropriate parse fn. -fn deliberate_object(_obj: serde_json::Map) -> Result { +fn deliberate_object(_obj: serde_json::Map) -> Result { todo!(); } */ // TODO: Account for 'bitlength' in _set -fn parse_set(obj: &serde_json::map::Map) -> RustTypeMarker { +fn parse_set(obj: &serde_json::map::Map) -> RustTypeMarker { let mut set_vec = Vec::new(); for (key, value) in obj.iter() { let num: u8 = serde_json::from_value(value.clone()).expect("Must be u8"); @@ -214,7 +218,7 @@ fn parse_set(obj: &serde_json::map::Map) -> RustTypeM /// Process the enum and return the representation as a Rust Type /// /// # Panics -fn parse_enum(value: &serde_json::Value) -> Result { +fn parse_enum(value: &Value) -> Result { // println!("{:?}", value); if value.is_array() { let arr = value.as_array().expect("checked before cast; qed"); @@ -241,12 +245,12 @@ fn parse_enum(value: &serde_json::Value) -> Result { let mut rust_enum = Vec::new(); for (key, value) in value.iter() { match value { - serde_json::Value::Null => rust_enum.push(EnumField::new(key.into(), Some(RustTypeMarker::Null))), - serde_json::Value::String(s) => { + Value::Null => rust_enum.push(EnumField::new(key.into(), Some(RustTypeMarker::Null))), + Value::String(s) => { let field = regex::parse(s).ok_or(Error::from(s.to_string()))?; rust_enum.push(EnumField::new(key.into(), Some(field))); }, - serde_json::Value::Object(o) => { + Value::Object(o) => { let rust_struct = parse_struct(o)?; rust_enum.push(EnumField::new(key.into(), Some(rust_struct))); }, @@ -262,25 +266,25 @@ fn parse_enum(value: &serde_json::Value) -> Result { } /// Parses a rust struct representation from a JSON Map. -fn parse_struct(rust_struct: &serde_json::Map) -> Result { +fn parse_struct(rust_struct: &serde_json::Map) -> Result { let mut fields = Vec::new(); for (key, value) in rust_struct.iter() { match value { - serde_json::Value::Null => { + Value::Null => { let field = StructField::new(key, RustTypeMarker::Null); fields.push(field); }, - serde_json::Value::String(s) => { // points to some other type + Value::String(s) => { // points to some other type let ty = regex::parse(s).ok_or(s.to_string())?; let field = StructField::new(key, ty); fields.push(field); }, - serde_json::Value::Object(o) => { // struct-within-a-struct + Value::Object(o) => { // struct-within-a-struct let inner_struct = parse_struct(o)?; let field = StructField::new(key, inner_struct); fields.push(field); }, - serde_json::Value::Array(a) => { + Value::Array(a) => { let tuples = parse_tuple(a)?; let field = StructField::new(key, tuples); fields.push(field); @@ -288,15 +292,15 @@ fn parse_struct(rust_struct: &serde_json::Map) -> Res _ => return Err(Error::UnexpectedType), } } - Ok(RustTypeMarker::Null) + Ok(RustTypeMarker::Struct(fields)) } -fn parse_tuple(json_tuple: &[serde_json::Value]) -> Result { +fn parse_tuple(json_tuple: &[Value]) -> Result { let mut tuple = Vec::new(); for value in json_tuple.iter() { match value { - serde_json::Value::Null => tuple.push(RustTypeMarker::Null), - serde_json::Value::String(s) => { + Value::Null => tuple.push(RustTypeMarker::Null), + Value::String(s) => { let ty = regex::parse(s).ok_or(s.to_string())?; tuple.push(ty); }, From 76da72c8a75fefca465db34bf0834453e0ba2ad2 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Fri, 27 Aug 2021 21:52:30 -0400 Subject: [PATCH 07/13] fix decoder test --- core/src/decoder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/decoder.rs b/core/src/decoder.rs index ef57591f..4a438958 100644 --- a/core/src/decoder.rs +++ b/core/src/decoder.rs @@ -1133,7 +1133,7 @@ mod tests { ]), SubstrateType::Enum( EnumField::new( - "TestEnum".into(), + "Wraith".into(), Some(Box::new(SubstrateType::Struct(vec![ StructField { name: Some("name".into()), From 82b14e78cf43f894805b2c24f7432178520cdffe Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Sat, 28 Aug 2021 19:50:26 -0400 Subject: [PATCH 08/13] add more logging and add metadata v13, v14 --- core/src/decoder.rs | 2 ++ core/src/decoder/metadata.rs | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/core/src/decoder.rs b/core/src/decoder.rs index 4a438958..db359082 100644 --- a/core/src/decoder.rs +++ b/core/src/decoder.rs @@ -215,6 +215,7 @@ impl Decoder { Ok(storage) } StorageType::Map { value: val_rtype, unused: _unused, .. } => { + log::trace!("Resolving storage `Map`. Value: {:?}, module {}, spec {}", val_rtype, storage_info.module.name(), spec); let key = self.get_key_data(key, storage_info, &lookup_table); let mut cursor = 0; let value = @@ -223,6 +224,7 @@ impl Decoder { Ok(storage) } StorageType::DoubleMap { value: val_rtype, .. } => { + log::trace!("Resolving storage `DoubleMap`. Value: {:?}, module {}, spec {}", value, storage_info.module.name(), spec); let key = self.get_key_data(key, storage_info, &lookup_table); let mut cursor = 0; let value = diff --git a/core/src/decoder/metadata.rs b/core/src/decoder/metadata.rs index a2846048..77bb6ab2 100644 --- a/core/src/decoder/metadata.rs +++ b/core/src/decoder/metadata.rs @@ -180,9 +180,18 @@ impl Metadata { Decode::decode(&mut &*bytes).expect("Decode failed"); meta.try_into().expect("Conversion failed") }, - 0xD => todo!(), - 0xE => todo!(), - 0xF => todo!(), + 0xD => { + log::debug!("Metadata V13"); + let meta: frame_metadata::RuntimeMetadataPrefixed = + Decode::decode(&mut &bytes[..]).expect("decode failed"); + meta.try_into().expect("Conversion failed") + }, + 0xE => { + log::debug!("Metadata V14"); + let meta: frame_metadata::RuntimeMetadataPrefixed = + Decode::decode(&mut &bytes[..]).expect("decode failed"); + meta.try_into().expect("Conversion failed") + }, /* TODO remove panics */ e => panic!("subPrefixedstrate metadata version {} is unknown, invalid or unsupported", e), } From 4410d578ecb794a874e4287012552418a7b23709 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Mon, 30 Aug 2021 23:52:47 -0400 Subject: [PATCH 09/13] rewrote most of modules to make JSON parsing more flexible --- Cargo.lock | 1 + core/src/decoder.rs | 1 + core/src/decoder/metadata.rs | 5 +- extras/src/modules.rs | 125 ++++++++++++++------------ integration_tests/Cargo.toml | 1 + integration_tests/tests/storage.rs | 11 +-- integration_tests/tests/test_suite.rs | 25 +++--- 7 files changed, 92 insertions(+), 77 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b7874a7b..ee3aee3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1313,6 +1313,7 @@ dependencies = [ name = "integration_tests" version = "0.1.0" dependencies = [ + "anyhow", "desub-core", "desub-extras", "frame-system", diff --git a/core/src/decoder.rs b/core/src/decoder.rs index db359082..aec23109 100644 --- a/core/src/decoder.rs +++ b/core/src/decoder.rs @@ -500,6 +500,7 @@ impl Decoder { num.into() } RustTypeMarker::U32 => { + log::trace!("{:?}", &data[*cursor..]); let num: u32 = if is_compact { let num: Compact = Decode::decode(&mut &data[*cursor..])?; let len = Compact::compact_len(&u32::from(num)); diff --git a/core/src/decoder/metadata.rs b/core/src/decoder/metadata.rs index 77bb6ab2..fba74516 100644 --- a/core/src/decoder/metadata.rs +++ b/core/src/decoder/metadata.rs @@ -269,9 +269,8 @@ impl Metadata { StorageLookupTable::new(lookup) } - fn generate_key>(prefix: S) -> Vec { - let prefix: String = prefix.into(); - prefix.split_ascii_whitespace().map(|s| twox_128(s.as_bytes()).to_vec()).flatten().collect() + fn generate_key>(prefix: S) -> Vec { + prefix.as_ref().split_ascii_whitespace().map(|s| twox_128(s.as_bytes()).to_vec()).flatten().collect() } /// print out a detailed but human readable description of the module diff --git a/extras/src/modules.rs b/extras/src/modules.rs index ac724805..682f7e93 100644 --- a/extras/src/modules.rs +++ b/extras/src/modules.rs @@ -18,7 +18,7 @@ use serde::{ de::{self, Deserializer, MapAccess, Visitor}, Deserialize, Serialize, }; -use serde_json::Value; +use serde_json::{Value, map::Map}; use std::{collections::HashMap, fmt}; /// Types for each substrate Module @@ -54,6 +54,7 @@ impl Modules { pub struct ModuleTypes { /// Type Name -> Type types: HashMap, + fallbacks: HashMap } impl ModuleTypes { @@ -64,11 +65,13 @@ impl ModuleTypes { /// Merges a ModuleTypes struct with another, to create a new HashMap /// The `other` struct takes priority if there are type conflicts pub fn merge(&self, other: &ModuleTypes) -> ModuleTypes { - let mut types = self.types.clone(); + let (mut types, mut fallbacks) = (self.types.clone(), self.fallbacks.clone()); let other = other.clone(); types.extend(other.types.into_iter()); + fallbacks.extend(other.fallbacks.into_iter()); - ModuleTypes { types } + + ModuleTypes { types, fallbacks } } } @@ -124,56 +127,66 @@ impl<'de> Visitor<'de> for ModuleTypeVisitor { where V: MapAccess<'de>, { - let mut module_types: HashMap = HashMap::new(); + let mut types: HashMap = HashMap::new(); + let mut fallbacks: HashMap = HashMap::new(); while let Some(key) = map.next_key::<&str>()? { match key { // skip over "types" key, this encapsulates the types we actually care // about "types" => { - let val: Value = map.next_value()?; - let val = val.as_object().expect("Types must refer to an object"); - for (key, val) in val.iter() { - parse_mod_types(&mut module_types, key, val).map_err(de::Error::custom)?; + let mut obj: Value = map.next_value()?; + let obj = obj.as_object_mut().ok_or_else(|| de::Error::custom("Types must refer to an object"))?; + for (key, ref mut val) in obj.iter_mut() { + parse_mod_types(&mut types, &mut fallbacks, key, val).map_err(de::Error::custom)?; } } m => { - let val: Value = map.next_value()?; - parse_mod_types(&mut module_types, m, &val).map_err(de::Error::custom)?; + let mut val: Value = map.next_value()?; + parse_mod_types(&mut types, &mut fallbacks, m, &mut val).map_err(de::Error::custom)?; } } } - Ok(ModuleTypes { types: module_types }) + Ok(ModuleTypes { types, fallbacks }) } } -// FIXME: This whole function should return a Result<_,_> -fn parse_mod_types(module_types: &mut HashMap, key: &str, val: &Value) -> Result<(), Error> { +type TypeMap = HashMap; + + +/// In Polkadot-JS Definitions, an _object_ can be: +/// - Struct (no identifier), +/// - Enum (`_enum` identifier) +/// - Set (`_set`) +/// +/// This function decides which is what and dispatches a call +/// to the appropriate parse fn. +fn parse_mod_types( + module_types: &mut TypeMap, + fallbacks: &mut TypeMap, + key: &str, + val: &mut Value +) -> Result<(), Error> { + match val { Value::String(s) => { module_types.insert(key.to_string(), regex::parse(s).ok_or(Error::from(s.to_string()))?); }, - Value::Object(obj) => { - if obj.contains_key("_enum") { - let rust_enum = parse_enum(&obj["_enum"])?; - module_types.insert(key.to_string(), rust_enum); - } else if obj.contains_key("_set") { - let obj = obj["_set"].as_object().expect("_set is a map"); - module_types.insert(key.to_string(), parse_set(obj)); - } else if obj.contains_key("_alias") { - let mut fields = Vec::new(); - for (key, val) in obj.iter() { - if key == "_alias" { - continue; - } else { - let field = StructField::new(key, regex::parse(&val_to_str(val)).expect("Not a type")); - fields.push(field); - } + Value::Object(ref mut obj) => { + if obj.len() == 1 && obj.keys().any(|k| k == "_enum" || k == "_set") { + let ty = match obj.iter().nth(0).map(|(s, v)| (s.as_str(), v)) { + Some(("_enum", v)) => parse_enum(v)?, + Some(("_set", v)) => parse_set(v.as_object().expect("set is always an object"))?, + Some((_, _)) => return Err(Error::UnexpectedType), + None => panic!("This should never occur, checked for object length.") + }; + module_types.insert(key.to_string(), ty); + } else { + if let Some(fallback) = clean_struct(obj)? { + fallbacks.insert(key.to_string(), fallback); } - module_types.insert(key.to_string(), RustTypeMarker::Struct(fields)); - } else { // is just a struct - let rust_struct = parse_struct(obj)?; - module_types.insert(key.to_string(), rust_struct); + let ty = parse_struct(&obj)?; + module_types.insert(key.to_string(), ty); } }, Value::Null => { @@ -184,42 +197,40 @@ fn parse_mod_types(module_types: &mut HashMap, key: &str Ok(()) } -/// internal api to convert a serde value to str -/// -/// # Panics -/// panics if the value is not a string -fn val_to_str(v: &Value) -> String { - v.as_str().expect("will be string").to_string() -} - -/* -/// In Polkadot-JS Definitions, an object can be: -/// - Struct (no identifier), -/// - Enum (`_enum` identifier) -/// - Set (`_set`) -/// This functions decides which is what and dispatches a call -/// to the appropriate parse fn. -fn deliberate_object(_obj: serde_json::Map) -> Result { - todo!(); +// Removes unsupported/unnecessary keys from struct, +// and returns fallback value if it exists. +fn clean_struct(map: &mut Map) -> Result, Error> { + map.remove("_alias"); // aliases are javascript-specific + + if let Some(fallback) = map.remove("_fallback") { + let ty = match fallback { + Value::String(s) => regex::parse(&s).ok_or_else(|| Error::from(s.to_string()))?, + Value::Object(o) => parse_struct(&o)?, + Value::Array(a) => parse_tuple(&a)?, + Value::Null => RustTypeMarker::Null, + _ => return Err(Error::UnexpectedType) + }; + Ok(Some(ty)) + } else { + Ok(None) + } } -*/ // TODO: Account for 'bitlength' in _set -fn parse_set(obj: &serde_json::map::Map) -> RustTypeMarker { +fn parse_set(obj: &Map) -> Result { let mut set_vec = Vec::new(); for (key, value) in obj.iter() { - let num: u8 = serde_json::from_value(value.clone()).expect("Must be u8"); + let num: u8 = serde_json::from_value(value.clone())?; let set_field = SetField::new(key, num); set_vec.push(set_field) } - RustTypeMarker::Set(set_vec) + Ok(RustTypeMarker::Set(set_vec)) } /// Process the enum and return the representation as a Rust Type /// /// # Panics fn parse_enum(value: &Value) -> Result { - // println!("{:?}", value); if value.is_array() { let arr = value.as_array().expect("checked before cast; qed"); let rust_enum = arr.iter().map(|u| { @@ -266,7 +277,7 @@ fn parse_enum(value: &Value) -> Result { } /// Parses a rust struct representation from a JSON Map. -fn parse_struct(rust_struct: &serde_json::Map) -> Result { +fn parse_struct(rust_struct: &Map) -> Result { let mut fields = Vec::new(); for (key, value) in rust_struct.iter() { match value { @@ -425,7 +436,7 @@ mod tests { assert_eq!(val, &deser_dot_types.modules["runtime"].types[key]); } - let mod_types = ModuleTypes { types }; + let mod_types = ModuleTypes { types, fallbacks: HashMap::new() }; modules.insert("runtime".to_string(), mod_types); let dot_types = Modules { modules }; assert_eq!(dot_types, deser_dot_types); diff --git a/integration_tests/Cargo.toml b/integration_tests/Cargo.toml index 09999bdc..e1477082 100644 --- a/integration_tests/Cargo.toml +++ b/integration_tests/Cargo.toml @@ -20,6 +20,7 @@ pretty_env_logger = "0.4" log = "0.4" hex = "0.4" paste = "1.0.3" +anyhow = "1" [[test]] name = "integration_tests" diff --git a/integration_tests/tests/storage.rs b/integration_tests/tests/storage.rs index 2d3b04d8..ad077146 100644 --- a/integration_tests/tests/storage.rs +++ b/integration_tests/tests/storage.rs @@ -7,6 +7,7 @@ use desub_core::{ use frame_system::AccountInfo; use pallet_balances::AccountData; use primitives::twox_128; +use anyhow::Result; fn mock_account_info() -> AccountInfo> { let mock_account_data: AccountData = @@ -39,7 +40,7 @@ fn should_decode_plain() { } #[test] -fn should_decode_map() { +fn should_decode_map() -> Result<()> { let _ = pretty_env_logger::try_init(); let types = extras::TypeResolver::default(); @@ -48,13 +49,13 @@ fn should_decode_map() { let meta = test_suite::runtime_v11(); let meta = Metadata::new(meta.as_slice()); decoder.register_version(2023, &meta); - - let account = mock_account_info(); - let encoded_account = account.encode(); + // AccountInfo from block 3944196 + let encoded_account = hex::decode("01000000037c127ed1d8c6010000000000000000000000000000000000000000000000000000406352bfc60100000000000000000000406352bfc601000000000000000000").unwrap(); let storage_key = hex::decode("26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da932a5935f6edc617ae178fef9eb1e211fbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f").unwrap(); - let res = decoder.decode_storage(2023, (storage_key, Some(encoded_account))).unwrap(); + let res = decoder.decode_storage(2023, (storage_key, Some(encoded_account)))?; println!("{:?}", res); + Ok(()) } #[test] diff --git a/integration_tests/tests/test_suite.rs b/integration_tests/tests/test_suite.rs index c1f2b320..57398941 100644 --- a/integration_tests/tests/test_suite.rs +++ b/integration_tests/tests/test_suite.rs @@ -120,6 +120,19 @@ pub fn runtime_v9_block500k() -> Vec { buffer } +/// Get some runtime metadata from KusamaCC3 at block 6 +/// Block hash +/// 0xb5ee550d20a55b76adeba7149516d367ac7cbdd95cd0864a8753d6b5dd02d3bb +/// +/// # Panics +/// Panics on std::io::Error +pub fn runtime_v9_block6() -> Vec { + let mut f = File::open("./data/metadata_v9_block6.bin").expect("Opening file failed"); + let mut buffer = Vec::new(); + f.read_to_end(&mut buffer).expect("Reading file failed"); + buffer +} + /// Get the runtime metadata from KusamaCC3 for metadata version 10 /// Block hash /// 0x627a6a8e7698dd360bd44e7816e7f8c5321fa31e0a3f39324d93ec5716a57fb5 @@ -140,15 +153,3 @@ pub fn runtime_v12_block_4643974() -> Vec { buffer } -/// Get some runtime metadata from KusamaCC3 at block 6 -/// Block hash -/// 0xb5ee550d20a55b76adeba7149516d367ac7cbdd95cd0864a8753d6b5dd02d3bb -/// -/// # Panics -/// Panics on std::io::Error -pub fn runtime_v9_block6() -> Vec { - let mut f = File::open("./data/metadata_v9_block6.bin").expect("Opening file failed"); - let mut buffer = Vec::new(); - f.read_to_end(&mut buffer).expect("Reading file failed"); - buffer -} From ec5e4b17029b1493d1fc87c71079f8332aa71ad2 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Tue, 31 Aug 2021 10:40:15 -0400 Subject: [PATCH 10/13] typo --- core/src/decoder/metadata.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/decoder/metadata.rs b/core/src/decoder/metadata.rs index fba74516..2c64aa6c 100644 --- a/core/src/decoder/metadata.rs +++ b/core/src/decoder/metadata.rs @@ -193,7 +193,7 @@ impl Metadata { meta.try_into().expect("Conversion failed") }, /* TODO remove panics */ - e => panic!("subPrefixedstrate metadata version {} is unknown, invalid or unsupported", e), + e => panic!("substrate metadata version {} is unknown, invalid or unsupported", e), } } From aa5e49dc688781cdba0ecfa3923a716e8eb62e04 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Tue, 31 Aug 2021 22:00:25 -0400 Subject: [PATCH 11/13] implement fallback --- Cargo.lock | 101 +----------------- core/Cargo.toml | 3 +- core/src/decoder.rs | 21 ++-- core/src/lib.rs | 4 + core/src/substrate_types.rs | 10 +- core/src/substrate_types/data.rs | 97 +++++++++++++++++ core/src/substrate_types/remote.rs | 32 +----- extras/Cargo.toml | 1 - extras/src/definitions/definitions.json | 4 +- extras/src/modules.rs | 10 +- extras/src/resolver.rs | 10 ++ .../sp_core_versions/core-7314a/src/ecdsa.rs | 1 + .../core-7314a/src/ed25519.rs | 1 + 13 files changed, 149 insertions(+), 146 deletions(-) create mode 100644 core/src/substrate_types/data.rs diff --git a/Cargo.lock b/Cargo.lock index ee3aee3b..bb5cf2b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -585,12 +585,11 @@ dependencies = [ "frame-metadatav11", "frame-metadatav8", "frame-metadatav9", + "frame-support", "hex", "log", "onig", "pallet-democracy", - "pallet-identity", - "pallet-indices", "parity-scale-codec 1.3.7", "parity-scale-codec 2.2.0", "pretty_env_logger", @@ -607,7 +606,6 @@ name = "desub-extras" version = "0.0.1" dependencies = [ "desub-core", - "env_logger 0.7.1", "log", "parity-scale-codec 1.3.7", "serde", @@ -701,26 +699,6 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" -[[package]] -name = "enumflags2" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0" -dependencies = [ - "enumflags2_derive", -] - -[[package]] -name = "enumflags2_derive" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "env_logger" version = "0.7.1" @@ -1156,15 +1134,6 @@ dependencies = [ "ahash", ] -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "hermit-abi" version = "0.1.19" @@ -1741,36 +1710,6 @@ dependencies = [ "sp-std 4.0.0-dev", ] -[[package]] -name = "pallet-identity" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" -dependencies = [ - "enumflags2", - "frame-benchmarking", - "frame-support", - "frame-system", - "parity-scale-codec 2.2.0", - "sp-io", - "sp-runtime", - "sp-std 4.0.0-dev", -] - -[[package]] -name = "pallet-indices" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" -dependencies = [ - "frame-support", - "frame-system", - "parity-scale-codec 2.2.0", - "sp-core 4.0.0-dev", - "sp-io", - "sp-keyring", - "sp-runtime", - "sp-std 4.0.0-dev", -] - [[package]] name = "parity-scale-codec" version = "1.3.7" @@ -2810,17 +2749,6 @@ dependencies = [ "tracing-core", ] -[[package]] -name = "sp-keyring" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" -dependencies = [ - "lazy_static", - "sp-core 4.0.0-dev", - "sp-runtime", - "strum", -] - [[package]] name = "sp-keystore" version = "0.10.0-dev" @@ -3129,27 +3057,6 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" -[[package]] -name = "strum" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7318c509b5ba57f18533982607f24070a55d353e90d4cae30c467cdb2ad5ac5c" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee8bc6b87a5112aeeab1f4a9f7ab634fe6cbefc4850006df31267f4cfb9e3149" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "substrate-bip39" version = "0.4.2" @@ -3481,12 +3388,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-segmentation" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" - [[package]] name = "unicode-width" version = "0.1.8" diff --git a/core/Cargo.toml b/core/Cargo.toml index 0f987772..d0716a03 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -18,9 +18,8 @@ dyn-clone = "1.0" hex = "0.4" runtime-version = { package = "sp-version", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } -pallet-indices = { package = "pallet-indices", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } pallet-democracy = { package = "pallet-democracy", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } -pallet-identity = { package = "pallet-identity", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } +frame-support = { package = "frame-support", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } primitives = { package = "sp-core", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } runtime-primitives = { package = "sp-runtime", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } diff --git a/core/src/decoder.rs b/core/src/decoder.rs index aec23109..4722139b 100644 --- a/core/src/decoder.rs +++ b/core/src/decoder.rs @@ -352,7 +352,14 @@ impl Decoder { )) })?; log::trace!("Resolved {:?}", new_type); - self.decode_single(module, spec, new_type, data, cursor, is_compact)? + let mut saved_cursor = *cursor; + let resolved = self.decode_single(module, spec, new_type, data, cursor, is_compact); + if resolved.is_err() { + if let Some(fallback) = self.types.try_fallback(self.chain.as_str(), spec, module, v) { + return Ok(self.decode_single(module, spec, fallback, data, &mut saved_cursor, is_compact)?); + } + } + resolved? } } RustTypeMarker::Unit(u) => SubstrateType::Unit(u.to_string()), @@ -714,20 +721,18 @@ impl Decoder { ), ]))) } - /* "Data" => { log::trace!("Data::cursor={}", *cursor); - let identity_data: pallet_identity::Data = Decode::decode(&mut &data[*cursor..])?; + let identity_data: substrate_types::Data = Decode::decode(&mut &data[*cursor..])?; match &identity_data { - pallet_identity::Data::None => (), - pallet_identity::Data::Raw(v) => *cursor += v.len(), + substrate_types::Data::None => (), + substrate_types::Data::Raw(v) => *cursor += v.len(), _ => *cursor += 32, }; // for the enum byte *cursor += 1; Ok(Some(SubstrateType::Data(identity_data))) } - */ "Call" | "GenericCall" => { let types = self.decode_call(spec, data, cursor)?; Ok(Some(SubstrateType::Call(types))) @@ -880,6 +885,10 @@ mod tests { Some(&RustTypeMarker::I128) } + fn try_fallback(&self, _chain: &str, _spec: u32, _module: &str, _ty: &str) -> Option<&RustTypeMarker> { + None + } + fn get_extrinsic_ty(&self, _chain: &str, _spec: u32, _ty: &str) -> Option<&RustTypeMarker> { None } diff --git a/core/src/lib.rs b/core/src/lib.rs index 8808e4ca..45526991 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -35,6 +35,10 @@ pub trait TypeDetective: fmt::Debug + dyn_clone::DynClone + Send + Sync { /// Get a 'RustTypeMarker' fn get(&self, chain: &str, spec: u32, module: &str, ty: &str) -> Option<&RustTypeMarker>; + /// Some types have a fallback type that may be decoded into if the original + /// type fails. + fn try_fallback(&self, chain: &str, spec: u32, module: &str, ty: &str) -> Option<&RustTypeMarker>; + /// get a type specific to decoding extrinsics fn get_extrinsic_ty(&self, chain: &str, spec: u32, ty: &str) -> Option<&RustTypeMarker>; } diff --git a/core/src/substrate_types.rs b/core/src/substrate_types.rs index d9ee6978..91239bcf 100644 --- a/core/src/substrate_types.rs +++ b/core/src/substrate_types.rs @@ -20,6 +20,7 @@ //! Display Implementation mod remote; +mod data; use self::remote::*; use crate::{Error, SetField}; @@ -28,10 +29,11 @@ use primitives::crypto::{Ss58AddressFormat, Ss58Codec}; use serde::Serialize; use std::{convert::TryFrom, fmt}; +pub use self::data::Data; + pub type Address = runtime_primitives::MultiAddress; pub type Vote = pallet_democracy::Vote; pub type Conviction = pallet_democracy::Conviction; -// pub type Data = pallet_identity::Data; /// A 'stateful' version of [RustTypeMarker](enum.RustTypeMarker.html). /// 'Std' variant is not here like in RustTypeMarker. @@ -58,10 +60,8 @@ pub enum SubstrateType { // u32 and [u8; 32] for its index/id #[serde(with = "RemoteAddress")] Address(Address), -/* - #[serde(with = "RemoteData")] + /// Data Identity Type Data(Data), -*/ /// SignedExtension Type SignedExtra(String), @@ -146,7 +146,7 @@ impl fmt::Display for SubstrateType { runtime_primitives::MultiAddress::Address32(ary) => write!(f, "Address32: {:?}", ary), runtime_primitives::MultiAddress::Address20(ary) => write!(f, "Address20: {:?}", ary), }, - // SubstrateType::Data(d) => write!(f, "{:?}", d), + SubstrateType::Data(d) => write!(f, "{:?}", d), SubstrateType::SignedExtra(v) => write!(f, "{}", v), SubstrateType::Unit(u) => write!(f, "{}", u), SubstrateType::Composite(v) => { diff --git a/core/src/substrate_types/data.rs b/core/src/substrate_types/data.rs new file mode 100644 index 00000000..4325ece6 --- /dev/null +++ b/core/src/substrate_types/data.rs @@ -0,0 +1,97 @@ +// Copyright 2019-2021 Parity Technologies (UK) Ltd. +// This file is part of substrate-desub. +// +// substrate-desub is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// substrate-desub is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with substrate-desub. If not, see . + +//! Copy of this: https://substrate.dev/rustdocs/latest/pallet_identity/enum.Data.html +//! For the purpose of Decoding the Data field. +//! Because of the specificity/complexity of decoding: +//! - `BoundedVec` includes private tuple fields with no getters so Serde `remote` does not work +//! - `Data` has a special way of encoding/decoding +//! Data impl is copied over and must be maintaned against substrate master. + + +use codec::{Decode, Encode}; +use serde::{Serialize, Deserialize}; +use std::iter::once; + + +/// Either underlying data blob if it is at most 32 bytes, or a hash of it. If the data is greater +/// than 32-bytes then it will be truncated when encoding. +/// +/// Can also be `None`. +#[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)] +pub enum Data { + /// No data here. + None, + /// The data is stored directly. + Raw(Vec), + /// Only the Blake2 hash of the data is stored. The preimage of the hash may be retrieved + /// through some hash-lookup service. + BlakeTwo256([u8; 32]), + /// Only the SHA2-256 hash of the data is stored. The preimage of the hash may be retrieved + /// through some hash-lookup service. + Sha256([u8; 32]), + /// Only the Keccak-256 hash of the data is stored. The preimage of the hash may be retrieved + /// through some hash-lookup service. + Keccak256([u8; 32]), + /// Only the SHA3-256 hash of the data is stored. The preimage of the hash may be retrieved + /// through some hash-lookup service. + ShaThree256([u8; 32]), +} + +impl Decode for Data { + fn decode(input: &mut I) -> Result { + let b = input.read_byte()?; + Ok(match b { + 0 => Data::None, + n @ 1 ..= 33 => { + let mut r = vec![0u8; n as usize - 1]; + input.read(&mut r[..])?; + Data::Raw(r) + } + 34 => Data::BlakeTwo256(<[u8; 32]>::decode(input)?), + 35 => Data::Sha256(<[u8; 32]>::decode(input)?), + 36 => Data::Keccak256(<[u8; 32]>::decode(input)?), + 37 => Data::ShaThree256(<[u8; 32]>::decode(input)?), + _ => return Err(codec::Error::from("invalid leading byte")), + }) + } +} + +impl Encode for Data { + fn encode(&self) -> Vec { + match self { + Data::None => vec![0u8; 1], + Data::Raw(ref x) => { + let l = x.len().min(32); + let mut r = vec![l as u8 + 1; l + 1]; + r[1..].copy_from_slice(&x[..l as usize]); + r + } + Data::BlakeTwo256(ref h) => once(34u8).chain(h.iter().cloned()).collect(), + Data::Sha256(ref h) => once(35u8).chain(h.iter().cloned()).collect(), + Data::Keccak256(ref h) => once(36u8).chain(h.iter().cloned()).collect(), + Data::ShaThree256(ref h) => once(37u8).chain(h.iter().cloned()).collect(), + } + } +} +impl codec::EncodeLike for Data {} + +impl Default for Data { + fn default() -> Self { + Self::None + } +} + diff --git a/core/src/substrate_types/remote.rs b/core/src/substrate_types/remote.rs index 0a54dc53..3d0b41a8 100644 --- a/core/src/substrate_types/remote.rs +++ b/core/src/substrate_types/remote.rs @@ -1,4 +1,4 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. +// Copyright 2019-2021 Parity Technologies (UK) Ltd. // This file is part of substrate-desub. // // substrate-desub is free software: you can redistribute it and/or modify @@ -17,7 +17,8 @@ use primitives::crypto::AccountId32; use serde::{Deserialize, Serialize}; -use super::{Address, Conviction, Vote}; // Data +use super::{Address, Conviction, Vote}; + #[derive(Serialize, Deserialize)] #[serde(remote = "Address")] @@ -42,33 +43,6 @@ pub struct RemoteVote { pub conviction: Conviction, } -/* -/// Either underlying data blob if it is at most 32 bytes, or a hash of it. If the data is greater -/// than 32-bytes then it will be truncated when encoding. -/// -/// Can also be `None`. -#[derive(Serialize, Deserialize)] -#[serde(remote = "Data")] -pub enum RemoteData { - /// No data here. - None, - /// The data is stored directly. - Raw(BoundedVec,), - /// Only the Blake2 hash of the data is stored. The preimage of the hash may be retrieved - /// through some hash-lookup service. - BlakeTwo256([u8; 32]), - /// Only the SHA2-256 hash of the data is stored. The preimage of the hash may be retrieved - /// through some hash-lookup service. - Sha256([u8; 32]), - /// Only the Keccak-256 hash of the data is stored. The preimage of the hash may be retrieved - /// through some hash-lookup service. - Keccak256([u8; 32]), - /// Only the SHA3-256 hash of the data is stored. The preimage of the hash may be retrieved - /// through some hash-lookup service. - ShaThree256([u8; 32]), -} -*/ - #[derive(Serialize, Deserialize)] #[serde(remote = "Conviction")] pub enum RemoteConviction { diff --git a/extras/Cargo.toml b/extras/Cargo.toml index bc0c201e..d2da5f6d 100644 --- a/extras/Cargo.toml +++ b/extras/Cargo.toml @@ -11,7 +11,6 @@ thiserror = "1.0" core = { path = "../core", package = "desub-core" } codec = { version = "1", features = ["derive"], package = "parity-scale-codec" } log = { version = "0.4" } -env_logger = "0.7" serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0", features = ["preserve_order"] } diff --git a/extras/src/definitions/definitions.json b/extras/src/definitions/definitions.json index 484e7d10..a40d084c 100644 --- a/extras/src/definitions/definitions.json +++ b/extras/src/definitions/definitions.json @@ -1616,7 +1616,7 @@ "Twitter": 128 } }, - "IdentityInfoAdditional": "(Data, Data)", + "IdentityInfoAdditional": "(Data, Data)", "IdentityInfo": { "additional": "Vec", "display": "Data", @@ -2752,7 +2752,7 @@ "NewConfiguration": "Option" } }, - "ConsensusEngineId": "GenericConsensusEngineId", + "ConsensusEngineId": "GenericConsensusEngineId", "CodecHash": "Hash", "Digest": { "logs": "Vec" diff --git a/extras/src/modules.rs b/extras/src/modules.rs index 682f7e93..df08736e 100644 --- a/extras/src/modules.rs +++ b/extras/src/modules.rs @@ -40,7 +40,11 @@ impl Modules { } pub fn get_type(&self, module: &str, ty: &str) -> Option<&RustTypeMarker> { - self.modules.get(module)?.types.get(ty) + self.modules.get(module)?.get(ty) + } + + pub fn try_fallback(&self, module: &str, ty: &str) -> Option<&RustTypeMarker> { + self.modules.get(module)?.try_fallback(ty) } /// Iterate over all the types in each module @@ -62,6 +66,10 @@ impl ModuleTypes { self.types.get(ty) } + pub fn try_fallback(&self, ty: &str) -> Option<&RustTypeMarker> { + self.fallbacks.get(ty) + } + /// Merges a ModuleTypes struct with another, to create a new HashMap /// The `other` struct takes priority if there are type conflicts pub fn merge(&self, other: &ModuleTypes) -> ModuleTypes { diff --git a/extras/src/resolver.rs b/extras/src/resolver.rs index fc865830..91d54a89 100644 --- a/extras/src/resolver.rs +++ b/extras/src/resolver.rs @@ -134,6 +134,12 @@ impl TypeResolver { } } + pub fn try_fallback(&self, chain: &str, module: &str, ty: &str) -> Option<&RustTypeMarker> { + let (module, ty, _) = sanitize_types(module, ty, chain); + self.mods.try_fallback(&module, &ty) + } + + /// Get type for decoding an Extrinsic pub fn get_ext_ty(&self, chain: &str, spec: u32, ty: &str) -> Option<&RustTypeMarker> { if let Some(t) = self.extrinsics.get(ty, spec, chain) { match t { @@ -198,6 +204,10 @@ impl TypeDetective for TypeResolver { TypeResolver::get(self, chain, spec, module, ty) } + fn try_fallback(&self, chain: &str, spec: u32, module: &str, ty: &str) -> Option<&RustTypeMarker> { + TypeResolver::get(self, chain, spec, module, ty) + } + fn get_extrinsic_ty(&self, chain: &str, spec: u32, ty: &str) -> Option<&RustTypeMarker> { TypeResolver::get_ext_ty(self, chain, spec, ty) } diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/ecdsa.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/ecdsa.rs index a836eb0e..73e0a6db 100644 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/ecdsa.rs +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/ecdsa.rs @@ -667,6 +667,7 @@ mod test { } #[test] + #[ignore] // we are not using ss58 from this crate because it's only for legacy purposes (decoding) fn ss58check_roundtrip_works() { let pair = Pair::from_seed(b"12345678901234567890123456789012"); let public = pair.public(); diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/ed25519.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/ed25519.rs index fcc84c5c..e7fc53b4 100644 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/ed25519.rs +++ b/substrate-metadata-versions/sp_core_versions/core-7314a/src/ed25519.rs @@ -677,6 +677,7 @@ mod test { } #[test] + #[ignore] // We are not using ss58 from this crate because only for legacy purposes (decoding) fn ss58check_roundtrip_works() { let pair = Pair::from_seed(b"12345678901234567890123456789012"); let public = pair.public(); From bb12194ae0decdd372d2de7f54a76f6a25621051 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Thu, 2 Sep 2021 21:22:03 -0400 Subject: [PATCH 12/13] start working on tx verifier for entire chains of extrinsics --- Cargo.toml | 4 + bin/tx-decoder/Cargo.lock | 4143 +++++++++++++++++ bin/tx-decoder/Cargo.toml | 19 + bin/tx-decoder/README.md | 12 + bin/tx-decoder/src/main.rs | 65 + bin/tx-decoder/src/queries.rs | 55 + core/src/lib.rs | 2 +- integration_tests/tests/storage.rs | 28 +- .../tests/storage_extended_tests.rs | 1 + integration_tests/tests/test_suite.rs | 76 +- .../tests/test_suite/runtime_metadata.rs | 74 + 11 files changed, 4398 insertions(+), 81 deletions(-) create mode 100644 bin/tx-decoder/Cargo.lock create mode 100644 bin/tx-decoder/Cargo.toml create mode 100644 bin/tx-decoder/README.md create mode 100644 bin/tx-decoder/src/main.rs create mode 100644 bin/tx-decoder/src/queries.rs create mode 100644 integration_tests/tests/storage_extended_tests.rs create mode 100644 integration_tests/tests/test_suite/runtime_metadata.rs diff --git a/Cargo.toml b/Cargo.toml index d8979db0..3744dbdb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,10 @@ members = [ "substrate-metadata-versions/sp_core_versions/core-7314a" ] +exclude = [ + "bin/tx-decoder" +] + [patch.crates-io] # codec = { git = "https://github.com/insipx/parity-scale-codec", version = "1.3", branch = "insipx/debugging", package = "parity-scale-codec" } # parity-scale-codec-derive = { path = "derive", version = "^1", git = "https://github.com/insipx/parity-scale-codec", branch="insipx/debugging" } diff --git a/bin/tx-decoder/Cargo.lock b/bin/tx-decoder/Cargo.lock new file mode 100644 index 00000000..ab5a0442 --- /dev/null +++ b/bin/tx-decoder/Cargo.lock @@ -0,0 +1,4143 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "addr2line" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98" +dependencies = [ + "getrandom 0.2.3", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" + +[[package]] +name = "approx" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "072df7202e63b127ab55acfe16ce97013d5b97bf160489336d3f1840fd78e99e" +dependencies = [ + "num-traits", +] + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", +] + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "arrayvec" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4dc07131ffa69b8072d35f5007352af944213cde02545e2103680baed38fcd" + +[[package]] +name = "async-attributes" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "async-channel" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-executor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "once_cell", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9586ec52317f36de58453159d48351bc244bc24ced3effc1fce22f3d48664af6" +dependencies = [ + "async-channel", + "async-executor", + "async-io", + "async-mutex", + "blocking", + "futures-lite", + "num_cpus", + "once_cell", +] + +[[package]] +name = "async-io" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a811e6a479f2439f0c04038796b5cfb3d2ad56c230e0f2d3f7b04d68cfee607b" +dependencies = [ + "concurrent-queue", + "futures-lite", + "libc", + "log", + "once_cell", + "parking", + "polling", + "slab", + "socket2", + "waker-fn", + "winapi", +] + +[[package]] +name = "async-lock" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6a8ea61bf9947a1007c5cada31e647dbc77b103c679858150003ba697ea798b" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-mutex" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-process" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b21b63ab5a0db0369deb913540af2892750e42d949faacc7a61495ac418a1692" +dependencies = [ + "async-io", + "blocking", + "cfg-if 1.0.0", + "event-listener", + "futures-lite", + "libc", + "once_cell", + "signal-hook", + "winapi", +] + +[[package]] +name = "async-rustls" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c86f33abd5a4f3e2d6d9251a9e0c6a7e52eb1113caf893dae8429bf4a53f378" +dependencies = [ + "futures-lite", + "rustls", + "webpki", +] + +[[package]] +name = "async-std" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8056f1455169ab86dd47b47391e4ab0cbd25410a70e9fe675544f49bafaf952" +dependencies = [ + "async-attributes", + "async-channel", + "async-global-executor", + "async-io", + "async-lock", + "async-process", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "num_cpus", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-stream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171374e7e3b2504e0e5236e3b59260560f9fe94bfe9ac39ba5e4e929c5590625" +dependencies = [ + "async-stream-impl", + "futures-core", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "648ed8c8d2ce5409ccd57453d9d1b214b342a0d69376a6feda1fd6cae3299308" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-task" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" + +[[package]] +name = "async-trait" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atoi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616896e05fc0e2649463a93a15183c6a16bf03413a7af88ef1285ddedfa9cda5" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atomic-waker" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "backtrace" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01" +dependencies = [ + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base58" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bindgen" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da379dbebc0b76ef63ca68d8fc6e71c0f13e59432e0987e508c1820e6ab5239" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "clap", + "env_logger 0.8.4", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "which", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitvec" +version = "0.17.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" +dependencies = [ + "either", + "radium 0.3.0", +] + +[[package]] +name = "bitvec" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" +dependencies = [ + "funty", + "radium 0.6.2", + "tap", + "wyz", +] + +[[package]] +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +dependencies = [ + "arrayvec 0.4.12", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array 0.12.4", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array 0.14.4", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "blocking" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e170dbede1f740736619b776d7251cb1b9095c435c34d8ca9f57fcd2f335e9" +dependencies = [ + "async-channel", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", + "once_cell", +] + +[[package]] +name = "bumpalo" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" + +[[package]] +name = "byte-slice-cast" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" + +[[package]] +name = "byte-slice-cast" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65c1bf4a04a88c54f589125563643d773f3254b5c38571395e2b591c693bbc81" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "cache-padded" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" + +[[package]] +name = "cc" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0" +dependencies = [ + "jobserver", +] + +[[package]] +name = "cexpr" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" +dependencies = [ + "nom 5.1.2", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "winapi", +] + +[[package]] +name = "clang-sys" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cf2cc85830eae84823884db23c5306442a6c3d5bfd3beb2f2a2c829faa1816" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "ansi_term 0.11.0", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "concurrent-queue" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" +dependencies = [ + "cache-padded", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10c2722795460108a7872e1cd933a85d6ec38abc4baecad51028f702da28889f" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403" + +[[package]] +name = "crossbeam-channel" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b10ddc024425c88c2ad148c1b0fd53f4c6d38db9697c9f1588381212fa657c9" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +dependencies = [ + "cfg-if 1.0.0", + "lazy_static", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-mac" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +dependencies = [ + "generic-array 0.12.4", + "subtle 1.0.0", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array 0.14.4", + "subtle 2.4.1", +] + +[[package]] +name = "crypto-mac" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff07008ec701e8028e2ceb8f83f0e4274ee62bd2dbdc4fefff2e9a91824081a" +dependencies = [ + "generic-array 0.14.4", + "subtle 2.4.1", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array 0.14.4", + "subtle 2.4.1", +] + +[[package]] +name = "ctor" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "curve25519-dalek" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b85542f99a2dfa2a1b8e192662741c9859a846b296bef1c92ef9b58b5a216" +dependencies = [ + "byteorder", + "digest 0.8.1", + "rand_core 0.5.1", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "derive_more" +version = "0.99.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn", +] + +[[package]] +name = "desub-core" +version = "0.0.1" +dependencies = [ + "derive_more", + "dyn-clone", + "frame-metadata 14.0.0", + "frame-metadatav10", + "frame-metadatav11", + "frame-metadatav8", + "frame-metadatav9", + "frame-support", + "hex", + "log", + "onig", + "pallet-democracy", + "parity-scale-codec 1.3.7", + "parity-scale-codec 2.2.0", + "serde", + "serde_json", + "sp-core 4.0.0-dev", + "sp-runtime", + "sp-version", + "thiserror", +] + +[[package]] +name = "desub-extras" +version = "0.0.1" +dependencies = [ + "desub-core", + "log", + "parity-scale-codec 1.3.7", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.4", +] + +[[package]] +name = "dirs" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "dyn-clonable" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4" +dependencies = [ + "dyn-clonable-impl", + "dyn-clone", +] + +[[package]] +name = "dyn-clonable-impl" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dyn-clone" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" + +[[package]] +name = "ed25519" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4620d40f6d2601794401d6dd95a5cf69b6c157852539470eeda433a99b3c0efc" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519", + "rand 0.7.3", + "serde", + "sha2 0.9.6", + "zeroize", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "atty", + "humantime 1.3.0", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "env_logger" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" +dependencies = [ + "atty", + "humantime 2.1.0", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "environmental" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b91989ae21441195d7d9b9993a2f9295c7e1a8c96255d8b729accddc124797" + +[[package]] +name = "erased-serde" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3de9ad4541d99dc22b59134e7ff8dc3d6c988c89ecd7324bf10a8362b07a2afa" +dependencies = [ + "serde", +] + +[[package]] +name = "event-listener" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" + +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "fastrand" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b394ed3d285a429378d3b384b9eb1285267e7df4b166df24b7a6939a04dc392e" +dependencies = [ + "instant", +] + +[[package]] +name = "fixed-hash" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11498d382790b7a8f2fd211780bec78619bba81cdad3a283997c0c41f836759c" +dependencies = [ + "byteorder", + "rand 0.7.3", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "byteorder", + "rand 0.8.4", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "frame-benchmarking" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "frame-support", + "frame-system", + "linregress", + "log", + "parity-scale-codec 2.2.0", + "paste", + "sp-api", + "sp-io", + "sp-runtime", + "sp-runtime-interface 4.0.0-dev", + "sp-std 4.0.0-dev", + "sp-storage 4.0.0-dev", +] + +[[package]] +name = "frame-metadata" +version = "14.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "parity-scale-codec 2.2.0", + "serde", + "sp-core 4.0.0-dev", + "sp-std 4.0.0-dev", +] + +[[package]] +name = "frame-metadata" +version = "14.0.0" +source = "git+https://github.com/paritytech/frame-metadata#39fe3d8f279a37c7c414bf37db281a35e0ccd520" +dependencies = [ + "cfg-if 1.0.0", + "parity-scale-codec 2.2.0", + "scale-info", + "serde", +] + +[[package]] +name = "frame-metadatav10" +version = "10.0.0" +dependencies = [ + "parity-scale-codec 1.3.7", + "serde", + "sp-core 2.0.0", + "sp-std 2.0.0", +] + +[[package]] +name = "frame-metadatav11" +version = "11.0.0-rc6" +dependencies = [ + "parity-scale-codec 1.3.7", + "serde", + "sp-core 2.0.0", + "sp-std 2.0.0", +] + +[[package]] +name = "frame-metadatav8" +version = "2.0.0" +dependencies = [ + "parity-scale-codec 1.3.7", + "serde", + "sp-core 2.0.0", + "sp-std 2.0.0", +] + +[[package]] +name = "frame-metadatav9" +version = "2.0.0" +dependencies = [ + "parity-scale-codec 1.3.7", + "serde", + "sp-core 2.0.0", + "sp-std 2.0.0", +] + +[[package]] +name = "frame-support" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "bitflags", + "frame-metadata 14.0.0-dev", + "frame-support-procedural", + "impl-trait-for-tuples 0.2.1", + "log", + "once_cell", + "parity-scale-codec 2.2.0", + "paste", + "serde", + "smallvec", + "sp-arithmetic", + "sp-core 4.0.0-dev", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-state-machine", + "sp-std 4.0.0-dev", + "sp-tracing 4.0.0-dev", +] + +[[package]] +name = "frame-support-procedural" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "Inflector", + "frame-support-procedural-tools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "frame-support-procedural-tools" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "frame-support-procedural-tools-derive", + "proc-macro-crate 1.0.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "frame-support-procedural-tools-derive" +version = "3.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "frame-system" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "frame-support", + "impl-trait-for-tuples 0.2.1", + "log", + "parity-scale-codec 2.2.0", + "serde", + "sp-core 4.0.0-dev", + "sp-io", + "sp-runtime", + "sp-std 4.0.0-dev", + "sp-version", +] + +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + +[[package]] +name = "futures" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" + +[[package]] +name = "futures-executor" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-intrusive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62007592ac46aa7c2b6416f7deb9a8a8f63a01e0f1d6e1787d5630170db2b63e" +dependencies = [ + "futures-core", + "lock_api 0.4.5", + "parking_lot 0.11.2", +] + +[[package]] +name = "futures-io" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" + +[[package]] +name = "futures-lite" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" +dependencies = [ + "autocfg", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" + +[[package]] +name = "futures-task" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" + +[[package]] +name = "futures-util" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" +dependencies = [ + "autocfg", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "gimli" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "gloo-timers" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "hash-db" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" + +[[package]] +name = "hash256-std-hasher" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" +dependencies = [ + "crunchy", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashlink" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" +dependencies = [ + "hashbrown", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" +dependencies = [ + "crypto-mac 0.7.0", + "digest 0.8.1", +] + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac 0.8.0", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" +dependencies = [ + "crypto-mac 0.10.1", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac 0.11.1", + "digest 0.9.0", +] + +[[package]] +name = "hmac-drbg" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" +dependencies = [ + "digest 0.8.1", + "generic-array 0.12.4", + "hmac 0.7.1", +] + +[[package]] +name = "humantime" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "impl-codec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" +dependencies = [ + "parity-scale-codec 1.3.7", +] + +[[package]] +name = "impl-codec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "161ebdfec3c8e3b52bf61c4f3550a1eea4f9579d10dc1b936f3171ebdcd6c443" +dependencies = [ + "parity-scale-codec 2.2.0", +] + +[[package]] +name = "impl-serde" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b47ca4d2b6931707a55fce5cf66aff80e2178c8b63bbb4ecb5695cbc870ddf6f" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5dacb10c5b3bb92d46ba347505a9041e676bb20ad220101326bffb0c93031ee" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "indexmap" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "integer-sqrt" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" +dependencies = [ + "num-traits", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "jobserver" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "keccak" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" + +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" + +[[package]] +name = "libloading" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a" +dependencies = [ + "cfg-if 1.0.0", + "winapi", +] + +[[package]] +name = "libm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" + +[[package]] +name = "libsecp256k1" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" +dependencies = [ + "arrayref", + "crunchy", + "digest 0.8.1", + "hmac-drbg", + "rand 0.7.3", + "sha2 0.8.2", + "subtle 2.4.1", + "typenum", +] + +[[package]] +name = "linregress" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6c601a85f5ecd1aba625247bca0031585fb1c446461b142878a16f8245ddeb8" +dependencies = [ + "nalgebra", + "statrs", +] + +[[package]] +name = "lock_api" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "lock_api" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if 1.0.0", + "value-bag", +] + +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + +[[package]] +name = "matchers" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "matrixmultiply" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a8a15b776d9dfaecd44b03c5828c2199cddff5247215858aac14624f8d6b741" +dependencies = [ + "rawpointer", +] + +[[package]] +name = "md-5" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memory-db" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de006e09d04fc301a5f7e817b75aa49801c4479a8af753764416b085337ddcc5" +dependencies = [ + "hash-db", + "hashbrown", + "parity-util-mem", +] + +[[package]] +name = "memory_units" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" + +[[package]] +name = "merlin" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e261cf0f8b3c42ded9f7d2bb59dea03aa52bc8a1cbc7482f9fc3fd1229d3b42" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] +name = "minimal-lexical" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6595bb28ed34f43c3fe088e48f6cfb2e033cab45f25a5384d5fdf564fbc8c4b2" + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "nalgebra" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "462fffe4002f4f2e1f6a9dcf12cc1a6fc0e15989014efc02a941d3e0f5dc2120" +dependencies = [ + "approx", + "matrixmultiply", + "nalgebra-macros", + "num-complex", + "num-rational 0.4.0", + "num-traits", + "rand 0.8.4", + "rand_distr", + "simba", + "typenum", +] + +[[package]] +name = "nalgebra-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01fcc0b8149b4632adc89ac3b7b31a12fb6099a0317a4eb2ebff574ef7de7218" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "nom" +version = "5.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" +dependencies = [ + "memchr", + "version_check", +] + +[[package]] +name = "nom" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffd9d26838a953b4af82cbeb9f1592c6798916983959be223a7124e992742c1" +dependencies = [ + "memchr", + "minimal-lexical", + "version_check", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +dependencies = [ + "parking_lot 0.11.2", +] + +[[package]] +name = "onig" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e723fc996fff1aeab8f62205f3e8528bf498bdd5eadb2784d2d31f30077947" +dependencies = [ + "bitflags", + "lazy_static", + "libc", + "onig_sys", +] + +[[package]] +name = "onig_sys" +version = "69.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fd9442a09e4fbd08d196ddf419b2c79a43c3a46c800320cc841d45c2449a240" +dependencies = [ + "bindgen", + "cc", + "pkg-config", +] + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "pallet-democracy" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec 2.2.0", + "serde", + "sp-io", + "sp-runtime", + "sp-std 4.0.0-dev", +] + +[[package]] +name = "parity-scale-codec" +version = "1.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b26b16c7687c3075982af47719e481815df30bc544f7a6690763a25ca16e9d" +dependencies = [ + "arrayvec 0.5.2", + "bitvec 0.17.4", + "byte-slice-cast 0.3.5", + "parity-scale-codec-derive 1.2.3", + "serde", +] + +[[package]] +name = "parity-scale-codec" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8975095a2a03bbbdc70a74ab11a4f76a6d0b84680d87c68d722531b0ac28e8a9" +dependencies = [ + "arrayvec 0.7.1", + "bitvec 0.20.4", + "byte-slice-cast 1.0.0", + "impl-trait-for-tuples 0.2.1", + "parity-scale-codec-derive 2.2.0", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41512944b1faff334a5f1b9447611bf4ef40638ccb6328173dacefb338e878c" +dependencies = [ + "proc-macro-crate 0.1.5", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40dbbfef7f0a1143c5b06e0d76a6278e25dac0bc1af4be51a0fbb73f07e7ad09" +dependencies = [ + "proc-macro-crate 1.0.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "parity-util-mem" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ad6f1acec69b95caf435bbd158d486e5a0a44fcf51531e84922c59ff09e8457" +dependencies = [ + "cfg-if 1.0.0", + "hashbrown", + "impl-trait-for-tuples 0.2.1", + "parity-util-mem-derive", + "parking_lot 0.11.2", + "primitive-types 0.10.1", + "winapi", +] + +[[package]] +name = "parity-util-mem-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" +dependencies = [ + "proc-macro2", + "syn", + "synstructure", +] + +[[package]] +name = "parity-wasm" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" + +[[package]] +name = "parity-wasm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" + +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + +[[package]] +name = "parking_lot" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" +dependencies = [ + "lock_api 0.3.4", + "parking_lot_core 0.7.2", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api 0.4.5", + "parking_lot_core 0.8.5", +] + +[[package]] +name = "parking_lot_core" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" +dependencies = [ + "cfg-if 0.1.10", + "cloudabi", + "libc", + "redox_syscall 0.1.57", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall 0.2.10", + "smallvec", + "winapi", +] + +[[package]] +name = "paste" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58" + +[[package]] +name = "pbkdf2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" +dependencies = [ + "byteorder", + "crypto-mac 0.7.0", +] + +[[package]] +name = "pbkdf2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" +dependencies = [ + "crypto-mac 0.8.0", +] + +[[package]] +name = "pbkdf2" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa" +dependencies = [ + "crypto-mac 0.11.1", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + +[[package]] +name = "polling" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92341d779fa34ea8437ef4d82d440d5e1ce3f3ff7f824aa64424cd481f9a1f25" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "log", + "wepoll-ffi", + "winapi", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "pretty_env_logger" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" +dependencies = [ + "env_logger 0.7.1", + "log", +] + +[[package]] +name = "primitive-types" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd39dcacf71411ba488570da7bbc89b717225e46478b30ba99b92db6b149809" +dependencies = [ + "fixed-hash 0.6.1", + "impl-codec 0.4.2", + "impl-serde", + "uint 0.8.5", +] + +[[package]] +name = "primitive-types" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" +dependencies = [ + "fixed-hash 0.7.0", + "impl-codec 0.5.1", + "impl-serde", + "uint 0.9.1", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fdbd1df62156fbc5945f4762632564d7d038153091c3fcf1067f6aef7cff92" +dependencies = [ + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro-nested" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" + +[[package]] +name = "proc-macro2" +version = "1.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" + +[[package]] +name = "radium" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.3", +] + +[[package]] +name = "rand_distr" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051b398806e42b9cd04ad9ec8f81e355d0a382c543ac6672c62f5a5b452ef142" +dependencies = [ + "num-traits", + "rand 0.8.4", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +dependencies = [ + "getrandom 0.2.3", + "redox_syscall 0.2.10", +] + +[[package]] +name = "ref-cast" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300f2a835d808734ee295d45007adacb9ebb29dd3ae2424acfa17930cae541da" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c38e3aecd2b21cb3959637b883bb3714bc7e43f0268b9a29d3743ee3e55cdd2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver", +] + +[[package]] +name = "rustls" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +dependencies = [ + "base64", + "log", + "ring", + "sct", + "webpki", +] + +[[package]] +name = "ruzstd" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cada0ef59efa6a5f4dc5e491f93d9f31e3fc7758df421ff1de8a706338e1100" +dependencies = [ + "byteorder", + "twox-hash", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "scale-info" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c55b744399c25532d63a0d2789b109df8d46fc93752d46b0782991a931a782f" +dependencies = [ + "bitvec 0.20.4", + "cfg-if 1.0.0", + "derive_more", + "parity-scale-codec 2.2.0", + "scale-info-derive", + "serde", +] + +[[package]] +name = "scale-info-derive" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baeb2780690380592f86205aa4ee49815feb2acad8c2f59e6dd207148c3f1fcd" +dependencies = [ + "proc-macro-crate 1.0.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "schnorrkel" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "curve25519-dalek 2.1.3", + "getrandom 0.1.16", + "merlin", + "rand 0.7.3", + "rand_core 0.5.1", + "sha2 0.8.2", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "secrecy" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9182278ed645df3477a9c27bfee0621c621aa16f6972635f7f795dae3d81070f" +dependencies = [ + "zeroize", +] + +[[package]] +name = "secrecy" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0673d6a6449f5e7d12a1caf424fd9363e2af3a4953023ed455e3c4beef4597c0" +dependencies = [ + "zeroize", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "serde" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "sha2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +dependencies = [ + "block-buffer 0.7.3", + "digest 0.8.1", + "fake-simd", + "opaque-debug 0.2.3", +] + +[[package]] +name = "sha2" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9204c41a1597a8c5af23c82d1c921cb01ec0a4c59e07a9c7306062829a3903f3" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "sharded-slab" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740223c51853f3145fe7c90360d2d4232f2b62e3449489c207eccde818979982" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" + +[[package]] +name = "signal-hook" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c98891d737e271a2954825ef19e46bd16bdb98e2746f2eec4f7a4ef7946efd1" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335" + +[[package]] +name = "simba" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e82063457853d00243beda9952e910b82593e4b07ae9f721b9278a99a0d3d5c" +dependencies = [ + "approx", + "num-complex", + "num-traits", + "paste", +] + +[[package]] +name = "slab" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" + +[[package]] +name = "slog" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06" +dependencies = [ + "erased-serde", +] + +[[package]] +name = "smallvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" + +[[package]] +name = "socket2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "765f090f0e423d2b55843402a07915add955e7d60657db13707a159727326cad" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "sp-api" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "hash-db", + "log", + "parity-scale-codec 2.2.0", + "sp-api-proc-macro", + "sp-core 4.0.0-dev", + "sp-runtime", + "sp-state-machine", + "sp-std 4.0.0-dev", + "sp-version", + "thiserror", +] + +[[package]] +name = "sp-api-proc-macro" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "blake2-rfc", + "proc-macro-crate 1.0.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-application-crypto" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "parity-scale-codec 2.2.0", + "serde", + "sp-core 4.0.0-dev", + "sp-io", + "sp-std 4.0.0-dev", +] + +[[package]] +name = "sp-arithmetic" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "integer-sqrt", + "num-traits", + "parity-scale-codec 2.2.0", + "serde", + "sp-debug-derive 3.0.0", + "sp-std 4.0.0-dev", + "static_assertions", +] + +[[package]] +name = "sp-core" +version = "2.0.0" +dependencies = [ + "base58", + "blake2-rfc", + "byteorder", + "derive_more", + "dyn-clonable", + "ed25519-dalek", + "futures", + "hash-db", + "hash256-std-hasher", + "hex", + "impl-serde", + "lazy_static", + "libsecp256k1", + "log", + "merlin", + "num-traits", + "parity-scale-codec 1.3.7", + "parity-util-mem", + "parking_lot 0.10.2", + "primitive-types 0.7.3", + "rand 0.7.3", + "regex", + "schnorrkel", + "secrecy 0.6.0", + "serde", + "sha2 0.8.2", + "sp-debug-derive 2.0.0", + "sp-externalities 0.8.0", + "sp-runtime-interface 2.0.0", + "sp-std 2.0.0", + "sp-storage 2.0.0", + "substrate-bip39", + "tiny-bip39 0.7.3", + "tiny-keccak", + "twox-hash", + "wasmi 0.6.2", + "zeroize", +] + +[[package]] +name = "sp-core" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "base58", + "blake2-rfc", + "byteorder", + "dyn-clonable", + "ed25519-dalek", + "futures", + "hash-db", + "hash256-std-hasher", + "hex", + "impl-serde", + "lazy_static", + "libsecp256k1", + "log", + "merlin", + "num-traits", + "parity-scale-codec 2.2.0", + "parity-util-mem", + "parking_lot 0.11.2", + "primitive-types 0.10.1", + "rand 0.7.3", + "regex", + "schnorrkel", + "secrecy 0.7.0", + "serde", + "sha2 0.9.6", + "sp-debug-derive 3.0.0", + "sp-externalities 0.10.0-dev", + "sp-runtime-interface 4.0.0-dev", + "sp-std 4.0.0-dev", + "sp-storage 4.0.0-dev", + "substrate-bip39", + "thiserror", + "tiny-bip39 0.8.0", + "tiny-keccak", + "twox-hash", + "wasmi 0.9.0", + "zeroize", +] + +[[package]] +name = "sp-debug-derive" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-debug-derive" +version = "3.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-externalities" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "environmental", + "parity-scale-codec 1.3.7", + "sp-std 2.0.0", + "sp-storage 2.0.0", +] + +[[package]] +name = "sp-externalities" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "environmental", + "parity-scale-codec 2.2.0", + "sp-std 4.0.0-dev", + "sp-storage 4.0.0-dev", +] + +[[package]] +name = "sp-inherents" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "async-trait", + "impl-trait-for-tuples 0.2.1", + "parity-scale-codec 2.2.0", + "sp-core 4.0.0-dev", + "sp-runtime", + "sp-std 4.0.0-dev", + "thiserror", +] + +[[package]] +name = "sp-io" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "futures", + "hash-db", + "libsecp256k1", + "log", + "parity-scale-codec 2.2.0", + "parking_lot 0.11.2", + "sp-core 4.0.0-dev", + "sp-externalities 0.10.0-dev", + "sp-keystore", + "sp-maybe-compressed-blob", + "sp-runtime-interface 4.0.0-dev", + "sp-state-machine", + "sp-std 4.0.0-dev", + "sp-tracing 4.0.0-dev", + "sp-trie", + "sp-wasm-interface 4.0.0-dev", + "tracing", + "tracing-core", +] + +[[package]] +name = "sp-keystore" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "async-trait", + "derive_more", + "futures", + "merlin", + "parity-scale-codec 2.2.0", + "parking_lot 0.11.2", + "schnorrkel", + "sp-core 4.0.0-dev", + "sp-externalities 0.10.0-dev", +] + +[[package]] +name = "sp-maybe-compressed-blob" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "ruzstd", + "zstd", +] + +[[package]] +name = "sp-panic-handler" +version = "3.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "backtrace", +] + +[[package]] +name = "sp-runtime" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "either", + "hash256-std-hasher", + "impl-trait-for-tuples 0.2.1", + "log", + "parity-scale-codec 2.2.0", + "parity-util-mem", + "paste", + "rand 0.7.3", + "serde", + "sp-application-crypto", + "sp-arithmetic", + "sp-core 4.0.0-dev", + "sp-io", + "sp-std 4.0.0-dev", +] + +[[package]] +name = "sp-runtime-interface" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "parity-scale-codec 1.3.7", + "primitive-types 0.7.3", + "sp-externalities 0.8.0", + "sp-runtime-interface-proc-macro 2.0.0", + "sp-std 2.0.0", + "sp-storage 2.0.0", + "sp-tracing 2.0.0", + "sp-wasm-interface 2.0.0", + "static_assertions", +] + +[[package]] +name = "sp-runtime-interface" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "impl-trait-for-tuples 0.2.1", + "parity-scale-codec 2.2.0", + "primitive-types 0.10.1", + "sp-externalities 0.10.0-dev", + "sp-runtime-interface-proc-macro 4.0.0-dev", + "sp-std 4.0.0-dev", + "sp-storage 4.0.0-dev", + "sp-tracing 4.0.0-dev", + "sp-wasm-interface 4.0.0-dev", + "static_assertions", +] + +[[package]] +name = "sp-runtime-interface-proc-macro" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "Inflector", + "proc-macro-crate 0.1.5", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-runtime-interface-proc-macro" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "Inflector", + "proc-macro-crate 1.0.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-staking" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "parity-scale-codec 2.2.0", + "sp-runtime", + "sp-std 4.0.0-dev", +] + +[[package]] +name = "sp-state-machine" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "hash-db", + "log", + "num-traits", + "parity-scale-codec 2.2.0", + "parking_lot 0.11.2", + "rand 0.7.3", + "smallvec", + "sp-core 4.0.0-dev", + "sp-externalities 0.10.0-dev", + "sp-panic-handler", + "sp-std 4.0.0-dev", + "sp-trie", + "thiserror", + "tracing", + "trie-db", + "trie-root", +] + +[[package]] +name = "sp-std" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" + +[[package]] +name = "sp-std" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" + +[[package]] +name = "sp-storage" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "impl-serde", + "parity-scale-codec 1.3.7", + "ref-cast", + "serde", + "sp-debug-derive 2.0.0", + "sp-std 2.0.0", +] + +[[package]] +name = "sp-storage" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "impl-serde", + "parity-scale-codec 2.2.0", + "ref-cast", + "serde", + "sp-debug-derive 3.0.0", + "sp-std 4.0.0-dev", +] + +[[package]] +name = "sp-tracing" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "log", + "parity-scale-codec 1.3.7", + "sp-std 2.0.0", + "tracing", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "sp-tracing" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "erased-serde", + "log", + "parity-scale-codec 2.2.0", + "parking_lot 0.10.2", + "serde", + "serde_json", + "slog", + "sp-std 4.0.0-dev", + "tracing", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "sp-trie" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "hash-db", + "memory-db", + "parity-scale-codec 2.2.0", + "sp-core 4.0.0-dev", + "sp-std 4.0.0-dev", + "trie-db", + "trie-root", +] + +[[package]] +name = "sp-version" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "impl-serde", + "parity-scale-codec 2.2.0", + "parity-wasm 0.42.2", + "serde", + "sp-runtime", + "sp-std 4.0.0-dev", + "sp-version-proc-macro", + "thiserror", +] + +[[package]] +name = "sp-version-proc-macro" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "parity-scale-codec 2.2.0", + "proc-macro-crate 1.0.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-wasm-interface" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" +dependencies = [ + "impl-trait-for-tuples 0.1.3", + "parity-scale-codec 1.3.7", + "sp-std 2.0.0", + "wasmi 0.6.2", +] + +[[package]] +name = "sp-wasm-interface" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" +dependencies = [ + "impl-trait-for-tuples 0.2.1", + "parity-scale-codec 2.2.0", + "sp-std 4.0.0-dev", + "wasmi 0.9.0", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "sqlformat" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "684001e7985ec1a9a66963b77ed151ef22a7876b3fdd7e37a57ec774f54b7d96" +dependencies = [ + "lazy_static", + "maplit", + "nom 7.0.0", + "regex", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4b94ab0f8c21ee4899b93b06451ef5d965f1a355982ee73684338228498440" +dependencies = [ + "sqlx-core", + "sqlx-macros", +] + +[[package]] +name = "sqlx-core" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec28b91a01e1fe286d6ba66f68289a2286df023fc97444e1fd86c2fd6d5dc026" +dependencies = [ + "ahash", + "atoi", + "base64", + "bitflags", + "byteorder", + "bytes", + "crc", + "crossbeam-channel", + "crossbeam-queue", + "crossbeam-utils", + "dirs", + "either", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-util", + "hashlink", + "hex", + "hmac 0.10.1", + "itoa", + "libc", + "log", + "md-5", + "memchr", + "once_cell", + "parking_lot 0.11.2", + "percent-encoding", + "rand 0.8.4", + "rustls", + "serde", + "serde_json", + "sha-1", + "sha2 0.9.6", + "smallvec", + "sqlformat", + "sqlx-rt", + "stringprep", + "thiserror", + "url", + "webpki", + "webpki-roots", + "whoami", +] + +[[package]] +name = "sqlx-macros" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dc33c35d54774eed73d54568d47a6ac099aed8af5e1556a017c131be88217d5" +dependencies = [ + "dotenv", + "either", + "futures", + "heck", + "once_cell", + "proc-macro2", + "quote", + "sha2 0.9.6", + "sqlx-core", + "sqlx-rt", + "syn", + "url", +] + +[[package]] +name = "sqlx-rt" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14302b678d9c76b28f2e60115211e25e0aabc938269991745a169753dc00e35c" +dependencies = [ + "async-rustls", + "async-std", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "statrs" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05bdbb8e4e78216a85785a85d3ec3183144f98d0097b9281802c019bb07a6f05" +dependencies = [ + "approx", + "lazy_static", + "nalgebra", + "num-traits", + "rand 0.8.4", +] + +[[package]] +name = "stringprep" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "substrate-bip39" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49eee6965196b32f882dd2ee85a92b1dbead41b04e53907f269de3b0dc04733c" +dependencies = [ + "hmac 0.11.0", + "pbkdf2 0.8.0", + "schnorrkel", + "sha2 0.9.6", + "zeroize", +] + +[[package]] +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "474aaa926faa1603c40b7885a9eaea29b444d1cb2850cb7c0e37bb1a4182f4fa" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "283d5230e63df9608ac7d9691adc1dfb6e701225436eb64d0b9a7f0a5a04f6ec" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa3884228611f5cd3608e2d409bf7dce832e4eb3135e3f11addbd7e41bd68e71" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tiny-bip39" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0165e045cc2ae1660270ca65e1676dbaab60feb0f91b10f7d0665e9b47e31f2" +dependencies = [ + "failure", + "hmac 0.7.1", + "once_cell", + "pbkdf2 0.3.0", + "rand 0.7.3", + "rustc-hash", + "sha2 0.8.2", + "unicode-normalization", +] + +[[package]] +name = "tiny-bip39" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9e44c4759bae7f1032e286a7ef990bd9ed23fe831b7eeba0beb97484c2e59b8" +dependencies = [ + "anyhow", + "hmac 0.8.1", + "once_cell", + "pbkdf2 0.4.0", + "rand 0.7.3", + "rustc-hash", + "sha2 0.9.6", + "thiserror", + "unicode-normalization", + "zeroize", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +dependencies = [ + "cfg-if 1.0.0", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ca517f43f0fb96e0c3072ed5c275fe5eece87e8cb52f4a77b69226d3b1c9df8" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tracing-log" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cbe87a2fa7e35900ce5de20220a582a9483a7063811defce79d7cbd59d4cfe" +dependencies = [ + "ansi_term 0.12.1", + "chrono", + "lazy_static", + "matchers", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "trie-db" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eac131e334e81b6b3be07399482042838adcd7957aa0010231d0813e39e02fa" +dependencies = [ + "hash-db", + "hashbrown", + "log", + "rustc-hex", + "smallvec", +] + +[[package]] +name = "trie-root" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "652931506d2c1244d7217a70b99f56718a7b4161b37f04e7cd868072a99f68cd" +dependencies = [ + "hash-db", +] + +[[package]] +name = "twox-hash" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f559b464de2e2bdabcac6a210d12e9b5a5973c251e102c44c585c71d51bd78e" +dependencies = [ + "cfg-if 1.0.0", + "rand 0.8.4", + "static_assertions", +] + +[[package]] +name = "tx-decoder" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-std", + "async-stream", + "desub-core", + "desub-extras", + "futures", + "log", + "pretty_env_logger", + "serde", + "serde_json", + "sqlx", +] + +[[package]] +name = "typenum" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" + +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + +[[package]] +name = "uint" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9db035e67dfaf7edd9aebfe8676afcd63eed53c8a4044fed514c8cccf1835177" +dependencies = [ + "byteorder", + "crunchy", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "uint" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6470ab50f482bde894a037a57064480a246dbfdd5960bd65a44824693f08da5f" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085" + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", +] + +[[package]] +name = "value-bag" +version = "1.0.0-alpha.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd320e1520f94261153e96f7534476ad869c14022aee1e59af7c778075d840ae" +dependencies = [ + "ctor", + "version_check", +] + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasm-bindgen" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95fded345a6559c2cfee778d562300c581f7d4ff3edb9b0d230d69800d213972" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29" + +[[package]] +name = "wasmi" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf617d864d25af3587aa745529f7aaa541066c876d57e050c0d0c85c61c92aff" +dependencies = [ + "libc", + "memory_units", + "num-rational 0.2.4", + "num-traits", + "parity-wasm 0.41.0", + "wasmi-validation 0.3.0", +] + +[[package]] +name = "wasmi" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ee05bba3d1d994652079893941a2ef9324d2b58a63c31b40678fb7eddd7a5a" +dependencies = [ + "downcast-rs", + "libc", + "memory_units", + "num-rational 0.2.4", + "num-traits", + "parity-wasm 0.42.2", + "wasmi-validation 0.4.0", +] + +[[package]] +name = "wasmi-validation" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea78c597064ba73596099281e2f4cfc019075122a65cdda3205af94f0b264d93" +dependencies = [ + "parity-wasm 0.41.0", +] + +[[package]] +name = "wasmi-validation" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb8e860796d8be48efef530b60eebf84e74a88bce107374fffb0da97d504b8" +dependencies = [ + "parity-wasm 0.42.2", +] + +[[package]] +name = "web-sys" +version = "0.3.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" +dependencies = [ + "webpki", +] + +[[package]] +name = "wepoll-ffi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" +dependencies = [ + "cc", +] + +[[package]] +name = "which" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" +dependencies = [ + "libc", +] + +[[package]] +name = "whoami" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7741161a40200a867c96dfa5574544efa4178cf4c8f770b62dd1cc0362d7ae1" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + +[[package]] +name = "zeroize" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "377db0846015f7ae377174787dd452e1c5f5a9050bc6f954911d01f116daa0cd" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zstd" +version = "0.6.1+zstd.1.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de55e77f798f205d8561b8fe2ef57abfb6e0ff2abe7fd3c089e119cdb5631a3" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "3.0.1+zstd.1.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1387cabcd938127b30ce78c4bf00b30387dddf704e3f0881dbc4ff62b5566f8c" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "1.4.20+zstd.1.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd5b733d7cf2d9447e2c3e76a5589b4f5e5ae065c22a2bc0b023cbc331b6c8e" +dependencies = [ + "cc", + "libc", +] diff --git a/bin/tx-decoder/Cargo.toml b/bin/tx-decoder/Cargo.toml new file mode 100644 index 00000000..5892e132 --- /dev/null +++ b/bin/tx-decoder/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "tx-decoder" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +async-std = { version = "1.10.0", features = [ "attributes" ] } +async-stream = "0.3.2" +sqlx = { version = "0.5", features = [ "runtime-async-std-rustls", "postgres" ]} +desub = { path = "../../core/", package = "desub-core" } +desub-extras = { path = "../../extras", features = [ "polkadot" ]} +anyhow = "1.0.43" +futures = "0.3.17" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0.67" +log = "0.4.14" +pretty_env_logger = "0.4.0" diff --git a/bin/tx-decoder/README.md b/bin/tx-decoder/README.md new file mode 100644 index 00000000..f994e7bc --- /dev/null +++ b/bin/tx-decoder/README.md @@ -0,0 +1,12 @@ +# Tx Decoder +### Tool that decodes transactions in a given SQL database + + +The goal of TxDecoder is to be a handy CLI tool for decoding extrinsics/storage that exist in an archive SQL database. +- Decode all extrinsics of a certain spec (one or multiple or every), and return all those that were not succesful +- Decode a specific extrinsic based on block_num & optional extrinsic index (no index will decode all ext). +- Decode storage entries of a specific prefix of all blocks in a specific spec version/time period/etc +- Decode specific storage entry of a specific block +- Decode all storage entries of a specific block + + diff --git a/bin/tx-decoder/src/main.rs b/bin/tx-decoder/src/main.rs new file mode 100644 index 00000000..b77cea0a --- /dev/null +++ b/bin/tx-decoder/src/main.rs @@ -0,0 +1,65 @@ +// Copyright 2021 Parity Technologies (UK) Ltd. +// This file is part of substrate-desub. +// +// substrate-desub is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// substrate-desub is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with substrate-desub. If not, see . + +mod queries; + +use queries::*; + +use desub::decoder::{Decoder, Chain}; + +use sqlx::postgres::PgPoolOptions; +use futures::StreamExt; +use anyhow::Error; +use std::convert::TryInto; + +const SPEC: i32 = 1030; + +#[async_std::main] +async fn main() -> Result<(), Error> { + pretty_env_logger::init(); + + let pool = PgPoolOptions::new() + .connect("postgres://postgres:123@localhost:6432/kusama-db") + .await?; + + let mut conn = pool.acquire().await?; + + let types = desub_extras::TypeResolver::default(); + let mut decoder = Decoder::new(types, Chain::Kusama); + let metadata = metadata(&mut conn, SPEC).await?; + decoder.register_version(SPEC.try_into()?, metadata); + + let mut blocks = blocks(&mut conn, SPEC); + let mut len = 0; + let mut error_count = 0; + let now = std::time::Instant::now(); + while let Some(Ok(block)) = blocks.next().await { + match decoder.decode_extrinsic(SPEC.try_into()?, block.ext.as_slice()) { + Err(e) => { + error_count += 1; + len += 1; + log::error!("Failed to decode block {} due to {}", block.block_num, e); + }, + Ok(_) => { + len += 1; + } + } + } + + println!("Took {:?} to decode {} blocks with {} errors.", now.elapsed(), len, error_count); + + Ok(()) +} diff --git a/bin/tx-decoder/src/queries.rs b/bin/tx-decoder/src/queries.rs new file mode 100644 index 00000000..250bff11 --- /dev/null +++ b/bin/tx-decoder/src/queries.rs @@ -0,0 +1,55 @@ +// Copyright 2021 Parity Technologies (UK) Ltd. +// This file is part of substrate-desub. +// +// substrate-desub is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// substrate-desub is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with substrate-desub. If not, see . + +use sqlx::{PgConnection, FromRow}; +use futures::{Stream, TryStreamExt}; +use anyhow::Error; +use serde::{Serialize, Deserialize}; + +/// Struct modeling data returned from database when querying for a block +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, FromRow)] +pub struct BlockModel { + pub id: i32, + pub parent_hash: Vec, + pub hash: Vec, + pub block_num: i32, + pub state_root: Vec, + pub extrinsics_root: Vec, + pub digest: Vec, + pub ext: Vec, + pub spec: i32, +} +// just returns all blocks in the database of a specific spec as a stream +pub fn blocks<'a>(conn: &'a mut PgConnection, spec: i32) -> impl Stream> + 'a { + sqlx::query_as!(BlockModel, "SELECT * FROM blocks WHERE spec = $1", spec) + .fetch(conn) + .map_err(Into::into) +} + +#[derive(FromRow)] +struct Meta { + pub meta: Vec +} + +pub async fn metadata(conn: &mut PgConnection, spec: i32) -> Result, Error> { + sqlx::query_as!(Meta, "SELECT meta FROM metadata WHERE version = $1", spec) + .fetch_one(conn) + .await + .map_err(Into::into) + .map(|m| m.meta) +} + + diff --git a/core/src/lib.rs b/core/src/lib.rs index 45526991..a28369b8 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. +// Copyright 2019-2021 Parity Technologies (UK) Ltd. // This file is part of substrate-desub. // // substrate-desub is free software: you can redistribute it and/or modify diff --git a/integration_tests/tests/storage.rs b/integration_tests/tests/storage.rs index ad077146..b9183b9f 100644 --- a/integration_tests/tests/storage.rs +++ b/integration_tests/tests/storage.rs @@ -4,17 +4,9 @@ use desub_core::{ decoder::{Chain, Decoder, Metadata}, SubstrateType, }; -use frame_system::AccountInfo; -use pallet_balances::AccountData; use primitives::twox_128; use anyhow::Result; -fn mock_account_info() -> AccountInfo> { - let mock_account_data: AccountData = - AccountData { free: 100, reserved: 200, misc_frozen: 300, fee_frozen: 400 }; - let mock_account_info: AccountInfo> = AccountInfo::default(); - mock_account_info -} /// T::BlockNumber in meta V11 Block 1768321 fn get_plain_value() -> (Vec, Option>) { @@ -58,6 +50,26 @@ fn should_decode_map() -> Result<()> { Ok(()) } +#[test] +fn should_decode_map_ksm_3944195() -> Result<()> { + let _ = pretty_env_logger::try_init(); + + let types = extras::TypeResolver::default(); + let mut decoder = Decoder::new(types, Chain::Kusama); + + let meta = test_suite::runtime_v11(); + let meta = Metadata::new(meta.as_slice()); + decoder.register_version(2023, &meta); + // BlockHash from block 3944196 + let storage_key = hex::decode("26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c1187465eb805861b659fd1022f3c00").unwrap(); + let encoded_hash = hex::decode("38f14d3d028e2f5b9ce889a444b49e774b88bcb3fe205fa4f5a10c2e66290c59").unwrap(); + + let res = decoder.decode_storage(2023, (storage_key, Some(encoded_hash)))?; + println!("{:?}", res); + Ok(()) +} + + #[test] fn should_decode_double_map() { let _ = pretty_env_logger::try_init(); diff --git a/integration_tests/tests/storage_extended_tests.rs b/integration_tests/tests/storage_extended_tests.rs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/integration_tests/tests/storage_extended_tests.rs @@ -0,0 +1 @@ + diff --git a/integration_tests/tests/test_suite.rs b/integration_tests/tests/test_suite.rs index 57398941..afb5685c 100644 --- a/integration_tests/tests/test_suite.rs +++ b/integration_tests/tests/test_suite.rs @@ -1,9 +1,13 @@ +mod runtime_metadata; + const EXT_PATH: &'static str = "./data/extrinsics/"; use desub_core::decoder::Chain; use std::{fs::File, io::prelude::*}; use paste::paste; +pub use runtime_metadata::*; + // NOTE: it is only usable in the current file. macro_rules! decl_extrinsic_test { ( @@ -81,75 +85,3 @@ decl_extrinsic_test! { ["1", Chain::Westend, "1191"] } -/// Get the runtime metadata from KusamaCC3 from block 3,901,874 -/// Block hash 0x1d65a4c67817c4f32f99f7247f070a2f3fd58baf81d4e533c9be9d1aa8c4e65a -/// -/// # Panics -/// Panics on std::io::Error -pub fn runtime_v11() -> Vec { - let mut f = File::open("./data/metadata_v11.bin").expect("Opening file failed"); - let mut buffer = Vec::new(); - f.read_to_end(&mut buffer).expect("Reading file failed"); - buffer -} - -/// Get the runtime metadata from KusamaCC3 around block 361,0000 -/// Block hash -/// 0x627a6a8e7698dd360bd44e7816e7f8c5321fa31e0a3f39324d93ec5716a57fb5 -/// -/// # Panics -/// Panics on std::io::Error -pub fn runtime_v9() -> Vec { - let mut f = File::open("./data/metadata_v9.bin").expect("Opening file failed"); - let mut buffer = Vec::new(); - f.read_to_end(&mut buffer).expect("Reading file failed"); - buffer -} - -/// Get the runtime metadata from KusamaCC3 around block 361,0000 -/// Block 500,000 -/// Block hash 0x166f5cc1a51a702b79171455c0f3aa3cc6ba010075c1aaa86e1b9e8067510806 -/// -// -/// # Panics -/// Panics on std::io::Error -pub fn runtime_v9_block500k() -> Vec { - let mut f = File::open("./data/metadata_v9_block500000.bin").expect("Opening file failed"); - let mut buffer = Vec::new(); - f.read_to_end(&mut buffer).expect("Reading file failed"); - buffer -} - -/// Get some runtime metadata from KusamaCC3 at block 6 -/// Block hash -/// 0xb5ee550d20a55b76adeba7149516d367ac7cbdd95cd0864a8753d6b5dd02d3bb -/// -/// # Panics -/// Panics on std::io::Error -pub fn runtime_v9_block6() -> Vec { - let mut f = File::open("./data/metadata_v9_block6.bin").expect("Opening file failed"); - let mut buffer = Vec::new(); - f.read_to_end(&mut buffer).expect("Reading file failed"); - buffer -} - -/// Get the runtime metadata from KusamaCC3 for metadata version 10 -/// Block hash -/// 0x627a6a8e7698dd360bd44e7816e7f8c5321fa31e0a3f39324d93ec5716a57fb5 -/// -/// # Panics -/// Panics on std::io::Error -pub fn runtime_v10() -> Vec { - let mut f = File::open("./data/metadata_v10.bin").expect("Opening file failed"); - let mut buffer = Vec::new(); - f.read_to_end(&mut buffer).expect("Reading file failed"); - buffer -} - -pub fn runtime_v12_block_4643974() -> Vec { - let mut f = File::open("./data/metadata_v12_block4643974.bin").expect("Opening file failed"); - let mut buffer = Vec::new(); - f.read_to_end(&mut buffer).expect("Reading file failed"); - buffer -} - diff --git a/integration_tests/tests/test_suite/runtime_metadata.rs b/integration_tests/tests/test_suite/runtime_metadata.rs new file mode 100644 index 00000000..5d3d957a --- /dev/null +++ b/integration_tests/tests/test_suite/runtime_metadata.rs @@ -0,0 +1,74 @@ +use std::{fs::File, io::prelude::*}; + +/// Get the runtime metadata from KusamaCC3 from block 3,901,874 +/// Block hash 0x1d65a4c67817c4f32f99f7247f070a2f3fd58baf81d4e533c9be9d1aa8c4e65a +/// +/// # Panics +/// Panics on std::io::Error +pub fn runtime_v11() -> Vec { + let mut f = File::open("./data/metadata_v11.bin").expect("Opening file failed"); + let mut buffer = Vec::new(); + f.read_to_end(&mut buffer).expect("Reading file failed"); + buffer +} + +/// Get the runtime metadata from KusamaCC3 around block 361,0000 +/// Block hash +/// 0x627a6a8e7698dd360bd44e7816e7f8c5321fa31e0a3f39324d93ec5716a57fb5 +/// +/// # Panics +/// Panics on std::io::Error +pub fn runtime_v9() -> Vec { + let mut f = File::open("./data/metadata_v9.bin").expect("Opening file failed"); + let mut buffer = Vec::new(); + f.read_to_end(&mut buffer).expect("Reading file failed"); + buffer +} + +/// Get the runtime metadata from KusamaCC3 around block 361,0000 +/// Block 500,000 +/// Block hash 0x166f5cc1a51a702b79171455c0f3aa3cc6ba010075c1aaa86e1b9e8067510806 +/// +// +/// # Panics +/// Panics on std::io::Error +pub fn runtime_v9_block500k() -> Vec { + let mut f = File::open("./data/metadata_v9_block500000.bin").expect("Opening file failed"); + let mut buffer = Vec::new(); + f.read_to_end(&mut buffer).expect("Reading file failed"); + buffer +} + +/// Get some runtime metadata from KusamaCC3 at block 6 +/// Block hash +/// 0xb5ee550d20a55b76adeba7149516d367ac7cbdd95cd0864a8753d6b5dd02d3bb +/// +/// # Panics +/// Panics on std::io::Error +pub fn runtime_v9_block6() -> Vec { + let mut f = File::open("./data/metadata_v9_block6.bin").expect("Opening file failed"); + let mut buffer = Vec::new(); + f.read_to_end(&mut buffer).expect("Reading file failed"); + buffer +} + +/// Get the runtime metadata from KusamaCC3 for metadata version 10 +/// Block hash +/// 0x627a6a8e7698dd360bd44e7816e7f8c5321fa31e0a3f39324d93ec5716a57fb5 +/// +/// # Panics +/// Panics on std::io::Error +pub fn runtime_v10() -> Vec { + let mut f = File::open("./data/metadata_v10.bin").expect("Opening file failed"); + let mut buffer = Vec::new(); + f.read_to_end(&mut buffer).expect("Reading file failed"); + buffer +} + +pub fn runtime_v12_block_4643974() -> Vec { + let mut f = File::open("./data/metadata_v12_block4643974.bin").expect("Opening file failed"); + let mut buffer = Vec::new(); + f.read_to_end(&mut buffer).expect("Reading file failed"); + buffer +} + From 50f0108752070ea1e452138e6f5a5b9e9c338f75 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Mon, 11 Oct 2021 14:10:35 +0200 Subject: [PATCH 13/13] Desub refactor (#42) * make tx-decoder actual cli app * huge refactoring to consolidate cursor and data states * formatting * clippy * progress, missing an increment somewhere causing signatures to fail decoding * some parts of incrementing the cursor is made clearer by DecodeState * make Extrinsic bytes into an iterator, fix more extrinsics in 1020 * fix bug in Vec decoding * all of 1020 decodes * fix all tests * Decode up to 1050 * fix spec 1062 * 2008 decodes * fix definition for ConsensusEngineId * some upgrades to tx decoder * rework tx-decoder to use previous spec version when blocks transition from runtimes, the spec will be `next` but the block extrinsics still use previous spec version * mutex -> rwlock * fix sanitization, v12 metadata conversion - use index in metadata rather than enumerater() iterator - fix type name sanitization to support > and > * Add tx_decoder to logs * fix runtimes, number => version * do_decode decides on decode_length independently * remove do_decode in favor of decode do_decode is no longer needed since we can inspect the decode length independently. * fix v12, add v13 metadata * Add bitvec type to `SubstrateTypes` * update v11 to scale-codec 2 * update v9 to scale-codec 2 * update v8 to scale-codec 2 * use one DecodeDifferent from frame-metadata * remove dependency on legacy sp-core * update codec to 2 for extras * Add bitvec type remove not-used version7 metadata * Update core/src/decoder.rs * Update core/src/decoder.rs * some cleanup * Update core/src/decoder.rs * log::error -> println * check for upgrade block 0 * check some * fix santiziation of types with empty generic, <()> * remove all extrinsic integration tests * fix remaining integration tests * fix tests/clippy lints * remove solved todos * add back unused * add test for ChunkedExtrinsic * remove println from test * remove unused RustTypeMarker variant 'String' * remove 'impossible' types * remove more impossible types * fix tests * fix comment * add westend, centrifuge and rococo to FromStr impl * FromStr should allow for custom chains * add docs about upgrade blocks * docs * Update README.md fix release docs * Update README.md * Update bin/tx-decoder/src/queries.rs Co-authored-by: Tarik Gul <47201679+TarikGul@users.noreply.github.com> * Update bin/tx-decoder/src/queries.rs Co-authored-by: Tarik Gul <47201679+TarikGul@users.noreply.github.com> * Update bin/tx-decoder/src/queries.rs Co-authored-by: Tarik Gul <47201679+TarikGul@users.noreply.github.com> * rustfmt * minus v14 for now * add StorageKey definition * add readme comment about StorageKey * choose simplest representations for substrate_types * rusfmt Co-authored-by: Tarik Gul <47201679+TarikGul@users.noreply.github.com> --- Cargo.lock | 1219 +++-------- Cargo.toml | 1 - README.md | 14 +- bin/tx-decoder/Cargo.lock | 941 ++++----- bin/tx-decoder/Cargo.toml | 8 +- bin/tx-decoder/src/app.rs | 259 +++ bin/tx-decoder/src/main.rs | 70 +- bin/tx-decoder/src/queries.rs | 119 +- core/Cargo.toml | 7 +- core/src/decoder.rs | 831 ++++---- core/src/decoder/metadata.rs | 65 +- core/src/decoder/metadata/test_suite.rs | 12 +- core/src/decoder/metadata/version_07.rs | 264 --- core/src/decoder/metadata/version_08.rs | 25 +- core/src/decoder/metadata/version_09.rs | 25 +- core/src/decoder/metadata/version_10.rs | 25 +- core/src/decoder/metadata/version_11.rs | 8 +- core/src/decoder/metadata/version_12.rs | 52 +- core/src/decoder/metadata/version_13.rs | 237 +++ core/src/decoder/metadata/versions.rs | 15 - core/src/decoder/storage.rs | 2 +- core/src/error.rs | 2 + core/src/lib.rs | 28 +- core/src/regex.rs | 116 +- core/src/substrate_types.rs | 17 +- core/src/substrate_types/data.rs | 13 +- core/src/substrate_types/remote.rs | 1 - extras/Cargo.toml | 4 +- extras/README.md | 1 + extras/src/definitions/definitions.json | 5 +- extras/src/definitions/extrinsics.json | 142 +- extras/src/lib.rs | 5 +- extras/src/modules.rs | 76 +- extras/src/overrides.rs | 2 +- extras/src/resolver.rs | 41 +- extras/src/runtimes.rs | 150 ++ ...XTRINSIC_spec_1020_block_10994_index_0.bin | Bin 12 -> 0 bytes ...XTRINSIC_spec_1020_block_10994_index_1.bin | Bin 7 -> 0 bytes ...XTRINSIC_spec_1020_block_10994_index_2.bin | Bin 6 -> 0 bytes ...EXTRINSIC_spec_1020_block_6144_index_0.bin | Bin 12 -> 0 bytes ...EXTRINSIC_spec_1020_block_6144_index_1.bin | Bin 7 -> 0 bytes ...EXTRINSIC_spec_1020_block_6144_index_2.bin | Bin 6 -> 0 bytes .../spec_1020_block_6144_METADATA.bin | Bin 61379 -> 0 bytes ...TRINSIC_spec_1030_block_233816_index_0.bin | Bin 12 -> 0 bytes ...TRINSIC_spec_1030_block_233816_index_1.bin | Bin 9 -> 0 bytes ...TRINSIC_spec_1030_block_233816_index_2.bin | Bin 6 -> 0 bytes ...TRINSIC_spec_1030_block_233816_index_3.bin | Bin 140 -> 0 bytes .../spec_1030_block_233816_METADATA.bin | Bin 69792 -> 0 bytes ...TRINSIC_spec_1031_block_342962_index_0.bin | Bin 12 -> 0 bytes ...TRINSIC_spec_1031_block_342962_index_1.bin | Bin 6 -> 0 bytes .../spec_1031_block_342962_METADATA.bin | Bin 72894 -> 0 bytes ...TRINSIC_spec_1031_block_422871_index_0.bin | Bin 12 -> 0 bytes ...TRINSIC_spec_1031_block_422871_index_1.bin | Bin 9 -> 0 bytes ...TRINSIC_spec_1031_block_422871_index_2.bin | Bin 6 -> 0 bytes .../spec_1031_block_422871_METADATA.bin | Bin 72894 -> 0 bytes ...XTRINSIC_spec_1031_block_50970_index_0.bin | Bin 12 -> 0 bytes ...XTRINSIC_spec_1031_block_50970_index_1.bin | Bin 9 -> 0 bytes ...XTRINSIC_spec_1031_block_50970_index_2.bin | Bin 6 -> 0 bytes ...XTRINSIC_spec_1031_block_50970_index_3.bin | Bin 120 -> 0 bytes .../spec_1031_block_50970_METADATA.bin | Bin 63386 -> 0 bytes ...TRINSIC_spec_1039_block_607421_index_0.bin | Bin 12 -> 0 bytes ...TRINSIC_spec_1039_block_607421_index_1.bin | Bin 9 -> 0 bytes ...TRINSIC_spec_1039_block_607421_index_2.bin | Bin 6 -> 0 bytes ...TRINSIC_spec_1039_block_607421_index_3.bin | Bin 175 -> 0 bytes .../spec_1039_block_607421_METADATA.bin | Bin 85207 -> 0 bytes ...TRINSIC_spec_1042_block_106284_index_0.bin | Bin 12 -> 0 bytes ...TRINSIC_spec_1042_block_106284_index_1.bin | Bin 9 -> 0 bytes ...TRINSIC_spec_1042_block_106284_index_2.bin | Bin 6 -> 0 bytes ...TRINSIC_spec_1042_block_106284_index_3.bin | Bin 149 -> 0 bytes .../spec_1042_block_106284_METADATA.bin | Bin 62709 -> 0 bytes ...TRINSIC_spec_1042_block_779410_index_0.bin | Bin 12 -> 0 bytes ...TRINSIC_spec_1042_block_779410_index_1.bin | Bin 9 -> 0 bytes ...TRINSIC_spec_1042_block_779410_index_2.bin | Bin 6 -> 0 bytes ...TRINSIC_spec_1042_block_779410_index_3.bin | Bin 184 -> 0 bytes .../spec_1042_block_779410_METADATA.bin | Bin 109345 -> 0 bytes ...TRINSIC_spec_1042_block_899638_index_0.bin | Bin 12 -> 0 bytes ...TRINSIC_spec_1042_block_899638_index_1.bin | Bin 9 -> 0 bytes ...TRINSIC_spec_1042_block_899638_index_2.bin | Bin 6 -> 0 bytes ...TRINSIC_spec_1042_block_899638_index_3.bin | Bin 151 -> 0 bytes .../spec_1042_block_899638_METADATA.bin | Bin 109345 -> 0 bytes ...RINSIC_spec_1055_block_1674683_index_0.bin | Bin 12 -> 0 bytes ...RINSIC_spec_1055_block_1674683_index_1.bin | Bin 9 -> 0 bytes ...RINSIC_spec_1055_block_1674683_index_2.bin | Bin 6 -> 0 bytes .../spec_1055_block_1674683_METADATA.bin | Bin 137436 -> 0 bytes ...RINSIC_spec_1055_block_1677621_index_0.bin | Bin 12 -> 0 bytes ...RINSIC_spec_1055_block_1677621_index_1.bin | Bin 9 -> 0 bytes ...RINSIC_spec_1055_block_1677621_index_2.bin | Bin 6 -> 0 bytes ...RINSIC_spec_1055_block_1677621_index_3.bin | Bin 301 -> 0 bytes .../spec_1055_block_1677621_METADATA.bin | Bin 137436 -> 0 bytes ...RINSIC_spec_1055_block_1702023_index_0.bin | Bin 12 -> 0 bytes ...RINSIC_spec_1055_block_1702023_index_1.bin | Bin 6 -> 0 bytes ...INSIC_spec_1055_block_1702023_index_10.bin | Bin 179 -> 0 bytes ...INSIC_spec_1055_block_1702023_index_11.bin | Bin 232 -> 0 bytes ...INSIC_spec_1055_block_1702023_index_12.bin | Bin 203 -> 0 bytes ...INSIC_spec_1055_block_1702023_index_13.bin | Bin 150 -> 0 bytes ...INSIC_spec_1055_block_1702023_index_14.bin | Bin 150 -> 0 bytes ...INSIC_spec_1055_block_1702023_index_15.bin | Bin 202 -> 0 bytes ...INSIC_spec_1055_block_1702023_index_16.bin | Bin 148 -> 0 bytes ...RINSIC_spec_1055_block_1702023_index_2.bin | Bin 258 -> 0 bytes ...RINSIC_spec_1055_block_1702023_index_3.bin | Bin 149 -> 0 bytes ...RINSIC_spec_1055_block_1702023_index_4.bin | Bin 148 -> 0 bytes ...RINSIC_spec_1055_block_1702023_index_5.bin | Bin 177 -> 0 bytes ...RINSIC_spec_1055_block_1702023_index_6.bin | Bin 149 -> 0 bytes ...RINSIC_spec_1055_block_1702023_index_7.bin | Bin 201 -> 0 bytes ...RINSIC_spec_1055_block_1702023_index_8.bin | Bin 241 -> 0 bytes ...RINSIC_spec_1055_block_1702023_index_9.bin | Bin 151 -> 0 bytes .../spec_1055_block_1702023_METADATA.bin | Bin 137436 -> 0 bytes ...RINSIC_spec_1055_block_1714495_index_0.bin | Bin 12 -> 0 bytes ...RINSIC_spec_1055_block_1714495_index_1.bin | Bin 9 -> 0 bytes ...RINSIC_spec_1055_block_1714495_index_2.bin | Bin 6 -> 0 bytes ...RINSIC_spec_1055_block_1714495_index_3.bin | Bin 146 -> 0 bytes .../spec_1055_block_1714495_METADATA.bin | Bin 137436 -> 0 bytes ...RINSIC_spec_1055_block_1717926_index_0.bin | Bin 12 -> 0 bytes ...RINSIC_spec_1055_block_1717926_index_1.bin | Bin 9 -> 0 bytes ...RINSIC_spec_1055_block_1717926_index_2.bin | Bin 6 -> 0 bytes ...RINSIC_spec_1055_block_1717926_index_3.bin | Bin 145 -> 0 bytes .../spec_1055_block_1717926_METADATA.bin | Bin 137436 -> 0 bytes ...RINSIC_spec_1055_block_1718223_index_0.bin | Bin 12 -> 0 bytes ...RINSIC_spec_1055_block_1718223_index_1.bin | Bin 6 -> 0 bytes ...RINSIC_spec_1055_block_1718223_index_2.bin | Bin 1721 -> 0 bytes ...RINSIC_spec_1055_block_1718223_index_3.bin | Bin 107 -> 0 bytes .../spec_1055_block_1718223_METADATA.bin | Bin 137436 -> 0 bytes ...RINSIC_spec_1055_block_1731904_index_0.bin | Bin 12 -> 0 bytes ...RINSIC_spec_1055_block_1731904_index_1.bin | Bin 9 -> 0 bytes ...RINSIC_spec_1055_block_1731904_index_2.bin | Bin 6 -> 0 bytes ...RINSIC_spec_1055_block_1731904_index_3.bin | Bin 148 -> 0 bytes .../spec_1055_block_1731904_METADATA.bin | Bin 137436 -> 0 bytes ...RINSIC_spec_1055_block_1732321_index_0.bin | Bin 12 -> 0 bytes ...RINSIC_spec_1055_block_1732321_index_1.bin | Bin 9 -> 0 bytes ...RINSIC_spec_1055_block_1732321_index_2.bin | Bin 6 -> 0 bytes ...RINSIC_spec_1055_block_1732321_index_3.bin | Bin 148 -> 0 bytes .../spec_1055_block_1732321_METADATA.bin | Bin 137436 -> 0 bytes ...RINSIC_spec_1055_block_1768321_index_0.bin | Bin 12 -> 0 bytes ...RINSIC_spec_1055_block_1768321_index_1.bin | Bin 9 -> 0 bytes ...RINSIC_spec_1055_block_1768321_index_2.bin | Bin 6 -> 0 bytes .../spec_1055_block_1768321_METADATA.bin | Bin 137436 -> 0 bytes .../EXTRINSIC_spec_0_block_892_index_0.bin | Bin 12 -> 0 bytes .../EXTRINSIC_spec_0_block_892_index_1.bin | Bin 7 -> 0 bytes .../EXTRINSIC_spec_0_block_892_index_2.bin | Bin 6 -> 0 bytes .../EXTRINSIC_spec_0_block_892_index_3.bin | Bin 305 -> 0 bytes .../spec_0_block_892_METADATA.bin | Bin 148734 -> 0 bytes .../EXTRINSIC_spec_1_block_1191_index_0.bin | Bin 12 -> 0 bytes .../EXTRINSIC_spec_1_block_1191_index_1.bin | Bin 7 -> 0 bytes .../EXTRINSIC_spec_1_block_1191_index_2.bin | Bin 6 -> 0 bytes .../EXTRINSIC_spec_1_block_1191_index_3.bin | Bin 146 -> 0 bytes .../spec_1_block_1191_METADATA.bin | Bin 80253 -> 0 bytes integration_tests/tests/extrinsics.rs | 417 ---- integration_tests/tests/lib.rs | 3 +- integration_tests/tests/metadata.rs | 14 +- .../{test_suite => }/runtime_metadata.rs | 1 - integration_tests/tests/storage.rs | 18 +- integration_tests/tests/test_suite.rs | 87 - .../metadatav10/Cargo.toml | 5 +- .../metadatav10/src/lib.rs | 127 +- .../metadatav11/Cargo.lock | 1791 ----------------- .../metadatav11/Cargo.toml | 5 +- .../metadatav11/src/lib.rs | 129 +- .../metadatav8/Cargo.toml | 6 +- .../metadatav8/src/lib.rs | 101 +- .../metadatav9/Cargo.toml | 5 +- .../metadatav9/src/lib.rs | 131 +- .../sp_core_versions/README.md | 7 - .../sp_core_versions/core-7314a/Cargo.toml | 126 -- .../core-7314a/src/changes_trie.rs | 306 --- .../sp_core_versions/core-7314a/src/crypto.rs | 1263 ------------ .../sp_core_versions/core-7314a/src/ecdsa.rs | 718 ------- .../core-7314a/src/ed25519.rs | 712 ------- .../sp_core_versions/core-7314a/src/hash.rs | 82 - .../sp_core_versions/core-7314a/src/hasher.rs | 58 - .../core-7314a/src/hashing.rs | 156 -- .../core-7314a/src/hexdisplay.rs | 104 - .../sp_core_versions/core-7314a/src/lib.rs | 390 ---- .../core-7314a/src/offchain/mod.rs | 775 ------- .../core-7314a/src/offchain/storage.rs | 297 --- .../core-7314a/src/offchain/testing.rs | 418 ---- .../core-7314a/src/sandbox.rs | 128 -- .../core-7314a/src/sr25519.rs | 889 -------- .../core-7314a/src/testing.rs | 464 ----- .../sp_core_versions/core-7314a/src/traits.rs | 388 ---- .../core-7314a/src/u32_trait.rs | 244 --- .../sp_core_versions/core-7314a/src/uint.rs | 100 - .../sp_core_versions/core-7314a/src/vrf.rs | 99 - 182 files changed, 2463 insertions(+), 12903 deletions(-) create mode 100644 bin/tx-decoder/src/app.rs delete mode 100644 core/src/decoder/metadata/version_07.rs create mode 100644 core/src/decoder/metadata/version_13.rs delete mode 100644 core/src/decoder/metadata/versions.rs create mode 100644 extras/README.md create mode 100644 extras/src/runtimes.rs delete mode 100644 integration_tests/data/extrinsics/kusama/spec1020_block10994/EXTRINSIC_spec_1020_block_10994_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1020_block10994/EXTRINSIC_spec_1020_block_10994_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1020_block10994/EXTRINSIC_spec_1020_block_10994_index_2.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1020_block6144/EXTRINSIC_spec_1020_block_6144_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1020_block6144/EXTRINSIC_spec_1020_block_6144_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1020_block6144/EXTRINSIC_spec_1020_block_6144_index_2.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1020_block6144/spec_1020_block_6144_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1030_block233816/EXTRINSIC_spec_1030_block_233816_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1030_block233816/EXTRINSIC_spec_1030_block_233816_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1030_block233816/EXTRINSIC_spec_1030_block_233816_index_2.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1030_block233816/EXTRINSIC_spec_1030_block_233816_index_3.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1030_block233816/spec_1030_block_233816_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1031_block342962/EXTRINSIC_spec_1031_block_342962_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1031_block342962/EXTRINSIC_spec_1031_block_342962_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1031_block342962/spec_1031_block_342962_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1031_block422871/EXTRINSIC_spec_1031_block_422871_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1031_block422871/EXTRINSIC_spec_1031_block_422871_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1031_block422871/EXTRINSIC_spec_1031_block_422871_index_2.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1031_block422871/spec_1031_block_422871_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1031_block50970/EXTRINSIC_spec_1031_block_50970_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1031_block50970/EXTRINSIC_spec_1031_block_50970_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1031_block50970/EXTRINSIC_spec_1031_block_50970_index_2.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1031_block50970/EXTRINSIC_spec_1031_block_50970_index_3.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1031_block50970/spec_1031_block_50970_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1039_block607421/EXTRINSIC_spec_1039_block_607421_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1039_block607421/EXTRINSIC_spec_1039_block_607421_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1039_block607421/EXTRINSIC_spec_1039_block_607421_index_2.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1039_block607421/EXTRINSIC_spec_1039_block_607421_index_3.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1039_block607421/spec_1039_block_607421_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1042_block106284/EXTRINSIC_spec_1042_block_106284_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1042_block106284/EXTRINSIC_spec_1042_block_106284_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1042_block106284/EXTRINSIC_spec_1042_block_106284_index_2.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1042_block106284/EXTRINSIC_spec_1042_block_106284_index_3.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1042_block106284/spec_1042_block_106284_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1042_block779410/EXTRINSIC_spec_1042_block_779410_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1042_block779410/EXTRINSIC_spec_1042_block_779410_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1042_block779410/EXTRINSIC_spec_1042_block_779410_index_2.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1042_block779410/EXTRINSIC_spec_1042_block_779410_index_3.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1042_block779410/spec_1042_block_779410_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1042_block899638/EXTRINSIC_spec_1042_block_899638_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1042_block899638/EXTRINSIC_spec_1042_block_899638_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1042_block899638/EXTRINSIC_spec_1042_block_899638_index_2.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1042_block899638/EXTRINSIC_spec_1042_block_899638_index_3.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1042_block899638/spec_1042_block_899638_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1674683/EXTRINSIC_spec_1055_block_1674683_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1674683/EXTRINSIC_spec_1055_block_1674683_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1674683/EXTRINSIC_spec_1055_block_1674683_index_2.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1674683/spec_1055_block_1674683_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1677621/EXTRINSIC_spec_1055_block_1677621_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1677621/EXTRINSIC_spec_1055_block_1677621_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1677621/EXTRINSIC_spec_1055_block_1677621_index_2.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1677621/EXTRINSIC_spec_1055_block_1677621_index_3.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1677621/spec_1055_block_1677621_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_10.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_11.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_12.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_13.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_14.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_15.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_16.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_2.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_3.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_4.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_5.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_6.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_7.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_8.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_9.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1702023/spec_1055_block_1702023_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1714495/EXTRINSIC_spec_1055_block_1714495_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1714495/EXTRINSIC_spec_1055_block_1714495_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1714495/EXTRINSIC_spec_1055_block_1714495_index_2.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1714495/EXTRINSIC_spec_1055_block_1714495_index_3.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1714495/spec_1055_block_1714495_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1717926/EXTRINSIC_spec_1055_block_1717926_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1717926/EXTRINSIC_spec_1055_block_1717926_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1717926/EXTRINSIC_spec_1055_block_1717926_index_2.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1717926/EXTRINSIC_spec_1055_block_1717926_index_3.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1717926/spec_1055_block_1717926_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1718223/EXTRINSIC_spec_1055_block_1718223_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1718223/EXTRINSIC_spec_1055_block_1718223_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1718223/EXTRINSIC_spec_1055_block_1718223_index_2.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1718223/EXTRINSIC_spec_1055_block_1718223_index_3.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1718223/spec_1055_block_1718223_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1731904/EXTRINSIC_spec_1055_block_1731904_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1731904/EXTRINSIC_spec_1055_block_1731904_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1731904/EXTRINSIC_spec_1055_block_1731904_index_2.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1731904/EXTRINSIC_spec_1055_block_1731904_index_3.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1731904/spec_1055_block_1731904_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1732321/EXTRINSIC_spec_1055_block_1732321_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1732321/EXTRINSIC_spec_1055_block_1732321_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1732321/EXTRINSIC_spec_1055_block_1732321_index_2.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1732321/EXTRINSIC_spec_1055_block_1732321_index_3.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1732321/spec_1055_block_1732321_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1768321/EXTRINSIC_spec_1055_block_1768321_index_0.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1768321/EXTRINSIC_spec_1055_block_1768321_index_1.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1768321/EXTRINSIC_spec_1055_block_1768321_index_2.bin delete mode 100644 integration_tests/data/extrinsics/kusama/spec1055_block1768321/spec_1055_block_1768321_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/polkadot/spec0_block892/EXTRINSIC_spec_0_block_892_index_0.bin delete mode 100644 integration_tests/data/extrinsics/polkadot/spec0_block892/EXTRINSIC_spec_0_block_892_index_1.bin delete mode 100644 integration_tests/data/extrinsics/polkadot/spec0_block892/EXTRINSIC_spec_0_block_892_index_2.bin delete mode 100644 integration_tests/data/extrinsics/polkadot/spec0_block892/EXTRINSIC_spec_0_block_892_index_3.bin delete mode 100644 integration_tests/data/extrinsics/polkadot/spec0_block892/spec_0_block_892_METADATA.bin delete mode 100644 integration_tests/data/extrinsics/westend/spec1_block1191/EXTRINSIC_spec_1_block_1191_index_0.bin delete mode 100644 integration_tests/data/extrinsics/westend/spec1_block1191/EXTRINSIC_spec_1_block_1191_index_1.bin delete mode 100644 integration_tests/data/extrinsics/westend/spec1_block1191/EXTRINSIC_spec_1_block_1191_index_2.bin delete mode 100644 integration_tests/data/extrinsics/westend/spec1_block1191/EXTRINSIC_spec_1_block_1191_index_3.bin delete mode 100644 integration_tests/data/extrinsics/westend/spec1_block1191/spec_1_block_1191_METADATA.bin delete mode 100644 integration_tests/tests/extrinsics.rs rename integration_tests/tests/{test_suite => }/runtime_metadata.rs (99%) delete mode 100644 integration_tests/tests/test_suite.rs delete mode 100644 substrate-metadata-versions/metadatav11/Cargo.lock delete mode 100644 substrate-metadata-versions/sp_core_versions/README.md delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/Cargo.toml delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/changes_trie.rs delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/crypto.rs delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/ecdsa.rs delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/ed25519.rs delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/hash.rs delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/hasher.rs delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/hashing.rs delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/hexdisplay.rs delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/lib.rs delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/mod.rs delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/storage.rs delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/testing.rs delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/sandbox.rs delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/sr25519.rs delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/testing.rs delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/traits.rs delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/u32_trait.rs delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/uint.rs delete mode 100644 substrate-metadata-versions/sp_core_versions/core-7314a/src/vrf.rs diff --git a/Cargo.lock b/Cargo.lock index bb5cf2b8..52abe8bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,9 +67,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" +checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1" [[package]] name = "approx" @@ -185,16 +185,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bitvec" -version = "0.17.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" -dependencies = [ - "either", - "radium 0.3.0", -] - [[package]] name = "bitvec" version = "0.20.4" @@ -202,7 +192,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" dependencies = [ "funty", - "radium 0.6.2", + "radium", + "serde", "tap", "wyz", ] @@ -247,35 +238,17 @@ dependencies = [ "byte-tools", ] -[[package]] -name = "bstr" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279" -dependencies = [ - "lazy_static", - "memchr", - "regex-automata", - "serde", -] - [[package]] name = "bumpalo" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" - -[[package]] -name = "byte-slice-cast" -version = "0.3.5" +version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" +checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538" [[package]] name = "byte-slice-cast" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65c1bf4a04a88c54f589125563643d773f3254b5c38571395e2b591c693bbc81" +checksum = "ca0796d76a983651b4a0ddda16203032759f2fd9103d9181f7c65c06ee8872e6" [[package]] name = "byte-tools" @@ -289,20 +262,11 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" -[[package]] -name = "cast" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" -dependencies = [ - "rustc_version 0.4.0", -] - [[package]] name = "cc" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" +checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0" dependencies = [ "jobserver", ] @@ -342,9 +306,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.2.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "853eda514c284c2287f4bf20ae614f8781f40a81d32ecda6e91449304dfe077c" +checksum = "10612c0ec0e0a1ff0e97980647cb058a6e7aedb913d01d009c406b8b7d0b26ee" dependencies = [ "glob", "libc", @@ -389,93 +353,13 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "cpufeatures" -version = "0.1.5" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" dependencies = [ "libc", ] -[[package]] -name = "criterion" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10" -dependencies = [ - "atty", - "cast", - "clap", - "criterion-plot", - "csv", - "itertools", - "lazy_static", - "num-traits", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_cbor", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57" -dependencies = [ - "cast", - "itertools", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils", - "lazy_static", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" -dependencies = [ - "cfg-if 1.0.0", - "lazy_static", -] - [[package]] name = "crunchy" version = "0.2.2" @@ -503,35 +387,13 @@ dependencies = [ ] [[package]] -name = "csv" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" -dependencies = [ - "bstr", - "csv-core", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "csv-core" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" -dependencies = [ - "memchr", -] - -[[package]] -name = "ctor" -version = "0.1.20" +name = "crypto-mac" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e98e2ad1a782e33928b96fc3948e7c355e5af34ba4de7670fe8bac2a3b2006d" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" dependencies = [ - "quote", - "syn", + "generic-array 0.14.4", + "subtle 2.4.1", ] [[package]] @@ -569,7 +431,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version 0.3.3", + "rustc_version", "syn", ] @@ -577,10 +439,11 @@ dependencies = [ name = "desub-core" version = "0.0.1" dependencies = [ + "bitvec", "derive_more", "desub-extras", "dyn-clone", - "frame-metadata 14.0.0-rc.2", + "frame-metadata 14.0.0", "frame-metadatav10", "frame-metadatav11", "frame-metadatav8", @@ -590,12 +453,11 @@ dependencies = [ "log", "onig", "pallet-democracy", - "parity-scale-codec 1.3.7", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "pretty_env_logger", "serde", "serde_json", - "sp-core 4.0.0-dev", + "sp-core", "sp-runtime", "sp-version", "thiserror", @@ -607,18 +469,14 @@ version = "0.0.1" dependencies = [ "desub-core", "log", - "parity-scale-codec 1.3.7", + "parity-scale-codec", + "phf", "serde", "serde_json", + "syn", "thiserror", ] -[[package]] -name = "difference" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" - [[package]] name = "digest" version = "0.8.1" @@ -689,7 +547,7 @@ dependencies = [ "ed25519", "rand 0.7.3", "serde", - "sha2 0.9.5", + "sha2 0.9.8", "zeroize", ] @@ -740,46 +598,12 @@ dependencies = [ "serde", ] -[[package]] -name = "failure" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" -dependencies = [ - "backtrace", - "failure_derive", -] - -[[package]] -name = "failure_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - [[package]] name = "fake-simd" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" -[[package]] -name = "fixed-hash" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11498d382790b7a8f2fd211780bec78619bba81cdad3a283997c0c41f836759c" -dependencies = [ - "byteorder", - "rand 0.7.3", - "rustc-hex", - "static_assertions", -] - [[package]] name = "fixed-hash" version = "0.7.0" @@ -801,14 +625,14 @@ dependencies = [ "frame-system", "linregress", "log", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "paste", "sp-api", "sp-io", "sp-runtime", - "sp-runtime-interface 4.0.0-dev", + "sp-runtime-interface", "sp-std 4.0.0-dev", - "sp-storage 4.0.0-dev", + "sp-storage", ] [[package]] @@ -816,19 +640,20 @@ name = "frame-metadata" version = "14.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ - "parity-scale-codec 2.2.0", + "parity-scale-codec", "serde", - "sp-core 4.0.0-dev", + "sp-core", "sp-std 4.0.0-dev", ] [[package]] name = "frame-metadata" -version = "14.0.0-rc.2" -source = "git+https://github.com/paritytech/frame-metadata#2c6499d9758632b5161f111b4320201640cf2af6" +version = "14.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96616f82e069102b95a72c87de4c84d2f87ef7f0f20630e78ce3824436483110" dependencies = [ "cfg-if 1.0.0", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "scale-info", "serde", ] @@ -837,9 +662,9 @@ dependencies = [ name = "frame-metadatav10" version = "10.0.0" dependencies = [ - "parity-scale-codec 1.3.7", + "frame-metadata 14.0.0", + "parity-scale-codec", "serde", - "sp-core 2.0.0", "sp-std 2.0.0", ] @@ -847,9 +672,9 @@ dependencies = [ name = "frame-metadatav11" version = "11.0.0-rc6" dependencies = [ - "parity-scale-codec 1.3.7", + "frame-metadata 14.0.0", + "parity-scale-codec", "serde", - "sp-core 2.0.0", "sp-std 2.0.0", ] @@ -857,9 +682,9 @@ dependencies = [ name = "frame-metadatav8" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.3.7", + "frame-metadata 14.0.0", + "parity-scale-codec", "serde", - "sp-core 2.0.0", "sp-std 2.0.0", ] @@ -867,9 +692,9 @@ dependencies = [ name = "frame-metadatav9" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.3.7", + "frame-metadata 14.0.0", + "parity-scale-codec", "serde", - "sp-core 2.0.0", "sp-std 2.0.0", ] @@ -881,22 +706,22 @@ dependencies = [ "bitflags", "frame-metadata 14.0.0-dev", "frame-support-procedural", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "log", "once_cell", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "paste", "serde", "smallvec", "sp-arithmetic", - "sp-core 4.0.0-dev", + "sp-core", "sp-inherents", "sp-io", "sp-runtime", "sp-staking", "sp-state-machine", "sp-std 4.0.0-dev", - "sp-tracing 4.0.0-dev", + "sp-tracing", ] [[package]] @@ -917,7 +742,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ "frame-support-procedural-tools-derive", - "proc-macro-crate 1.0.0", + "proc-macro-crate", "proc-macro2", "quote", "syn", @@ -939,11 +764,11 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ "frame-support", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "log", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "serde", - "sp-core 4.0.0-dev", + "sp-core", "sp-io", "sp-runtime", "sp-std 4.0.0-dev", @@ -958,9 +783,9 @@ checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" [[package]] name = "futures" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b" +checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" dependencies = [ "futures-channel", "futures-core", @@ -973,9 +798,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9" +checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" dependencies = [ "futures-core", "futures-sink", @@ -983,15 +808,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" +checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" [[package]] name = "futures-executor" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c" +checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" dependencies = [ "futures-core", "futures-task", @@ -1001,15 +826,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582" +checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" [[package]] name = "futures-macro" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57" +checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" dependencies = [ "autocfg", "proc-macro-hack", @@ -1020,21 +845,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" +checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" [[package]] name = "futures-task" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2" +checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" [[package]] name = "futures-util" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78" +checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" dependencies = [ "autocfg", "futures-channel", @@ -1077,8 +902,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ "cfg-if 1.0.0", + "js-sys", "libc", "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", ] [[package]] @@ -1104,12 +931,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" -[[package]] -name = "half" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" - [[package]] name = "hash-db" version = "0.15.2" @@ -1149,12 +970,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "hex-literal" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e4590e13640f19f249fe3e4eca5113bc4289f2497710378190e7f4bd96f45b" - [[package]] name = "hmac" version = "0.7.1" @@ -1175,6 +990,16 @@ dependencies = [ "digest 0.9.0", ] +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac 0.11.1", + "digest 0.9.0", +] + [[package]] name = "hmac-drbg" version = "0.2.0" @@ -1201,22 +1026,13 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -[[package]] -name = "impl-codec" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" -dependencies = [ - "parity-scale-codec 1.3.7", -] - [[package]] name = "impl-codec" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "161ebdfec3c8e3b52bf61c4f3550a1eea4f9579d10dc1b936f3171ebdcd6c443" dependencies = [ - "parity-scale-codec 2.2.0", + "parity-scale-codec", ] [[package]] @@ -1228,17 +1044,6 @@ dependencies = [ "serde", ] -[[package]] -name = "impl-trait-for-tuples" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "impl-trait-for-tuples" version = "0.2.1" @@ -1262,9 +1067,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +checksum = "716d3d89f35ac6a34fd0eed635395f4c3b76fa889338a4632e5231a8684216bd" dependencies = [ "cfg-if 1.0.0", ] @@ -1289,28 +1094,19 @@ dependencies = [ "hex", "log", "pallet-balances", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "paste", "pretty_env_logger", "serde", "serde_json", - "sp-core 4.0.0-dev", -] - -[[package]] -name = "itertools" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" -dependencies = [ - "either", + "sp-core", ] [[package]] name = "itoa" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "jobserver" @@ -1323,9 +1119,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.53" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d" +checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" dependencies = [ "wasm-bindgen", ] @@ -1350,9 +1146,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.99" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" +checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" [[package]] name = "libloading" @@ -1388,9 +1184,9 @@ dependencies = [ [[package]] name = "linregress" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6e407dadb4ca4b31bc69c27aff00e7ca4534fdcee855159b039a7cebb5f395" +checksum = "d6c601a85f5ecd1aba625247bca0031585fb1c446461b142878a16f8245ddeb8" dependencies = [ "nalgebra", "statrs", @@ -1407,9 +1203,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" +checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" dependencies = [ "scopeguard", ] @@ -1447,15 +1243,6 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" -[[package]] -name = "memoffset" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" -dependencies = [ - "autocfg", -] - [[package]] name = "memory-db" version = "0.27.0" @@ -1615,9 +1402,9 @@ dependencies = [ [[package]] name = "object" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2766204889d09937d00bfbb7fec56bb2a199e2ade963cab19185d8a6104c7c" +checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2" dependencies = [ "memchr", ] @@ -1627,9 +1414,6 @@ name = "once_cell" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" -dependencies = [ - "parking_lot 0.11.1", -] [[package]] name = "onig" @@ -1645,21 +1429,15 @@ dependencies = [ [[package]] name = "onig_sys" -version = "69.7.0" +version = "69.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fd9442a09e4fbd08d196ddf419b2c79a43c3a46c800320cc841d45c2449a240" +checksum = "5dd3eee045c84695b53b20255bb7317063df090b68e18bfac0abb6c39cf7f33e" dependencies = [ "bindgen", "cc", "pkg-config", ] -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - [[package]] name = "opaque-debug" version = "0.2.3" @@ -1672,15 +1450,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" -[[package]] -name = "output_vt100" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9" -dependencies = [ - "winapi", -] - [[package]] name = "pallet-balances" version = "4.0.0-dev" @@ -1690,7 +1459,7 @@ dependencies = [ "frame-support", "frame-system", "log", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "sp-runtime", "sp-std 4.0.0-dev", ] @@ -1703,7 +1472,7 @@ dependencies = [ "frame-benchmarking", "frame-support", "frame-system", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "serde", "sp-io", "sp-runtime", @@ -1712,50 +1481,25 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "1.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b26b16c7687c3075982af47719e481815df30bc544f7a6690763a25ca16e9d" -dependencies = [ - "arrayvec 0.5.2", - "bitvec 0.17.4", - "byte-slice-cast 0.3.5", - "parity-scale-codec-derive 1.2.3", - "serde", -] - -[[package]] -name = "parity-scale-codec" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8975095a2a03bbbdc70a74ab11a4f76a6d0b84680d87c68d722531b0ac28e8a9" +checksum = "373b1a4c1338d9cd3d1fa53b3a11bdab5ab6bd80a20f7f7becd76953ae2be909" dependencies = [ "arrayvec 0.7.1", - "bitvec 0.20.4", - "byte-slice-cast 1.0.0", - "impl-trait-for-tuples 0.2.1", - "parity-scale-codec-derive 2.2.0", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", "serde", ] [[package]] name = "parity-scale-codec-derive" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c41512944b1faff334a5f1b9447611bf4ef40638ccb6328173dacefb338e878c" -dependencies = [ - "proc-macro-crate 0.1.5", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40dbbfef7f0a1143c5b06e0d76a6278e25dac0bc1af4be51a0fbb73f07e7ad09" +checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" dependencies = [ - "proc-macro-crate 1.0.0", + "proc-macro-crate", "proc-macro2", "quote", "syn", @@ -1763,16 +1507,16 @@ dependencies = [ [[package]] name = "parity-util-mem" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ad6f1acec69b95caf435bbd158d486e5a0a44fcf51531e84922c59ff09e8457" +checksum = "6f4cb4e169446179cbc6b8b6320cc9fca49bd2e94e8db25f25f200a8ea774770" dependencies = [ "cfg-if 1.0.0", "hashbrown", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "parity-util-mem-derive", - "parking_lot 0.11.1", - "primitive-types 0.10.1", + "parking_lot 0.11.2", + "primitive-types", "winapi", ] @@ -1787,12 +1531,6 @@ dependencies = [ "synstructure", ] -[[package]] -name = "parity-wasm" -version = "0.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" - [[package]] name = "parity-wasm" version = "0.42.2" @@ -1811,13 +1549,13 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", - "lock_api 0.4.4", - "parking_lot_core 0.8.3", + "lock_api 0.4.5", + "parking_lot_core 0.8.5", ] [[package]] @@ -1836,9 +1574,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ "cfg-if 1.0.0", "instant", @@ -1856,21 +1594,20 @@ checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58" [[package]] name = "pbkdf2" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" +checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" dependencies = [ - "byteorder", - "crypto-mac 0.7.0", + "crypto-mac 0.8.0", ] [[package]] name = "pbkdf2" -version = "0.4.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" +checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa" dependencies = [ - "crypto-mac 0.8.0", + "crypto-mac 0.11.1", ] [[package]] @@ -1889,68 +1626,72 @@ dependencies = [ ] [[package]] -name = "pin-project-lite" -version = "0.2.7" +name = "phf" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" +checksum = "b9fc3db1018c4b59d7d582a739436478b6035138b6aecbce989fc91c3e98409f" +dependencies = [ + "phf_macros", + "phf_shared", + "proc-macro-hack", +] [[package]] -name = "pin-utils" -version = "0.1.0" +name = "phf_generator" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared", + "rand 0.8.4", +] + [[package]] -name = "pkg-config" -version = "0.3.19" +name = "phf_macros" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "plotters" -version = "0.3.1" +name = "phf_shared" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", + "siphasher", ] [[package]] -name = "plotters-backend" -version = "0.3.2" +name = "pin-project-lite" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" [[package]] -name = "plotters-svg" -version = "0.3.1" +name = "pin-utils" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9" -dependencies = [ - "plotters-backend", -] +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "ppv-lite86" -version = "0.2.10" +name = "pkg-config" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb" [[package]] -name = "pretty_assertions" -version = "0.6.1" +name = "ppv-lite86" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" -dependencies = [ - "ansi_term 0.11.0", - "ctor", - "difference", - "output_vt100", -] +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" [[package]] name = "pretty_env_logger" @@ -1962,44 +1703,23 @@ dependencies = [ "log", ] -[[package]] -name = "primitive-types" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd39dcacf71411ba488570da7bbc89b717225e46478b30ba99b92db6b149809" -dependencies = [ - "fixed-hash 0.6.1", - "impl-codec 0.4.2", - "impl-serde", - "uint 0.8.5", -] - [[package]] name = "primitive-types" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" dependencies = [ - "fixed-hash 0.7.0", - "impl-codec 0.5.1", + "fixed-hash", + "impl-codec", "impl-serde", - "uint 0.9.1", -] - -[[package]] -name = "proc-macro-crate" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" -dependencies = [ - "toml", + "uint", ] [[package]] name = "proc-macro-crate" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fdbd1df62156fbc5945f4762632564d7d038153091c3fcf1067f6aef7cff92" +checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" dependencies = [ "thiserror", "toml", @@ -2019,9 +1739,9 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" [[package]] name = "proc-macro2" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" dependencies = [ "unicode-xid", ] @@ -2034,19 +1754,13 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" dependencies = [ "proc-macro2", ] -[[package]] -name = "radium" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" - [[package]] name = "radium" version = "0.6.2" @@ -2119,9 +1833,9 @@ dependencies = [ [[package]] name = "rand_distr" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "051b398806e42b9cd04ad9ec8f81e355d0a382c543ac6672c62f5a5b452ef142" +checksum = "964d548f8e7d12e102ef183a0de7e98180c9f8729f555897a857b96e48122d2f" dependencies = [ "num-traits", "rand 0.8.4", @@ -2160,31 +1874,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" -[[package]] -name = "rayon" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" -dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "lazy_static", - "num_cpus", -] - [[package]] name = "redox_syscall" version = "0.1.57" @@ -2248,9 +1937,9 @@ checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] name = "rustc-demangle" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" [[package]] name = "rustc-hash" @@ -2270,16 +1959,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" dependencies = [ - "semver 0.11.0", -] - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver 1.0.4", + "semver", ] [[package]] @@ -2298,36 +1978,27 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - [[package]] name = "scale-info" -version = "0.10.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e62ff266e136db561a007c84569985805f84a1d5a08278e52c36aacb6e061b" +checksum = "5c55b744399c25532d63a0d2789b109df8d46fc93752d46b0782991a931a782f" dependencies = [ - "bitvec 0.20.4", + "bitvec", "cfg-if 1.0.0", "derive_more", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "scale-info-derive", "serde", ] [[package]] name = "scale-info-derive" -version = "0.7.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b648fa291891a4c80187a25532f6a7d96b82c70353e30b868b14632b8fe043d6" +checksum = "baeb2780690380592f86205aa4ee49815feb2acad8c2f59e6dd207148c3f1fcd" dependencies = [ - "proc-macro-crate 1.0.0", + "proc-macro-crate", "proc-macro2", "quote", "syn", @@ -2357,15 +2028,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "secrecy" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9182278ed645df3477a9c27bfee0621c621aa16f6972635f7f795dae3d81070f" -dependencies = [ - "zeroize", -] - [[package]] name = "secrecy" version = "0.7.0" @@ -2384,12 +2046,6 @@ dependencies = [ "semver-parser", ] -[[package]] -name = "semver" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" - [[package]] name = "semver-parser" version = "0.10.2" @@ -2401,28 +2057,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.127" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" dependencies = [ "serde_derive", ] -[[package]] -name = "serde_cbor" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" -dependencies = [ - "half", - "serde", -] - [[package]] name = "serde_derive" -version = "1.0.127" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" dependencies = [ "proc-macro2", "quote", @@ -2431,9 +2077,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.66" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" dependencies = [ "indexmap", "itoa", @@ -2455,9 +2101,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.5" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" +checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" dependencies = [ "block-buffer 0.9.0", "cfg-if 1.0.0", @@ -2499,6 +2145,12 @@ dependencies = [ "paste", ] +[[package]] +name = "siphasher" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b" + [[package]] name = "slab" version = "0.4.4" @@ -2516,9 +2168,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" +checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" [[package]] name = "sp-api" @@ -2527,9 +2179,9 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#910 dependencies = [ "hash-db", "log", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "sp-api-proc-macro", - "sp-core 4.0.0-dev", + "sp-core", "sp-runtime", "sp-state-machine", "sp-std 4.0.0-dev", @@ -2543,7 +2195,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ "blake2-rfc", - "proc-macro-crate 1.0.0", + "proc-macro-crate", "proc-macro2", "quote", "syn", @@ -2554,9 +2206,9 @@ name = "sp-application-crypto" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ - "parity-scale-codec 2.2.0", + "parity-scale-codec", "serde", - "sp-core 4.0.0-dev", + "sp-core", "sp-io", "sp-std 4.0.0-dev", ] @@ -2568,62 +2220,13 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#910 dependencies = [ "integer-sqrt", "num-traits", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "serde", - "sp-debug-derive 3.0.0", + "sp-debug-derive", "sp-std 4.0.0-dev", "static_assertions", ] -[[package]] -name = "sp-core" -version = "2.0.0" -dependencies = [ - "base58", - "blake2-rfc", - "byteorder", - "criterion", - "derive_more", - "dyn-clonable", - "ed25519-dalek", - "futures", - "hash-db", - "hash256-std-hasher", - "hex", - "hex-literal", - "impl-serde", - "lazy_static", - "libsecp256k1", - "log", - "merlin", - "num-traits", - "parity-scale-codec 1.3.7", - "parity-util-mem", - "parking_lot 0.10.2", - "pretty_assertions", - "primitive-types 0.7.3", - "rand 0.7.3", - "rand_chacha 0.2.2", - "regex", - "schnorrkel", - "secrecy 0.6.0", - "serde", - "serde_json", - "sha2 0.8.2", - "sp-debug-derive 2.0.0", - "sp-externalities 0.8.0", - "sp-runtime-interface 2.0.0", - "sp-serializer", - "sp-std 2.0.0", - "sp-storage 2.0.0", - "substrate-bip39", - "tiny-bip39 0.7.3", - "tiny-keccak", - "twox-hash", - "wasmi 0.6.2", - "zeroize", -] - [[package]] name = "sp-core" version = "4.0.0-dev" @@ -2644,40 +2247,30 @@ dependencies = [ "log", "merlin", "num-traits", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "parity-util-mem", - "parking_lot 0.11.1", - "primitive-types 0.10.1", + "parking_lot 0.11.2", + "primitive-types", "rand 0.7.3", "regex", "schnorrkel", - "secrecy 0.7.0", + "secrecy", "serde", - "sha2 0.9.5", - "sp-debug-derive 3.0.0", - "sp-externalities 0.10.0-dev", - "sp-runtime-interface 4.0.0-dev", + "sha2 0.9.8", + "sp-debug-derive", + "sp-externalities", + "sp-runtime-interface", "sp-std 4.0.0-dev", - "sp-storage 4.0.0-dev", + "sp-storage", "substrate-bip39", "thiserror", - "tiny-bip39 0.8.0", + "tiny-bip39", "tiny-keccak", "twox-hash", - "wasmi 0.9.0", + "wasmi", "zeroize", ] -[[package]] -name = "sp-debug-derive" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "sp-debug-derive" version = "3.0.0" @@ -2688,26 +2281,15 @@ dependencies = [ "syn", ] -[[package]] -name = "sp-externalities" -version = "0.8.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "environmental", - "parity-scale-codec 1.3.7", - "sp-std 2.0.0", - "sp-storage 2.0.0", -] - [[package]] name = "sp-externalities" version = "0.10.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ "environmental", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "sp-std 4.0.0-dev", - "sp-storage 4.0.0-dev", + "sp-storage", ] [[package]] @@ -2716,9 +2298,9 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ "async-trait", - "impl-trait-for-tuples 0.2.1", - "parity-scale-codec 2.2.0", - "sp-core 4.0.0-dev", + "impl-trait-for-tuples", + "parity-scale-codec", + "sp-core", "sp-runtime", "sp-std 4.0.0-dev", "thiserror", @@ -2733,18 +2315,18 @@ dependencies = [ "hash-db", "libsecp256k1", "log", - "parity-scale-codec 2.2.0", - "parking_lot 0.11.1", - "sp-core 4.0.0-dev", - "sp-externalities 0.10.0-dev", + "parity-scale-codec", + "parking_lot 0.11.2", + "sp-core", + "sp-externalities", "sp-keystore", "sp-maybe-compressed-blob", - "sp-runtime-interface 4.0.0-dev", + "sp-runtime-interface", "sp-state-machine", "sp-std 4.0.0-dev", - "sp-tracing 4.0.0-dev", + "sp-tracing", "sp-trie", - "sp-wasm-interface 4.0.0-dev", + "sp-wasm-interface", "tracing", "tracing-core", ] @@ -2758,11 +2340,11 @@ dependencies = [ "derive_more", "futures", "merlin", - "parity-scale-codec 2.2.0", - "parking_lot 0.11.1", + "parity-scale-codec", + "parking_lot 0.11.2", "schnorrkel", - "sp-core 4.0.0-dev", - "sp-externalities 0.10.0-dev", + "sp-core", + "sp-externalities", ] [[package]] @@ -2789,92 +2371,55 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#910 dependencies = [ "either", "hash256-std-hasher", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "log", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "parity-util-mem", "paste", "rand 0.7.3", "serde", "sp-application-crypto", "sp-arithmetic", - "sp-core 4.0.0-dev", + "sp-core", "sp-io", "sp-std 4.0.0-dev", ] -[[package]] -name = "sp-runtime-interface" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "parity-scale-codec 1.3.7", - "primitive-types 0.7.3", - "sp-externalities 0.8.0", - "sp-runtime-interface-proc-macro 2.0.0", - "sp-std 2.0.0", - "sp-storage 2.0.0", - "sp-tracing 2.0.0", - "sp-wasm-interface 2.0.0", - "static_assertions", -] - [[package]] name = "sp-runtime-interface" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ - "impl-trait-for-tuples 0.2.1", - "parity-scale-codec 2.2.0", - "primitive-types 0.10.1", - "sp-externalities 0.10.0-dev", - "sp-runtime-interface-proc-macro 4.0.0-dev", + "impl-trait-for-tuples", + "parity-scale-codec", + "primitive-types", + "sp-externalities", + "sp-runtime-interface-proc-macro", "sp-std 4.0.0-dev", - "sp-storage 4.0.0-dev", - "sp-tracing 4.0.0-dev", - "sp-wasm-interface 4.0.0-dev", + "sp-storage", + "sp-tracing", + "sp-wasm-interface", "static_assertions", ] -[[package]] -name = "sp-runtime-interface-proc-macro" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "Inflector", - "proc-macro-crate 0.1.5", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "sp-runtime-interface-proc-macro" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ "Inflector", - "proc-macro-crate 1.0.0", + "proc-macro-crate", "proc-macro2", "quote", "syn", ] -[[package]] -name = "sp-serializer" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "sp-staking" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ - "parity-scale-codec 2.2.0", + "parity-scale-codec", "sp-runtime", "sp-std 4.0.0-dev", ] @@ -2887,12 +2432,12 @@ dependencies = [ "hash-db", "log", "num-traits", - "parity-scale-codec 2.2.0", - "parking_lot 0.11.1", + "parity-scale-codec", + "parking_lot 0.11.2", "rand 0.7.3", "smallvec", - "sp-core 4.0.0-dev", - "sp-externalities 0.10.0-dev", + "sp-core", + "sp-externalities", "sp-panic-handler", "sp-std 4.0.0-dev", "sp-trie", @@ -2912,45 +2457,19 @@ name = "sp-std" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" -[[package]] -name = "sp-storage" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "impl-serde", - "parity-scale-codec 1.3.7", - "ref-cast", - "serde", - "sp-debug-derive 2.0.0", - "sp-std 2.0.0", -] - [[package]] name = "sp-storage" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ "impl-serde", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "ref-cast", "serde", - "sp-debug-derive 3.0.0", + "sp-debug-derive", "sp-std 4.0.0-dev", ] -[[package]] -name = "sp-tracing" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "log", - "parity-scale-codec 1.3.7", - "sp-std 2.0.0", - "tracing", - "tracing-core", - "tracing-subscriber", -] - [[package]] name = "sp-tracing" version = "4.0.0-dev" @@ -2958,7 +2477,7 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#910 dependencies = [ "erased-serde", "log", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "parking_lot 0.10.2", "serde", "serde_json", @@ -2976,8 +2495,8 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#910 dependencies = [ "hash-db", "memory-db", - "parity-scale-codec 2.2.0", - "sp-core 4.0.0-dev", + "parity-scale-codec", + "sp-core", "sp-std 4.0.0-dev", "trie-db", "trie-root", @@ -2989,8 +2508,8 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ "impl-serde", - "parity-scale-codec 2.2.0", - "parity-wasm 0.42.2", + "parity-scale-codec", + "parity-wasm", "serde", "sp-runtime", "sp-std 4.0.0-dev", @@ -3003,33 +2522,22 @@ name = "sp-version-proc-macro" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ - "parity-scale-codec 2.2.0", - "proc-macro-crate 1.0.0", + "parity-scale-codec", + "proc-macro-crate", "proc-macro2", "quote", "syn", ] -[[package]] -name = "sp-wasm-interface" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "impl-trait-for-tuples 0.1.3", - "parity-scale-codec 1.3.7", - "sp-std 2.0.0", - "wasmi 0.6.2", -] - [[package]] name = "sp-wasm-interface" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ - "impl-trait-for-tuples 0.2.1", - "parity-scale-codec 2.2.0", + "impl-trait-for-tuples", + "parity-scale-codec", "sp-std 4.0.0-dev", - "wasmi 0.9.0", + "wasmi", ] [[package]] @@ -3059,14 +2567,14 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "substrate-bip39" -version = "0.4.2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bed6646a0159b9935b5d045611560eeef842b78d7adc3ba36f5ca325a13a0236" +checksum = "49eee6965196b32f882dd2ee85a92b1dbead41b04e53907f269de3b0dc04733c" dependencies = [ - "hmac 0.7.1", - "pbkdf2 0.3.0", + "hmac 0.11.0", + "pbkdf2 0.8.0", "schnorrkel", - "sha2 0.8.2", + "sha2 0.9.8", "zeroize", ] @@ -3084,9 +2592,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.75" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" +checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194" dependencies = [ "proc-macro2", "quote", @@ -3131,18 +2639,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.26" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.26" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" dependencies = [ "proc-macro2", "quote", @@ -3160,25 +2668,9 @@ dependencies = [ [[package]] name = "tiny-bip39" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0165e045cc2ae1660270ca65e1676dbaab60feb0f91b10f7d0665e9b47e31f2" -dependencies = [ - "failure", - "hmac 0.7.1", - "once_cell", - "pbkdf2 0.3.0", - "rand 0.7.3", - "rustc-hash", - "sha2 0.8.2", - "unicode-normalization", -] - -[[package]] -name = "tiny-bip39" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9e44c4759bae7f1032e286a7ef990bd9ed23fe831b7eeba0beb97484c2e59b8" +checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" dependencies = [ "anyhow", "hmac 0.8.1", @@ -3186,9 +2678,10 @@ dependencies = [ "pbkdf2 0.4.0", "rand 0.7.3", "rustc-hash", - "sha2 0.9.5", + "sha2 0.9.8", "thiserror", "unicode-normalization", + "wasm-bindgen", "zeroize", ] @@ -3201,21 +2694,11 @@ dependencies = [ "crunchy", ] -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "tinyvec" -version = "1.3.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" +checksum = "f83b2a3d4d9091d0abd7eba4dc2710b1718583bd4d8992e2190720ea38f391f7" dependencies = [ "tinyvec_macros", ] @@ -3237,9 +2720,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.26" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" dependencies = [ "cfg-if 1.0.0", "pin-project-lite", @@ -3249,9 +2732,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.15" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2" +checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e" dependencies = [ "proc-macro2", "quote", @@ -3260,9 +2743,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.19" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ca517f43f0fb96e0c3072ed5c275fe5eece87e8cb52f4a77b69226d3b1c9df8" +checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" dependencies = [ "lazy_static", ] @@ -3290,9 +2773,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.2.20" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cbe87a2fa7e35900ce5de20220a582a9483a7063811defce79d7cbd59d4cfe" +checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" dependencies = [ "ansi_term 0.12.1", "chrono", @@ -3345,9 +2828,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.13.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" [[package]] name = "ucd-trie" @@ -3355,18 +2838,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" -[[package]] -name = "uint" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9db035e67dfaf7edd9aebfe8676afcd63eed53c8a4044fed514c8cccf1835177" -dependencies = [ - "byteorder", - "crunchy", - "rustc-hex", - "static_assertions", -] - [[package]] name = "uint" version = "0.9.1" @@ -3390,9 +2861,9 @@ dependencies = [ [[package]] name = "unicode-width" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "unicode-xid" @@ -3412,17 +2883,6 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" -[[package]] -name = "walkdir" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" -dependencies = [ - "same-file", - "winapi", - "winapi-util", -] - [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -3437,9 +2897,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0" +checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -3447,9 +2907,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041" +checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" dependencies = [ "bumpalo", "lazy_static", @@ -3462,9 +2922,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef" +checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3472,9 +2932,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad" +checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" dependencies = [ "proc-macro2", "quote", @@ -3485,65 +2945,32 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29" +checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" [[package]] name = "wasmi" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf617d864d25af3587aa745529f7aaa541066c876d57e050c0d0c85c61c92aff" -dependencies = [ - "libc", - "memory_units", - "num-rational 0.2.4", - "num-traits", - "parity-wasm 0.41.0", - "wasmi-validation 0.3.0", -] - -[[package]] -name = "wasmi" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ee05bba3d1d994652079893941a2ef9324d2b58a63c31b40678fb7eddd7a5a" +checksum = "ca00c5147c319a8ec91ec1a0edbec31e566ce2c9cc93b3f9bb86a9efd0eb795d" dependencies = [ "downcast-rs", "libc", "memory_units", "num-rational 0.2.4", "num-traits", - "parity-wasm 0.42.2", - "wasmi-validation 0.4.0", -] - -[[package]] -name = "wasmi-validation" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea78c597064ba73596099281e2f4cfc019075122a65cdda3205af94f0b264d93" -dependencies = [ - "parity-wasm 0.41.0", + "parity-wasm", + "wasmi-validation", ] [[package]] name = "wasmi-validation" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb8e860796d8be48efef530b60eebf84e74a88bce107374fffb0da97d504b8" -dependencies = [ - "parity-wasm 0.42.2", -] - -[[package]] -name = "web-sys" -version = "0.3.53" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c" +checksum = "165343ecd6c018fc09ebcae280752702c9a2ef3e6f8d02f1cfcbdb53ef6d7937" dependencies = [ - "js-sys", - "wasm-bindgen", + "parity-wasm", ] [[package]] @@ -3594,18 +3021,18 @@ checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" [[package]] name = "zeroize" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "377db0846015f7ae377174787dd452e1c5f5a9050bc6f954911d01f116daa0cd" +checksum = "bf68b08513768deaa790264a7fac27a58cbf2705cfcdc9448362229217d7e970" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1" +checksum = "bdff2024a851a322b08f179173ae2ba620445aef1e838f0c196820eade4ae0c7" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 3744dbdb..f6012a3c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,6 @@ members = [ "substrate-metadata-versions/metadatav9", "substrate-metadata-versions/metadatav10", "substrate-metadata-versions/metadatav11", - "substrate-metadata-versions/sp_core_versions/core-7314a" ] exclude = [ diff --git a/README.md b/README.md index 96ccba5d..92cf92f2 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Encompassing decoder for substrate/polkadot/kusama types. Gets type definitions from polkadot-js via JSON and decodes them into components that outline types and make decoding byte-strings possible, as long as the -module/generic type name are known. +module/generic type name are known. Supports Metadata versions from v8, which means all of Kusama (from CC1). Older networks are not supported (E.G Alexander). - makes decoding generic types from the substrate rpc possible @@ -30,9 +30,19 @@ Supports Metadata versions from v8, which means all of Kusama (from CC1). Older | Kulupu | | | | | | | | - Currently Supported Metadata Versions (From Kusama CC1): - [x] V8 - [x] V9 - [x] V10 - [x] V11 +- [x] V12 +- [x] V13 +- [ ] V14 + +### (Tentative) Release & Maintenence +#### Note: Release description is in no way complete because of current & active development for legacy desub types & scale-info based types. it is purely here as a record for things that _should_ be taken into account in the future + +- Depending on changes in legacy desub code, bump version in Cargo.toml for `extras/`, `core/` +- note `upgrade-blocks` present [here](https://github.com/polkadot-js/api/tree/master/packages/types-known/src/upgrades) and modify the hard-coded upgrade blocks as necessary in the desub `runtimes.rs` file. + - NOTE: this step may-or-may not be necessary depending on `scale-info` integration in the future. + diff --git a/bin/tx-decoder/Cargo.lock b/bin/tx-decoder/Cargo.lock index ab5a0442..ab1c234d 100644 --- a/bin/tx-decoder/Cargo.lock +++ b/bin/tx-decoder/Cargo.lock @@ -67,9 +67,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" +checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1" [[package]] name = "approx" @@ -80,6 +80,35 @@ dependencies = [ "num-traits", ] +[[package]] +name = "argh" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f023c76cd7975f9969f8e29f0e461decbdc7f51048ce43427107a3d192f1c9bf" +dependencies = [ + "argh_derive", + "argh_shared", +] + +[[package]] +name = "argh_derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48ad219abc0c06ca788aface2e3a1970587e3413ab70acd20e54b6ec524c1f8f" +dependencies = [ + "argh_shared", + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "argh_shared" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38de00daab4eac7d753e97697066238d67ce9d7e2d823ab4f72fe14af29f3f33" + [[package]] name = "arrayref" version = "0.3.6" @@ -359,7 +388,7 @@ dependencies = [ "cexpr", "clang-sys", "clap", - "env_logger 0.8.4", + "env_logger", "lazy_static", "lazycell", "log", @@ -378,16 +407,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bitvec" -version = "0.17.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" -dependencies = [ - "either", - "radium 0.3.0", -] - [[package]] name = "bitvec" version = "0.20.4" @@ -395,7 +414,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" dependencies = [ "funty", - "radium 0.6.2", + "radium", + "serde", "tap", "wyz", ] @@ -456,21 +476,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" - -[[package]] -name = "byte-slice-cast" -version = "0.3.5" +version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" +checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538" [[package]] name = "byte-slice-cast" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65c1bf4a04a88c54f589125563643d773f3254b5c38571395e2b591c693bbc81" +checksum = "ca0796d76a983651b4a0ddda16203032759f2fd9103d9181f7c65c06ee8872e6" [[package]] name = "byte-tools" @@ -540,9 +554,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cf2cc85830eae84823884db23c5306442a6c3d5bfd3beb2f2a2c829faa1816" +checksum = "10612c0ec0e0a1ff0e97980647cb058a6e7aedb913d01d009c406b8b7d0b26ee" dependencies = [ "glob", "libc", @@ -573,6 +587,28 @@ dependencies = [ "bitflags", ] +[[package]] +name = "colored" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" +dependencies = [ + "atty", + "lazy_static", + "winapi", +] + +[[package]] +name = "colored" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" +dependencies = [ + "atty", + "lazy_static", + "winapi", +] + [[package]] name = "concurrent-queue" version = "1.2.2" @@ -582,6 +618,19 @@ dependencies = [ "cache-padded", ] +[[package]] +name = "console" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3993e6445baa160675931ec041a5e03ca84b9c6e32a056150d3aa2bdda0a1f45" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "terminal_size", + "winapi", +] + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -628,6 +677,30 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + [[package]] name = "crossbeam-queue" version = "0.3.2" @@ -747,6 +820,7 @@ dependencies = [ name = "desub-core" version = "0.0.1" dependencies = [ + "bitvec", "derive_more", "dyn-clone", "frame-metadata 14.0.0", @@ -759,11 +833,10 @@ dependencies = [ "log", "onig", "pallet-democracy", - "parity-scale-codec 1.3.7", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "serde", "serde_json", - "sp-core 4.0.0-dev", + "sp-core", "sp-runtime", "sp-version", "thiserror", @@ -775,9 +848,11 @@ version = "0.0.1" dependencies = [ "desub-core", "log", - "parity-scale-codec 1.3.7", + "parity-scale-codec", + "phf", "serde", "serde_json", + "syn", "thiserror", ] @@ -877,7 +952,7 @@ dependencies = [ "ed25519", "rand 0.7.3", "serde", - "sha2 0.9.6", + "sha2 0.9.8", "zeroize", ] @@ -888,17 +963,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] -name = "env_logger" -version = "0.7.1" +name = "encode_unicode" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" -dependencies = [ - "atty", - "humantime 1.3.0", - "log", - "regex", - "termcolor", -] +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "env_logger" @@ -907,7 +975,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" dependencies = [ "atty", - "humantime 2.1.0", + "humantime", "log", "regex", "termcolor", @@ -934,28 +1002,6 @@ version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" -[[package]] -name = "failure" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" -dependencies = [ - "backtrace", - "failure_derive", -] - -[[package]] -name = "failure_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - [[package]] name = "fake-simd" version = "0.1.2" @@ -972,15 +1018,13 @@ dependencies = [ ] [[package]] -name = "fixed-hash" -version = "0.6.1" +name = "fern" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11498d382790b7a8f2fd211780bec78619bba81cdad3a283997c0c41f836759c" +checksum = "8c9a4820f0ccc8a7afd67c39a0f1a0f4b07ca1725164271a64939d7aeb9af065" dependencies = [ - "byteorder", - "rand 0.7.3", - "rustc-hex", - "static_assertions", + "colored 1.9.3", + "log", ] [[package]] @@ -1014,14 +1058,14 @@ dependencies = [ "frame-system", "linregress", "log", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "paste", "sp-api", "sp-io", "sp-runtime", - "sp-runtime-interface 4.0.0-dev", + "sp-runtime-interface", "sp-std 4.0.0-dev", - "sp-storage 4.0.0-dev", + "sp-storage", ] [[package]] @@ -1029,19 +1073,20 @@ name = "frame-metadata" version = "14.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ - "parity-scale-codec 2.2.0", + "parity-scale-codec", "serde", - "sp-core 4.0.0-dev", + "sp-core", "sp-std 4.0.0-dev", ] [[package]] name = "frame-metadata" version = "14.0.0" -source = "git+https://github.com/paritytech/frame-metadata#39fe3d8f279a37c7c414bf37db281a35e0ccd520" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96616f82e069102b95a72c87de4c84d2f87ef7f0f20630e78ce3824436483110" dependencies = [ "cfg-if 1.0.0", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "scale-info", "serde", ] @@ -1050,9 +1095,9 @@ dependencies = [ name = "frame-metadatav10" version = "10.0.0" dependencies = [ - "parity-scale-codec 1.3.7", + "frame-metadata 14.0.0", + "parity-scale-codec", "serde", - "sp-core 2.0.0", "sp-std 2.0.0", ] @@ -1060,9 +1105,9 @@ dependencies = [ name = "frame-metadatav11" version = "11.0.0-rc6" dependencies = [ - "parity-scale-codec 1.3.7", + "frame-metadata 14.0.0", + "parity-scale-codec", "serde", - "sp-core 2.0.0", "sp-std 2.0.0", ] @@ -1070,9 +1115,9 @@ dependencies = [ name = "frame-metadatav8" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.3.7", + "frame-metadata 14.0.0", + "parity-scale-codec", "serde", - "sp-core 2.0.0", "sp-std 2.0.0", ] @@ -1080,9 +1125,9 @@ dependencies = [ name = "frame-metadatav9" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.3.7", + "frame-metadata 14.0.0", + "parity-scale-codec", "serde", - "sp-core 2.0.0", "sp-std 2.0.0", ] @@ -1094,22 +1139,22 @@ dependencies = [ "bitflags", "frame-metadata 14.0.0-dev", "frame-support-procedural", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "log", "once_cell", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "paste", "serde", "smallvec", "sp-arithmetic", - "sp-core 4.0.0-dev", + "sp-core", "sp-inherents", "sp-io", "sp-runtime", "sp-staking", "sp-state-machine", "sp-std 4.0.0-dev", - "sp-tracing 4.0.0-dev", + "sp-tracing", ] [[package]] @@ -1130,7 +1175,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ "frame-support-procedural-tools-derive", - "proc-macro-crate 1.0.0", + "proc-macro-crate", "proc-macro2", "quote", "syn", @@ -1152,11 +1197,11 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ "frame-support", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "log", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "serde", - "sp-core 4.0.0-dev", + "sp-core", "sp-io", "sp-runtime", "sp-std 4.0.0-dev", @@ -1464,15 +1509,6 @@ dependencies = [ "hmac 0.7.1", ] -[[package]] -name = "humantime" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -dependencies = [ - "quick-error", -] - [[package]] name = "humantime" version = "2.1.0" @@ -1490,22 +1526,13 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "impl-codec" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" -dependencies = [ - "parity-scale-codec 1.3.7", -] - [[package]] name = "impl-codec" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "161ebdfec3c8e3b52bf61c4f3550a1eea4f9579d10dc1b936f3171ebdcd6c443" dependencies = [ - "parity-scale-codec 2.2.0", + "parity-scale-codec", ] [[package]] @@ -1517,17 +1544,6 @@ dependencies = [ "serde", ] -[[package]] -name = "impl-trait-for-tuples" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "impl-trait-for-tuples" version = "0.2.1" @@ -1549,6 +1565,19 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "indicatif" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d207dc617c7a380ab07ff572a6e52fa202a2a8f355860ac9c38e23f8196be1b" +dependencies = [ + "console", + "lazy_static", + "number_prefix", + "rayon", + "regex", +] + [[package]] name = "instant" version = "0.1.10" @@ -1567,6 +1596,15 @@ dependencies = [ "num-traits", ] +[[package]] +name = "itertools" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "0.4.8" @@ -1584,9 +1622,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.53" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d" +checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" dependencies = [ "wasm-bindgen", ] @@ -1620,9 +1658,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.101" +version = "0.2.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" +checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" [[package]] name = "libloading" @@ -1694,12 +1732,6 @@ dependencies = [ "value-bag", ] -[[package]] -name = "maplit" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" - [[package]] name = "matchers" version = "0.0.1" @@ -1741,6 +1773,15 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +[[package]] +name = "memoffset" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +dependencies = [ + "autocfg", +] + [[package]] name = "memory-db" version = "0.27.0" @@ -1772,9 +1813,9 @@ dependencies = [ [[package]] name = "minimal-lexical" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6595bb28ed34f43c3fe088e48f6cfb2e033cab45f25a5384d5fdf564fbc8c4b2" +checksum = "0c835948974f68e0bd58636fc6c5b1fbff7b297e3046f11b3b3c18bbac012c6d" [[package]] name = "miniz_oxide" @@ -1915,6 +1956,12 @@ dependencies = [ "libc", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "object" version = "0.26.2" @@ -1976,7 +2023,7 @@ dependencies = [ "frame-benchmarking", "frame-support", "frame-system", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "serde", "sp-io", "sp-runtime", @@ -1985,50 +2032,25 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "1.3.7" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b26b16c7687c3075982af47719e481815df30bc544f7a6690763a25ca16e9d" -dependencies = [ - "arrayvec 0.5.2", - "bitvec 0.17.4", - "byte-slice-cast 0.3.5", - "parity-scale-codec-derive 1.2.3", - "serde", -] - -[[package]] -name = "parity-scale-codec" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8975095a2a03bbbdc70a74ab11a4f76a6d0b84680d87c68d722531b0ac28e8a9" +checksum = "e11263a97373b43da4b426edbb52ef99a7b51e2d9752ef56a7f8b356f48495a5" dependencies = [ "arrayvec 0.7.1", - "bitvec 0.20.4", - "byte-slice-cast 1.0.0", - "impl-trait-for-tuples 0.2.1", - "parity-scale-codec-derive 2.2.0", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", "serde", ] [[package]] name = "parity-scale-codec-derive" -version = "1.2.3" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c41512944b1faff334a5f1b9447611bf4ef40638ccb6328173dacefb338e878c" +checksum = "b157dc92b3db2bae522afb31b3843e91ae097eb01d66c72dda66a2e86bc3ca14" dependencies = [ - "proc-macro-crate 0.1.5", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40dbbfef7f0a1143c5b06e0d76a6278e25dac0bc1af4be51a0fbb73f07e7ad09" -dependencies = [ - "proc-macro-crate 1.0.0", + "proc-macro-crate", "proc-macro2", "quote", "syn", @@ -2042,10 +2064,10 @@ checksum = "7ad6f1acec69b95caf435bbd158d486e5a0a44fcf51531e84922c59ff09e8457" dependencies = [ "cfg-if 1.0.0", "hashbrown", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "parity-util-mem-derive", "parking_lot 0.11.2", - "primitive-types 0.10.1", + "primitive-types", "winapi", ] @@ -2060,12 +2082,6 @@ dependencies = [ "synstructure", ] -[[package]] -name = "parity-wasm" -version = "0.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" - [[package]] name = "parity-wasm" version = "0.42.2" @@ -2133,16 +2149,6 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58" -[[package]] -name = "pbkdf2" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" -dependencies = [ - "byteorder", - "crypto-mac 0.7.0", -] - [[package]] name = "pbkdf2" version = "0.4.0" @@ -2182,6 +2188,50 @@ dependencies = [ "ucd-trie", ] +[[package]] +name = "phf" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9fc3db1018c4b59d7d582a739436478b6035138b6aecbce989fc91c3e98409f" +dependencies = [ + "phf_macros", + "phf_shared", + "proc-macro-hack", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared", + "rand 0.8.4", +] + +[[package]] +name = "phf_macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project-lite" version = "0.2.7" @@ -2219,54 +2269,23 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" -[[package]] -name = "pretty_env_logger" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" -dependencies = [ - "env_logger 0.7.1", - "log", -] - -[[package]] -name = "primitive-types" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd39dcacf71411ba488570da7bbc89b717225e46478b30ba99b92db6b149809" -dependencies = [ - "fixed-hash 0.6.1", - "impl-codec 0.4.2", - "impl-serde", - "uint 0.8.5", -] - [[package]] name = "primitive-types" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" dependencies = [ - "fixed-hash 0.7.0", - "impl-codec 0.5.1", + "fixed-hash", + "impl-codec", "impl-serde", - "uint 0.9.1", + "uint", ] [[package]] name = "proc-macro-crate" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" -dependencies = [ - "toml", -] - -[[package]] -name = "proc-macro-crate" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fdbd1df62156fbc5945f4762632564d7d038153091c3fcf1067f6aef7cff92" +checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" dependencies = [ "thiserror", "toml", @@ -2293,12 +2312,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - [[package]] name = "quote" version = "1.0.9" @@ -2308,12 +2321,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "radium" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" - [[package]] name = "radium" version = "0.6.2" @@ -2427,6 +2434,31 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + [[package]] name = "redox_syscall" version = "0.1.57" @@ -2575,10 +2607,10 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c55b744399c25532d63a0d2789b109df8d46fc93752d46b0782991a931a782f" dependencies = [ - "bitvec 0.20.4", + "bitvec", "cfg-if 1.0.0", "derive_more", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "scale-info-derive", "serde", ] @@ -2589,7 +2621,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baeb2780690380592f86205aa4ee49815feb2acad8c2f59e6dd207148c3f1fcd" dependencies = [ - "proc-macro-crate 1.0.0", + "proc-macro-crate", "proc-macro2", "quote", "syn", @@ -2629,15 +2661,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "secrecy" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9182278ed645df3477a9c27bfee0621c621aa16f6972635f7f795dae3d81070f" -dependencies = [ - "zeroize", -] - [[package]] name = "secrecy" version = "0.7.0" @@ -2687,9 +2710,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950" +checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" dependencies = [ "indexmap", "itoa", @@ -2724,9 +2747,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.6" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9204c41a1597a8c5af23c82d1c921cb01ec0a4c59e07a9c7306062829a3903f3" +checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" dependencies = [ "block-buffer 0.9.0", "cfg-if 1.0.0", @@ -2787,6 +2810,12 @@ dependencies = [ "paste", ] +[[package]] +name = "siphasher" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b" + [[package]] name = "slab" version = "0.4.4" @@ -2810,9 +2839,9 @@ checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" [[package]] name = "socket2" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765f090f0e423d2b55843402a07915add955e7d60657db13707a159727326cad" +checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" dependencies = [ "libc", "winapi", @@ -2825,9 +2854,9 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#910 dependencies = [ "hash-db", "log", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "sp-api-proc-macro", - "sp-core 4.0.0-dev", + "sp-core", "sp-runtime", "sp-state-machine", "sp-std 4.0.0-dev", @@ -2841,7 +2870,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ "blake2-rfc", - "proc-macro-crate 1.0.0", + "proc-macro-crate", "proc-macro2", "quote", "syn", @@ -2852,9 +2881,9 @@ name = "sp-application-crypto" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ - "parity-scale-codec 2.2.0", + "parity-scale-codec", "serde", - "sp-core 4.0.0-dev", + "sp-core", "sp-io", "sp-std 4.0.0-dev", ] @@ -2866,56 +2895,13 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#910 dependencies = [ "integer-sqrt", "num-traits", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "serde", - "sp-debug-derive 3.0.0", + "sp-debug-derive", "sp-std 4.0.0-dev", "static_assertions", ] -[[package]] -name = "sp-core" -version = "2.0.0" -dependencies = [ - "base58", - "blake2-rfc", - "byteorder", - "derive_more", - "dyn-clonable", - "ed25519-dalek", - "futures", - "hash-db", - "hash256-std-hasher", - "hex", - "impl-serde", - "lazy_static", - "libsecp256k1", - "log", - "merlin", - "num-traits", - "parity-scale-codec 1.3.7", - "parity-util-mem", - "parking_lot 0.10.2", - "primitive-types 0.7.3", - "rand 0.7.3", - "regex", - "schnorrkel", - "secrecy 0.6.0", - "serde", - "sha2 0.8.2", - "sp-debug-derive 2.0.0", - "sp-externalities 0.8.0", - "sp-runtime-interface 2.0.0", - "sp-std 2.0.0", - "sp-storage 2.0.0", - "substrate-bip39", - "tiny-bip39 0.7.3", - "tiny-keccak", - "twox-hash", - "wasmi 0.6.2", - "zeroize", -] - [[package]] name = "sp-core" version = "4.0.0-dev" @@ -2936,40 +2922,30 @@ dependencies = [ "log", "merlin", "num-traits", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "parity-util-mem", "parking_lot 0.11.2", - "primitive-types 0.10.1", + "primitive-types", "rand 0.7.3", "regex", "schnorrkel", - "secrecy 0.7.0", + "secrecy", "serde", - "sha2 0.9.6", - "sp-debug-derive 3.0.0", - "sp-externalities 0.10.0-dev", - "sp-runtime-interface 4.0.0-dev", + "sha2 0.9.8", + "sp-debug-derive", + "sp-externalities", + "sp-runtime-interface", "sp-std 4.0.0-dev", - "sp-storage 4.0.0-dev", + "sp-storage", "substrate-bip39", "thiserror", - "tiny-bip39 0.8.0", + "tiny-bip39", "tiny-keccak", "twox-hash", - "wasmi 0.9.0", + "wasmi", "zeroize", ] -[[package]] -name = "sp-debug-derive" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "sp-debug-derive" version = "3.0.0" @@ -2980,26 +2956,15 @@ dependencies = [ "syn", ] -[[package]] -name = "sp-externalities" -version = "0.8.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "environmental", - "parity-scale-codec 1.3.7", - "sp-std 2.0.0", - "sp-storage 2.0.0", -] - [[package]] name = "sp-externalities" version = "0.10.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ "environmental", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "sp-std 4.0.0-dev", - "sp-storage 4.0.0-dev", + "sp-storage", ] [[package]] @@ -3008,9 +2973,9 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ "async-trait", - "impl-trait-for-tuples 0.2.1", - "parity-scale-codec 2.2.0", - "sp-core 4.0.0-dev", + "impl-trait-for-tuples", + "parity-scale-codec", + "sp-core", "sp-runtime", "sp-std 4.0.0-dev", "thiserror", @@ -3025,18 +2990,18 @@ dependencies = [ "hash-db", "libsecp256k1", "log", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "parking_lot 0.11.2", - "sp-core 4.0.0-dev", - "sp-externalities 0.10.0-dev", + "sp-core", + "sp-externalities", "sp-keystore", "sp-maybe-compressed-blob", - "sp-runtime-interface 4.0.0-dev", + "sp-runtime-interface", "sp-state-machine", "sp-std 4.0.0-dev", - "sp-tracing 4.0.0-dev", + "sp-tracing", "sp-trie", - "sp-wasm-interface 4.0.0-dev", + "sp-wasm-interface", "tracing", "tracing-core", ] @@ -3050,11 +3015,11 @@ dependencies = [ "derive_more", "futures", "merlin", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "parking_lot 0.11.2", "schnorrkel", - "sp-core 4.0.0-dev", - "sp-externalities 0.10.0-dev", + "sp-core", + "sp-externalities", ] [[package]] @@ -3081,72 +3046,44 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#910 dependencies = [ "either", "hash256-std-hasher", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "log", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "parity-util-mem", "paste", "rand 0.7.3", "serde", "sp-application-crypto", "sp-arithmetic", - "sp-core 4.0.0-dev", + "sp-core", "sp-io", "sp-std 4.0.0-dev", ] -[[package]] -name = "sp-runtime-interface" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "parity-scale-codec 1.3.7", - "primitive-types 0.7.3", - "sp-externalities 0.8.0", - "sp-runtime-interface-proc-macro 2.0.0", - "sp-std 2.0.0", - "sp-storage 2.0.0", - "sp-tracing 2.0.0", - "sp-wasm-interface 2.0.0", - "static_assertions", -] - [[package]] name = "sp-runtime-interface" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ - "impl-trait-for-tuples 0.2.1", - "parity-scale-codec 2.2.0", - "primitive-types 0.10.1", - "sp-externalities 0.10.0-dev", - "sp-runtime-interface-proc-macro 4.0.0-dev", + "impl-trait-for-tuples", + "parity-scale-codec", + "primitive-types", + "sp-externalities", + "sp-runtime-interface-proc-macro", "sp-std 4.0.0-dev", - "sp-storage 4.0.0-dev", - "sp-tracing 4.0.0-dev", - "sp-wasm-interface 4.0.0-dev", + "sp-storage", + "sp-tracing", + "sp-wasm-interface", "static_assertions", ] -[[package]] -name = "sp-runtime-interface-proc-macro" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "Inflector", - "proc-macro-crate 0.1.5", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "sp-runtime-interface-proc-macro" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ "Inflector", - "proc-macro-crate 1.0.0", + "proc-macro-crate", "proc-macro2", "quote", "syn", @@ -3157,7 +3094,7 @@ name = "sp-staking" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ - "parity-scale-codec 2.2.0", + "parity-scale-codec", "sp-runtime", "sp-std 4.0.0-dev", ] @@ -3170,12 +3107,12 @@ dependencies = [ "hash-db", "log", "num-traits", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "parking_lot 0.11.2", "rand 0.7.3", "smallvec", - "sp-core 4.0.0-dev", - "sp-externalities 0.10.0-dev", + "sp-core", + "sp-externalities", "sp-panic-handler", "sp-std 4.0.0-dev", "sp-trie", @@ -3195,45 +3132,19 @@ name = "sp-std" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" -[[package]] -name = "sp-storage" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "impl-serde", - "parity-scale-codec 1.3.7", - "ref-cast", - "serde", - "sp-debug-derive 2.0.0", - "sp-std 2.0.0", -] - [[package]] name = "sp-storage" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ "impl-serde", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "ref-cast", "serde", - "sp-debug-derive 3.0.0", + "sp-debug-derive", "sp-std 4.0.0-dev", ] -[[package]] -name = "sp-tracing" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "log", - "parity-scale-codec 1.3.7", - "sp-std 2.0.0", - "tracing", - "tracing-core", - "tracing-subscriber", -] - [[package]] name = "sp-tracing" version = "4.0.0-dev" @@ -3241,7 +3152,7 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#910 dependencies = [ "erased-serde", "log", - "parity-scale-codec 2.2.0", + "parity-scale-codec", "parking_lot 0.10.2", "serde", "serde_json", @@ -3259,8 +3170,8 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#910 dependencies = [ "hash-db", "memory-db", - "parity-scale-codec 2.2.0", - "sp-core 4.0.0-dev", + "parity-scale-codec", + "sp-core", "sp-std 4.0.0-dev", "trie-db", "trie-root", @@ -3272,8 +3183,8 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ "impl-serde", - "parity-scale-codec 2.2.0", - "parity-wasm 0.42.2", + "parity-scale-codec", + "parity-wasm", "serde", "sp-runtime", "sp-std 4.0.0-dev", @@ -3286,33 +3197,22 @@ name = "sp-version-proc-macro" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ - "parity-scale-codec 2.2.0", - "proc-macro-crate 1.0.0", + "parity-scale-codec", + "proc-macro-crate", "proc-macro2", "quote", "syn", ] -[[package]] -name = "sp-wasm-interface" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "impl-trait-for-tuples 0.1.3", - "parity-scale-codec 1.3.7", - "sp-std 2.0.0", - "wasmi 0.6.2", -] - [[package]] name = "sp-wasm-interface" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9#91061a7d925b5bc597804293da283477512ba4ff" dependencies = [ - "impl-trait-for-tuples 0.2.1", - "parity-scale-codec 2.2.0", + "impl-trait-for-tuples", + "parity-scale-codec", "sp-std 4.0.0-dev", - "wasmi 0.9.0", + "wasmi", ] [[package]] @@ -3323,14 +3223,12 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "sqlformat" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "684001e7985ec1a9a66963b77ed151ef22a7876b3fdd7e37a57ec774f54b7d96" +checksum = "b4b7922be017ee70900be125523f38bdd644f4f06a1b16e8fa5a8ee8c34bffd4" dependencies = [ - "lazy_static", - "maplit", + "itertools", "nom 7.0.0", - "regex", "unicode_categories", ] @@ -3382,7 +3280,7 @@ dependencies = [ "serde", "serde_json", "sha-1", - "sha2 0.9.6", + "sha2 0.9.8", "smallvec", "sqlformat", "sqlx-rt", @@ -3407,7 +3305,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "sha2 0.9.6", + "sha2 0.9.8", "sqlx-core", "sqlx-rt", "syn", @@ -3468,7 +3366,7 @@ dependencies = [ "hmac 0.11.0", "pbkdf2 0.8.0", "schnorrkel", - "sha2 0.9.6", + "sha2 0.9.8", "zeroize", ] @@ -3486,9 +3384,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.75" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" +checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84" dependencies = [ "proc-macro2", "quote", @@ -3522,6 +3420,16 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "terminal_size" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -3533,18 +3441,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "283d5230e63df9608ac7d9691adc1dfb6e701225436eb64d0b9a7f0a5a04f6ec" +checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa3884228611f5cd3608e2d409bf7dce832e4eb3135e3f11addbd7e41bd68e71" +checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" dependencies = [ "proc-macro2", "quote", @@ -3560,22 +3468,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "tiny-bip39" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0165e045cc2ae1660270ca65e1676dbaab60feb0f91b10f7d0665e9b47e31f2" -dependencies = [ - "failure", - "hmac 0.7.1", - "once_cell", - "pbkdf2 0.3.0", - "rand 0.7.3", - "rustc-hash", - "sha2 0.8.2", - "unicode-normalization", -] - [[package]] name = "tiny-bip39" version = "0.8.0" @@ -3588,7 +3480,7 @@ dependencies = [ "pbkdf2 0.4.0", "rand 0.7.3", "rustc-hash", - "sha2 0.9.6", + "sha2 0.9.8", "thiserror", "unicode-normalization", "zeroize", @@ -3605,9 +3497,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" +checksum = "5241dd6f21443a3606b432718b166d3cedc962fd4b8bea54a8bc7f514ebda986" dependencies = [ "tinyvec_macros", ] @@ -3629,9 +3521,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.26" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +checksum = "84f96e095c0c82419687c20ddf5cb3eadb61f4e1405923c9dc8e53a1adacbda8" dependencies = [ "cfg-if 1.0.0", "pin-project-lite", @@ -3641,9 +3533,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2" +checksum = "98863d0dd09fa59a1b79c6750ad80dbda6b75f4e71c437a6a1a8cb91a8bcbd77" dependencies = [ "proc-macro2", "quote", @@ -3652,9 +3544,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ca517f43f0fb96e0c3072ed5c275fe5eece87e8cb52f4a77b69226d3b1c9df8" +checksum = "46125608c26121c81b0c6d693eab5a420e416da7e43c426d2e8f7df8da8a3acf" dependencies = [ "lazy_static", ] @@ -3682,9 +3574,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.2.20" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cbe87a2fa7e35900ce5de20220a582a9483a7063811defce79d7cbd59d4cfe" +checksum = "56c42e73a9d277d4d2b6a88389a137ccf3c58599660b17e8f5fc39305e490669" dependencies = [ "ansi_term 0.12.1", "chrono", @@ -3740,13 +3632,19 @@ name = "tx-decoder" version = "0.1.0" dependencies = [ "anyhow", + "argh", "async-std", "async-stream", + "colored 2.0.0", "desub-core", "desub-extras", + "fern", "futures", + "indicatif", "log", - "pretty_env_logger", + "num_cpus", + "parking_lot 0.11.2", + "rayon", "serde", "serde_json", "sqlx", @@ -3764,18 +3662,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" -[[package]] -name = "uint" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9db035e67dfaf7edd9aebfe8676afcd63eed53c8a4044fed514c8cccf1835177" -dependencies = [ - "byteorder", - "crunchy", - "rustc-hex", - "static_assertions", -] - [[package]] name = "uint" version = "0.9.1" @@ -3811,9 +3697,9 @@ checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "unicode-xid" @@ -3887,9 +3773,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0" +checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -3897,9 +3783,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041" +checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" dependencies = [ "bumpalo", "lazy_static", @@ -3912,9 +3798,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.26" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fded345a6559c2cfee778d562300c581f7d4ff3edb9b0d230d69800d213972" +checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -3924,9 +3810,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef" +checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3934,9 +3820,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad" +checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" dependencies = [ "proc-macro2", "quote", @@ -3947,23 +3833,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29" - -[[package]] -name = "wasmi" -version = "0.6.2" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf617d864d25af3587aa745529f7aaa541066c876d57e050c0d0c85c61c92aff" -dependencies = [ - "libc", - "memory_units", - "num-rational 0.2.4", - "num-traits", - "parity-wasm 0.41.0", - "wasmi-validation 0.3.0", -] +checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" [[package]] name = "wasmi" @@ -3976,17 +3848,8 @@ dependencies = [ "memory_units", "num-rational 0.2.4", "num-traits", - "parity-wasm 0.42.2", - "wasmi-validation 0.4.0", -] - -[[package]] -name = "wasmi-validation" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea78c597064ba73596099281e2f4cfc019075122a65cdda3205af94f0b264d93" -dependencies = [ - "parity-wasm 0.41.0", + "parity-wasm", + "wasmi-validation", ] [[package]] @@ -3995,14 +3858,14 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb8e860796d8be48efef530b60eebf84e74a88bce107374fffb0da97d504b8" dependencies = [ - "parity-wasm 0.42.2", + "parity-wasm", ] [[package]] name = "web-sys" -version = "0.3.53" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c" +checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/bin/tx-decoder/Cargo.toml b/bin/tx-decoder/Cargo.toml index 5892e132..744c4b20 100644 --- a/bin/tx-decoder/Cargo.toml +++ b/bin/tx-decoder/Cargo.toml @@ -16,4 +16,10 @@ futures = "0.3.17" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.67" log = "0.4.14" -pretty_env_logger = "0.4.0" +argh = "0.1.6" +fern = {version = "0.6.0", features = [ "colored" ] } +colored = "2.0.0" +indicatif = { version = "0.16.2", features = [ "rayon" ] } +rayon = "1.5.1" +parking_lot = "0.11.2" +num_cpus = "1.13.0" diff --git a/bin/tx-decoder/src/app.rs b/bin/tx-decoder/src/app.rs new file mode 100644 index 00000000..8e4ceb1e --- /dev/null +++ b/bin/tx-decoder/src/app.rs @@ -0,0 +1,259 @@ +// Copyright 2021 Parity Technologies (UK) Ltd. +// This file is part of substrate-desub. +// +// substrate-desub is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// substrate-desub is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with substrate-desub. If not, see . + +use crate::queries::*; + +use desub::decoder::{Chain, Decoder}; +use desub_extras::runtimes; + +use anyhow::Error; +use argh::FromArgs; +use async_std::task; +use futures::StreamExt; +use indicatif::{ProgressBar, ProgressStyle}; +use parking_lot::{Mutex, RwLock}; +use rayon::prelude::*; +use sqlx::postgres::{PgConnection, PgPool, PgPoolOptions}; + +use std::{ + borrow::Cow, + convert::TryInto, + sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, + }, +}; + +type SpecVersion = i32; + +#[derive(FromArgs, PartialEq, Debug)] +/// Decode Extrinsics And Storage from Substrate Archive +pub struct App { + #[argh(option, default = "default_database_url()", short = 'd')] + /// database url containing encoded information. + database_url: String, + #[argh(option, default = "Chain::Polkadot", short = 'n')] + /// chain + network: Chain, + #[argh(option, short = 's')] + /// decode blocks only in this spec version. + spec: Option, + #[argh(option, short = 'b')] + /// decode only a specific block. + block: Option, + #[argh(switch, short = 'a')] + /// decode all blocks + all: bool, + #[argh(option, short = 'u')] + /// decode all blocks up to a spec version. + to: Option, + #[argh(switch, short = 'v')] + /// extra information about the programs execution. + pub verbose: bool, + #[argh(switch, short = 'p')] + /// show decoding progress. + pub progress: bool, +} + +struct AppState<'a> { + app: &'a App, + decoder: &'a RwLock, + pool: &'a PgPool, + pb: Option<&'a ProgressBar>, +} + +impl<'a> AppState<'a> { + fn new(app: &'a App, decoder: &'a RwLock, pool: &'a PgPool, pb: Option<&'a ProgressBar>) -> Self { + Self { app, decoder, pool, pb } + } + + fn print_blocks(&self, versions: Vec, errors: &mut Vec) -> Result<(usize, usize), Error> { + let error_count = AtomicUsize::new(0); + let length = AtomicUsize::new(0); + let errors = Arc::new(Mutex::new(errors)); + versions.into_par_iter().try_for_each(|version| { + let mut conn = task::block_on(self.pool.acquire())?; + let previous = task::block_on(self.register_metadata(&mut conn, version.try_into()?))?.map(|v| v as i32); + let mut errors = (*errors).lock(); + let (err, len) = + task::block_on(self.print_blocks_by_spec(&mut conn, version as i32, previous, &mut errors))?; + error_count.fetch_add(err, Ordering::SeqCst); + length.fetch_add(len, Ordering::SeqCst); + Ok::<_, Error>(()) + })?; + Ok((error_count.into_inner(), length.into_inner())) + } + + async fn print_blocks_by_spec( + &self, + conn: &mut PgConnection, + version: i32, + previous: Option, + errors: &mut Vec, + ) -> Result<(usize, usize), Error> { + let mut blocks = blocks_by_spec(conn, version); + let upgrade_block = get_upgrade_block(&self.app.network, version.try_into()?); + let mut len = 0; + let mut error_count = 0; + let decoder = self.decoder.read(); + while let Some(Ok(block)) = blocks.next().await { + let version = if upgrade_block == Some(block.block_num.try_into()?) && upgrade_block != Some(0) { + previous.expect("Upgrade block must have previous version; qed") + } else { + version + }; + if Self::decode(&decoder, block, version, errors).is_err() { + error_count += 1; + } + len += 1; + self.pb.map(|p| p.inc(1)); + } + Ok((error_count, len)) + } + + fn decode(decoder: &Decoder, block: BlockModel, spec: SpecVersion, errors: &mut Vec) -> Result<(), Error> { + log::debug!("-<<-<<-<<-<<-<<-<<-<<-<<-<< Decoding block {}, ext length {}", block.block_num, block.ext.len()); + match decoder.decode_extrinsics(spec.try_into()?, block.ext.as_slice()) { + Err(e) => { + let e: Error = e.into(); + let e = e.context(format!("Failed to decode block {}", block.block_num)); + errors.push(format!("{}", e)); + Err(e) + } + Ok(d) => { + log::info!("Block {} Decoded Succesfully. {}", block.block_num, serde_json::to_string_pretty(&d)?); + Ok(()) + } + } + } + + /// Register the metadata with Decoder + /// returns the previous spec version. + async fn register_metadata(&self, conn: &mut PgConnection, version: SpecVersion) -> Result, Error> { + let (past, present) = past_and_present_version(conn, version).await?; + let mut decoder = self.decoder.write(); + if !decoder.has_version(present) { + let meta = metadata(conn, present.try_into()?).await?; + decoder.register_version(present, meta); + } + + if let Some(p) = past { + if !decoder.has_version(p) { + let meta = metadata(conn, p.try_into()?).await?; + decoder.register_version(p, meta); + } + } + Ok(past.try_into()?) + } + + fn set_message(&self, msg: impl Into>) { + self.pb.map(|p| p.set_message(msg)); + } + + fn set_length(&self, len: u64) { + self.pb.map(|p| p.set_length(len)); + } + + fn finish_and_clear(&self) { + self.pb.map(|p| p.finish_and_clear()); + } +} + +pub async fn app(app: App) -> Result<(), Error> { + let pool = PgPoolOptions::new().max_connections(num_cpus::get() as u32).connect(&app.database_url).await?; + + let mut conn = pool.acquire().await?; + + let types = desub_extras::TypeResolver::default(); + let decoder = Arc::new(RwLock::new(Decoder::new(types, app.network.clone()))); + let mut errors = Vec::new(); + + let pb = if app.progress { Some(construct_progress_bar(1000)) } else { None }; + + let state = AppState::new(&app, &decoder, &pool, pb.as_ref()); + + if let Some(block) = &app.block { + let version = version_by_block(&mut conn, *block).await?; + let previous = state.register_metadata(&mut conn, version).await?; + let block = single_block(&mut conn, *block as i32).await?; + let version = if get_upgrade_block(&app.network, version.try_into()?) == Some(block.block_num.try_into()?) { + previous.expect("Upgrade block must have previous version; qed") + } else { + version as u32 + }; + AppState::decode(&decoder.read(), block, version.try_into()?, &mut errors)?; + } + + if let Some(spec) = app.spec { + let now = std::time::Instant::now(); + let count = blocks_in_spec(&mut conn, spec).await?; + state.set_message(format!("decoding blocks for spec {}", spec)); + state.set_length(count as u64); + let (error_count, len) = state.print_blocks(vec![spec.try_into()?], &mut errors)?; + state.finish_and_clear(); + println!("Took {:?} to decode {} blocks with {} errors.", now.elapsed(), len, error_count); + } + + if let Some(to) = app.to { + let spec_versions = spec_versions_upto(&mut conn, to).await?; + let now = std::time::Instant::now(); + let count = count_upto_spec(&mut conn, to).await?; + state.set_message(format!("decoding blocks up to spec {}", to)); + state.set_length(count as u64); + let (error_count, length) = state.print_blocks(spec_versions, &mut errors)?; + state.finish_and_clear(); + println!("Took {:?} to decode {} blocks with {} errors.", now.elapsed(), length, error_count); + } + + if app.all { + let spec_versions = spec_versions(&mut conn).await?; + let now = std::time::Instant::now(); + let count = total_block_count(&mut conn).await?; + pb.as_ref().map(|p| p.set_message("decoding all blocks")); + pb.as_ref().map(|p| p.set_length(count as u64)); + let (error_count, length) = state.print_blocks(spec_versions, &mut errors)?; + state.finish_and_clear(); + println!("Took {:?} to decode {} blocks with {} errors.", now.elapsed(), length, error_count); + } + + for e in errors.iter() { + println!("{}", e); + } + Ok(()) +} + +fn default_database_url() -> String { + "postgres://postgres@localhost:5432/postgres".to_string() +} + +fn construct_progress_bar(count: usize) -> ProgressBar { + let bar = ProgressBar::new(count as u64); + bar.set_style( + ProgressStyle::default_bar() + .template("{spinner:.cyan} {msg} [{elapsed_precise}] [{bar:40.cyan/blue}] {percent}% ({eta}) ({pos}/{len})") + .progress_chars("#>-"), + ); + bar +} + +fn get_upgrade_block(chain: &Chain, version: u32) -> Option { + match chain { + Chain::Kusama => runtimes::kusama_upgrade_block(&version), + Chain::Polkadot => runtimes::polkadot_upgrade_block(&version), + Chain::Westend => runtimes::westend_upgrade_block(&version), + _ => None, + } +} diff --git a/bin/tx-decoder/src/main.rs b/bin/tx-decoder/src/main.rs index b77cea0a..2cd4ad5e 100644 --- a/bin/tx-decoder/src/main.rs +++ b/bin/tx-decoder/src/main.rs @@ -14,52 +14,40 @@ // You should have received a copy of the GNU General Public License // along with substrate-desub. If not, see . +mod app; mod queries; -use queries::*; - -use desub::decoder::{Decoder, Chain}; - -use sqlx::postgres::PgPoolOptions; -use futures::StreamExt; use anyhow::Error; -use std::convert::TryInto; - -const SPEC: i32 = 1030; +use colored::Colorize; +use fern::colors::{Color, ColoredLevelConfig}; #[async_std::main] async fn main() -> Result<(), Error> { - pretty_env_logger::init(); - - let pool = PgPoolOptions::new() - .connect("postgres://postgres:123@localhost:6432/kusama-db") - .await?; - - let mut conn = pool.acquire().await?; - - let types = desub_extras::TypeResolver::default(); - let mut decoder = Decoder::new(types, Chain::Kusama); - let metadata = metadata(&mut conn, SPEC).await?; - decoder.register_version(SPEC.try_into()?, metadata); - - let mut blocks = blocks(&mut conn, SPEC); - let mut len = 0; - let mut error_count = 0; - let now = std::time::Instant::now(); - while let Some(Ok(block)) = blocks.next().await { - match decoder.decode_extrinsic(SPEC.try_into()?, block.ext.as_slice()) { - Err(e) => { - error_count += 1; - len += 1; - log::error!("Failed to decode block {} due to {}", block.block_num, e); - }, - Ok(_) => { - len += 1; - } - } - } - - println!("Took {:?} to decode {} blocks with {} errors.", now.elapsed(), len, error_count); - + let app: self::app::App = argh::from_env(); + let level = if app.verbose { log::LevelFilter::Trace } else { log::LevelFilter::Warn }; + let colors = + ColoredLevelConfig::new().trace(Color::Magenta).error(Color::Red).debug(Color::Blue).info(Color::Green); + + // Configure logger at runtime + fern::Dispatch::new() + .level(log::LevelFilter::Error) + .level_for("desub_core", level) + .level_for("desub_extras", level) + .level_for("tx_decoder", level) + .format(move |out, message, record| { + out.finish(format_args!( + " {} {}::{} >{} ", + colors.color(record.level()), + record.target().bold(), + record.line().map(|l| l.to_string()).unwrap_or_default(), + message.to_string(), + )) + }) + // Output to stdout, files, and other Dispatch configurations + .chain(std::io::stdout()) + // Apply globally + .apply()?; + + app::app(app).await?; Ok(()) } diff --git a/bin/tx-decoder/src/queries.rs b/bin/tx-decoder/src/queries.rs index 250bff11..7f76dc7d 100644 --- a/bin/tx-decoder/src/queries.rs +++ b/bin/tx-decoder/src/queries.rs @@ -14,10 +14,10 @@ // You should have received a copy of the GNU General Public License // along with substrate-desub. If not, see . -use sqlx::{PgConnection, FromRow}; +use anyhow::{Context, Error}; use futures::{Stream, TryStreamExt}; -use anyhow::Error; -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; +use sqlx::{FromRow, PgConnection}; /// Struct modeling data returned from database when querying for a block #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, FromRow)] @@ -32,16 +32,51 @@ pub struct BlockModel { pub ext: Vec, pub spec: i32, } -// just returns all blocks in the database of a specific spec as a stream -pub fn blocks<'a>(conn: &'a mut PgConnection, spec: i32) -> impl Stream> + 'a { - sqlx::query_as!(BlockModel, "SELECT * FROM blocks WHERE spec = $1", spec) - .fetch(conn) + +#[derive(FromRow)] +struct Count { + count: i64, +} + +/// returns how many blocks exist for a spec version. +pub async fn blocks_in_spec(conn: &mut PgConnection, spec: i32) -> Result { + Ok(sqlx::query_as::<_, Count>("SELECT COUNT(*) FROM blocks WHERE spec = $1") + .bind(spec) + .fetch_one(conn) + .await? + .count) +} + +/// returns the total amount of blocks +pub async fn total_block_count(conn: &mut PgConnection) -> Result { + Ok(sqlx::query_as::<_, Count>("SELECT COUNT(*) FROM blocks").fetch_one(conn).await?.count) +} + +/// returns how many blocks exist up to a spec version +pub async fn count_upto_spec(conn: &mut PgConnection, spec: i32) -> Result { + Ok(sqlx::query_as::<_, Count>("SELECT COUNT(*) FROM blocks WHERE spec < $1") + .bind(spec) + .fetch_one(conn) + .await? + .count) +} + +/// returns all blocks in the database of a specific spec as a stream +pub fn blocks_by_spec(conn: &mut PgConnection, spec: i32) -> impl Stream> + '_ { + sqlx::query_as!(BlockModel, "SELECT * FROM blocks WHERE spec = $1", spec).fetch(conn).map_err(Into::into) +} + +/// get a single block +pub async fn single_block(conn: &mut PgConnection, number: i32) -> Result { + sqlx::query_as!(BlockModel, "SELECT * FROM blocks WHERE block_num = $1", number) + .fetch_one(conn) + .await .map_err(Into::into) } #[derive(FromRow)] struct Meta { - pub meta: Vec + pub meta: Vec, } pub async fn metadata(conn: &mut PgConnection, spec: i32) -> Result, Error> { @@ -52,4 +87,72 @@ pub async fn metadata(conn: &mut PgConnection, spec: i32) -> Result, Err .map(|m| m.meta) } +#[derive(FromRow)] +struct Version { + pub version: i32, +} + +/// Gets all spec versions +pub async fn spec_versions(conn: &mut PgConnection) -> Result, Error> { + sqlx::query_as!(Version, "SELECT version FROM metadata") + .fetch_all(conn) + .await + .map_err(Into::into) + .map(|r| r.iter().map(|v| v.version as u32).collect()) +} + +/// returns all spec versions up to a specified version +pub async fn spec_versions_upto(conn: &mut PgConnection, upto: i32) -> Result, Error> { + sqlx::query_as!(Version, "SELECT version FROM metadata WHERE version < $1", upto) + .fetch_all(conn) + .await + .map_err(Into::into) + .map(|r| r.iter().map(|v| v.version as u32).collect()) +} + +#[derive(FromRow)] +struct PastAndPresentVersion { + pub present: i32, + pub past: Option, +} + +pub async fn past_and_present_version(conn: &mut PgConnection, spec: i32) -> Result<(Option, u32), Error> { + let version = sqlx::query_as::<_, PastAndPresentVersion>( + " + SELECT version as present, past_version as past FROM ( + SELECT version, metadata, + LAG(version, 1) OVER (ORDER BY version) as past_version + FROM metadata + ) as z WHERE version = $1;", + ) + .bind(spec) + .fetch_one(conn) + .await + .map(|v| (v.past.map(|p| p as u32), v.present as u32)) + .context(format!("Failed to get previous version of {}", spec))?; + + Ok(version) +} +#[derive(FromRow)] +struct MetaAndVersion { + pub version: i32, +} + +pub async fn version_by_block(conn: &mut PgConnection, number: u32) -> Result { + sqlx::query_as!( + MetaAndVersion, + "SELECT version FROM ( + SELECT block_num, blocks.spec, metadata.version FROM blocks, metadata + WHERE + block_num = $1 + AND + blocks.spec = metadata.version + ) as z;", + number as i32 + ) + .fetch_one(conn) + .await + .map_err(Into::into) + .map(|v| v.version) +} diff --git a/core/Cargo.toml b/core/Cargo.toml index d0716a03..7b4d9af4 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -8,14 +8,14 @@ repository = "https://github.com/paritytech/desub" [dependencies] log = "0.4" thiserror = "1.0.22" -codec = { version = "2", package = "parity-scale-codec" } -codec1 = { version = "1", package = "parity-scale-codec" } +codec = { version = "2", package = "parity-scale-codec", features = ["bit-vec"] } serde = { version = "1", features = ["derive"] } serde_json = { version = "1", features = ["preserve_order"] } onig = { version = "5.0", default-features = false } derive_more = "0.99.3" dyn-clone = "1.0" hex = "0.4" +bitvec = { version = "0.20.2", features = ["serde", "alloc"] } runtime-version = { package = "sp-version", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } pallet-democracy = { package = "pallet-democracy", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } @@ -24,7 +24,8 @@ frame-support = { package = "frame-support", git = "https://github.com/paritytec primitives = { package = "sp-core", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } runtime-primitives = { package = "sp-runtime", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } -frame-metadata = { package = "frame-metadata", git = "https://github.com/paritytech/frame-metadata", features = ["v12", "v13", "v14"] } +frame-metadata = { package = "frame-metadata", version = "14.0.0", features = ["v12", "v13", "v14"] } + runtime-metadata11 = { path = "../substrate-metadata-versions/metadatav11", package = "frame-metadatav11" } runtime-metadata10 = { path = "../substrate-metadata-versions/metadatav10", package = "frame-metadatav10" } runtime-metadata09 = { path = "../substrate-metadata-versions/metadatav9", package = "frame-metadatav9" } diff --git a/core/src/decoder.rs b/core/src/decoder.rs index 4722139b..3268937b 100644 --- a/core/src/decoder.rs +++ b/core/src/decoder.rs @@ -1,4 +1,4 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. +// Copyright 2019-2021 Parity Technologies (UK) Ltd. // This file is part of substrate-desub. // // substrate-desub is free software: you can redistribute it and/or modify @@ -33,7 +33,10 @@ pub use self::storage::{GenericStorage, StorageInfo, StorageKey, StorageKeyData, #[cfg(test)] pub use self::metadata::test_suite; -pub use self::metadata::{Metadata, MetadataError, ModuleIndex, StorageType, StorageHasher, StorageEntryModifier}; +pub use self::metadata::{ + CallMetadata, Metadata, MetadataError, ModuleIndex, ModuleMetadata, StorageEntryModifier, StorageHasher, + StorageType, +}; pub use frame_metadata::v14::StorageEntryType; use crate::{ @@ -41,8 +44,16 @@ use crate::{ substrate_types::{self, StructField, SubstrateType}, CommonTypes, RustTypeMarker, TypeDetective, }; -use codec::{Compact, CompactLen, Decode}; -use std::{collections::HashMap, convert::TryFrom}; +use bitvec::order::Lsb0 as BitOrderLsb0; +use codec::{Compact, CompactLen, Decode, Input}; +use std::{ + cell::RefCell, + collections::HashMap, + convert::TryFrom, + rc::Rc, + str::FromStr, + sync::atomic::{AtomicUsize, Ordering}, +}; type SpecVersion = u32; /// Decoder for substrate types @@ -78,7 +89,7 @@ pub enum Entry { Constant, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub enum Chain { Polkadot, Kusama, @@ -101,6 +112,212 @@ impl std::fmt::Display for Chain { } } +impl FromStr for Chain { + type Err = Error; + + fn from_str(s: &str) -> Result { + match s.to_lowercase().as_str() { + "polkadot" | "dot" => Ok(Chain::Polkadot), + "kusama" | "ksm" => Ok(Chain::Kusama), + "westend" | "wnd" => Ok(Chain::Westend), + "centrifuge" => Ok(Chain::Centrifuge), + "rococo" => Ok(Chain::Rococo), + _ => Ok(Chain::Custom(s.to_string())), + } + } +} + +#[derive(Debug)] +struct Module<'a> { + // no module, means we are probably decoding a signature. + // A signature is decoded before we know which module/call the extrinsic actually represents. + module: Option<&'a ModuleMetadata>, +} + +impl<'a> Module<'a> { + fn new(module: Option<&'a ModuleMetadata>) -> Self { + Module { module } + } + + fn set(&mut self, module: &'a ModuleMetadata) { + self.module = Some(module); + } + + fn reset(&mut self) { + self.module = None; + } + + fn name(&self) -> &'a str { + self.module.map(ModuleMetadata::name).unwrap_or("runtime") + } + + fn call(&self, index: u8) -> Result, MetadataError> { + self.module.map(|m| m.call(index)).transpose() + } +} + +#[derive(Debug)] +struct DecodeState<'a> { + module: Module<'a>, + call: Rc>>, + metadata: &'a Metadata, + cursor: AtomicUsize, + spec: SpecVersion, + data: &'a [u8], +} + +impl<'a> DecodeState<'a> { + fn new( + module: Option<&'a ModuleMetadata>, + call: Option, + metadata: &'a Metadata, + cursor: usize, + spec: SpecVersion, + data: &'a [u8], + ) -> Self { + let call = Rc::new(RefCell::new(call)); + let cursor = AtomicUsize::new(cursor); + let module = Module::new(module); + Self { module, call, metadata, cursor, spec, data } + } + + fn module_name(&'a self) -> &'a str { + self.module.name() + } + + /// Loads the module at the current index. + /// Increments the cursor by 1. + fn load_module(&mut self) -> Result<(), Error> { + log::trace!("Loading module in index {}", self.index()); + let module = self + .metadata + .module_by_index(ModuleIndex::Call(self.index())) + .map_err(|e| Error::DetailedMetaFail(e, self.cursor(), hex::encode(self.data)))?; + self.increment(); + self.module.set(module); + Ok(()) + } + + // Gets the call at the current index. Increments cursor by 1. + // Sets the call for the state. + // Panics if there is no module loaded + fn call(&self) -> Result { + let call = self.data[self.cursor.load(Ordering::Relaxed)]; + let call = self.module.call(call)?.expect("No module in state"); + self.increment(); + self.call.replace(Some(call.clone())); + Ok(self.call.borrow().as_ref().expect("Just set call").clone()) + } + + /// Interprets the version at the current byte offset. + /// Returns whether the extrinsic is signed. + fn interpret_version(&self) -> bool { + let version = self.do_index(); + let is_signed = version & 0b1000_0000 != 0; + let version = version & 0b0111_1111; + log::trace!("Extrinsic Version: {}", version); + is_signed + } + + /// Get the scale length at the current point in time. + /// Increment cursor accordingly to the length. + fn scale_length(&mut self) -> Result { + let length = Decoder::scale_length(&self.data[self.cursor.load(Ordering::Relaxed)..])?; + log::trace!("Scale Byte Length {}, actual items: {}", length.1, length.0); + self.cursor.fetch_add(length.1, Ordering::Relaxed); + Ok(length.0) + } + + fn reset(&mut self, data: &'a [u8]) { + self.data = data; + self.module.reset(); + self.call.replace(None); + self.set_cursor(0); + } + + /// Current value at cursor. + /// In other words: data[cursor] + fn index(&self) -> u8 { + self.data[self.cursor()] + } + + /// Current value at cursor (data[cursor]). + /// Increment the cursor by 1. + fn do_index(&self) -> u8 { + let number = self.data[self.cursor.load(Ordering::Relaxed)]; + self.add(1); + number + } + + /// Decode a value, automatically incrementing `cursor` + /// the correct number of bytes. + fn decode(&self) -> Result { + let input = &mut &self.data[self.cursor.load(Ordering::Relaxed)..]; + let remaining_len = input.remaining_len()?.expect("&'a u8 is always Some()"); + let ty = Decode::decode(input)?; + let after_remaining_len = input.remaining_len()?.expect("&'a u8 is always Some()"); + let inc = remaining_len - after_remaining_len; + self.add(inc); + Ok(ty) + } + + fn add(&self, inc: usize) { + self.cursor.fetch_add(inc, Ordering::Relaxed); + } + + fn increment(&self) { + self.cursor.fetch_add(1, Ordering::Relaxed); + } + + fn set_cursor(&self, new: usize) { + self.cursor.store(new, Ordering::Relaxed); + } + + fn cursor(&self) -> usize { + self.cursor.load(Ordering::Relaxed) + } + + /// Prints out a succinct debug snapshot of the current state. + fn observe(&self, line: u32) { + let module = self.module.name(); + let cursor = self.cursor.load(Ordering::Relaxed); + let value_at_cursor = &self.data[cursor]; + let data_at_cursor = &self.data[cursor..]; + + log::debug!( + "line: {}, module = {}, call = {:?}, cursor = {}, data[cursor] = {}, data[cursor..] = {:?}", + line, + module, + self.call.borrow().as_ref().map(|c| c.name()), + cursor, + value_at_cursor, + data_at_cursor, + ) + } +} + +struct ChunkedExtrinsic<'a> { + data: &'a [u8], + cursor: usize, +} + +impl<'a> ChunkedExtrinsic<'a> { + /// Create new ChunkedExtrinsic. + fn new(data: &'a [u8]) -> Self { + Self { data, cursor: 0 } + } +} + +impl<'a> Iterator for ChunkedExtrinsic<'a> { + type Item = &'a [u8]; + fn next(&mut self) -> Option<&'a [u8]> { + let (length, prefix) = Decoder::scale_length(&self.data[self.cursor..]).ok()?; + let extrinsic = &self.data[(self.cursor + prefix)..(self.cursor + length + prefix)]; + self.cursor += length + prefix; + Some(extrinsic) + } +} + impl Decoder { /// Create new Decoder with specified types pub fn new(types: impl TypeDetective + 'static, chain: Chain) -> Self { @@ -182,6 +399,7 @@ impl Decoder { }), } } + StorageType::NMap { .. } => unimplemented!(), } } @@ -208,112 +426,91 @@ impl Decoder { match &storage_info.meta.ty { StorageType::Plain(rtype) => { log::trace!("{:?}, module {}, spec {}", rtype, storage_info.module.name(), spec); - let mut cursor = 0; - let value = self.decode_single(storage_info.module.name(), spec, rtype, value, &mut cursor, false)?; + let mut state = DecodeState::new(Some(&storage_info.module), None, meta, 0, spec, value); + let value = self.decode_single(&mut state, rtype, false)?; let key = self.get_key_data(key, storage_info, &lookup_table); let storage = GenericStorage::new(key, Some(StorageValue::new(value))); Ok(storage) } StorageType::Map { value: val_rtype, unused: _unused, .. } => { - log::trace!("Resolving storage `Map`. Value: {:?}, module {}, spec {}", val_rtype, storage_info.module.name(), spec); + log::trace!( + "Resolving storage `Map`. Value: {:?}, module {}, spec {}", + val_rtype, + storage_info.module.name(), + spec + ); let key = self.get_key_data(key, storage_info, &lookup_table); - let mut cursor = 0; - let value = - self.decode_single(storage_info.module.name(), spec, val_rtype, value, &mut cursor, false)?; + let mut state = DecodeState::new(Some(&storage_info.module), None, meta, 0, spec, value); + let value = self.decode_single(&mut state, val_rtype, false)?; let storage = GenericStorage::new(key, Some(StorageValue::new(value))); Ok(storage) } StorageType::DoubleMap { value: val_rtype, .. } => { - log::trace!("Resolving storage `DoubleMap`. Value: {:?}, module {}, spec {}", value, storage_info.module.name(), spec); + log::trace!( + "Resolving storage `DoubleMap`. Value: {:?}, module {}, spec {}", + value, + storage_info.module.name(), + spec + ); let key = self.get_key_data(key, storage_info, &lookup_table); - let mut cursor = 0; - let value = - self.decode_single(storage_info.module.name(), spec, val_rtype, value, &mut cursor, false)?; + let mut state = DecodeState::new(Some(&storage_info.module), None, meta, 0, spec, value); + let value = self.decode_single(&mut state, val_rtype, false)?; let storage = GenericStorage::new(key, Some(StorageValue::new(value))); Ok(storage) } + StorageType::NMap { .. } => unimplemented!(), } } - /// Decode an extrinsic - pub fn decode_extrinsic(&self, spec: SpecVersion, data: &[u8]) -> Result { - let meta = self.versions.get(&spec).expect("Spec does not exist"); - - // first byte -> vector length - // second byte -> extrinsic version - // third byte -> Outer enum index - // fourth byte -> inner enum index (function index) - // can check if signed via a simple & too - let length = Self::scale_length(data)?; - let mut cursor: usize = length.1; - - let signature = self.decode_signature(spec, data, &mut cursor)?; - - if let Some(s) = &signature { - log::debug!("signature={}", s); + /// Decode a Vec. (Vec>) + pub fn decode_extrinsics(&self, spec: SpecVersion, data: &[u8]) -> Result, Error> { + let mut ext = Vec::new(); + let (length, prefix) = Self::scale_length(data)?; + let meta = self.versions.get(&spec).ok_or(Error::MissingSpec(spec))?; + log::trace!("Decoding {} Total Extrinsics. CALLS: {:#?}", length, meta.modules_by_call_index); + + let mut state = DecodeState::new(None, None, meta, prefix, spec, data); + for (idx, extrinsic) in ChunkedExtrinsic::new(&data[prefix..]).enumerate() { + log::trace!("Extrinsic {}:{:?}", idx, extrinsic); + state.reset(extrinsic); + ext.push(self.decode_extrinsic(&mut state)?); + log::info!("Success! {}", serde_json::to_string_pretty(&ext).unwrap()); } - let mut temp_cursor = cursor; - let module = meta - .module_by_index(ModuleIndex::Call(data[temp_cursor])) - .map_err(|e| Error::DetailedMetaFail(e, temp_cursor, hex::encode(data)))?; - temp_cursor += 1; - let call_meta = - module.call(data[temp_cursor]).map_err(|e| Error::DetailedMetaFail(e, temp_cursor, hex::encode(data)))?; - let types = self.decode_call(spec, data, &mut cursor)?; + Ok(ext) + } - Ok(GenericExtrinsic::new(signature, types, call_meta.name(), module.name().into())) + /// Decode an extrinsic + fn decode_extrinsic(&self, state: &mut DecodeState) -> Result { + let signature = if state.interpret_version() { Some(self.decode_signature(state)?) } else { None }; + + state.load_module()?; + let types = self.decode_call(state)?; + log::debug!("Finished cursor length={}", state.cursor()); + let call = state.call.borrow().as_ref().map(|c| c.name()).unwrap_or_else(|| "unknown".into()); + Ok(GenericExtrinsic::new(signature, types, call, state.module_name().into())) } /// Decode the signature part of an UncheckedExtrinsic - fn decode_signature( - &self, - spec: SpecVersion, - data: &[u8], - cursor: &mut usize, - ) -> Result, Error> { - let version = data[*cursor]; - let is_signed = version & 0b1000_0000 != 0; - let version = version & 0b0111_1111; - log::trace!("Extrinsic Version: {}", version); - *cursor += 1; - - if is_signed { - log::trace!("SIGNED EXTRINSIC"); - log::trace!("Getting signature for spec: {}, chain: {}", spec, self.chain.as_str()); - let signature = self - .types - .get_extrinsic_ty(self.chain.as_str(), spec, "signature") - .expect("Signature must not be empty"); - Ok(Some(self.decode_single("runtime", spec, signature, data, cursor, false)?)) - } else { - Ok(None) - } + fn decode_signature(&self, state: &mut DecodeState) -> Result { + log::trace!("SIGNED EXTRINSIC"); + log::trace!("Getting signature for spec: {}, chain: {}", state.spec, self.chain.as_str()); + let signature = self + .types + .get_extrinsic_ty(self.chain.as_str(), state.spec, "signature") + .expect("Signature must not be empty"); + log::trace!("Signature type is: {}", signature); + state.observe(line!()); + self.decode_single(state, signature, false) } - fn decode_call( - &self, - spec: SpecVersion, - data: &[u8], - cursor: &mut usize, - ) -> Result, Error> { - let meta = self.versions.get(&spec).expect("Spec does not exist"); - - log::trace!("data = {:?}", &data[*cursor..]); - log::trace!("cursor = {}", cursor); - let module = meta.module_by_index(ModuleIndex::Call(data[*cursor]))?; - *cursor += 1; - log::trace!("cursor = {}", cursor); - let call_meta = module.call(data[*cursor])?; - *cursor += 1; - log::trace!("cursor = {}", cursor); - log::trace!("data = {:X?}", &data[*cursor..]); - - // TODO: tuple of argument name -> value + fn decode_call(&self, state: &mut DecodeState) -> Result, Error> { let mut types: Vec<(String, SubstrateType)> = Vec::new(); - for arg in call_meta.arguments() { - log::trace!("arg = {:?}", arg); - let val = self.decode_single(module.name(), spec, &arg.ty, data, cursor, false)?; + let call = state.call()?; + for arg in call.arguments() { + state.observe(line!()); + log::trace!("Decoding {:?} for call {}", &arg.ty, call); + let val = self.decode_single(state, &arg.ty, false)?; types.push((arg.name.to_string(), val)); } Ok(types) @@ -328,35 +525,35 @@ impl Decoder { #[track_caller] fn decode_single( &self, - module: &str, - spec: SpecVersion, + state: &mut DecodeState, ty: &RustTypeMarker, - data: &[u8], - cursor: &mut usize, is_compact: bool, ) -> Result { let ty = match ty { RustTypeMarker::TypePointer(v) => { log::trace!("Resolving: {}", v); - if let Some(t) = self.decode_sub_type(spec, v, data, cursor, is_compact)? { + if let Some(t) = self.decode_sub_type(state, v, is_compact)? { t } else { - let new_type = self.types.get(self.chain.as_str(), spec, module, v).ok_or_else(|| { - Error::from(format!( - "Name Resolution Failure: module={}, v={}, spec={}, chain={}", - module, - v, - spec, - self.chain.as_str() - )) - })?; + let new_type = + self.types.get(self.chain.as_str(), state.spec, state.module_name(), v).ok_or_else(|| { + Error::from(format!( + "Name Resolution Failure: module={}, v={}, spec={}, chain={}", + state.module_name(), + v, + state.spec, + self.chain.as_str() + )) + })?; log::trace!("Resolved {:?}", new_type); - let mut saved_cursor = *cursor; - let resolved = self.decode_single(module, spec, new_type, data, cursor, is_compact); + let saved_cursor = state.cursor(); + let resolved = self.decode_single(state, new_type, is_compact); if resolved.is_err() { - if let Some(fallback) = self.types.try_fallback(self.chain.as_str(), spec, module, v) { - return Ok(self.decode_single(module, spec, fallback, data, &mut saved_cursor, is_compact)?); + if let Some(fallback) = self.types.try_fallback(state.module_name(), v) { + log::trace!("Falling back to type: {}", fallback); + state.set_cursor(saved_cursor); + return self.decode_single(state, fallback, is_compact); } } resolved? @@ -364,51 +561,47 @@ impl Decoder { } RustTypeMarker::Unit(u) => SubstrateType::Unit(u.to_string()), RustTypeMarker::Struct(v) => { - log::trace!("Struct::cursor = {:?}", cursor); - let ty = self.decode_structlike(v, module, spec, data, cursor, is_compact)?; + log::trace!("Struct::cursor = {:?}", state.cursor); + let ty = self.decode_structlike(v, state, is_compact)?; SubstrateType::Struct(ty) } - // TODO: test RustTypeMarker::Set(v) => { - log::trace!("Set::cursor = {}", *cursor); + log::trace!("Set::cursor = {}", state.cursor()); // a set item must be an u8 // can decode this right away - let index = data[*cursor]; - *cursor += 1; + let index = state.do_index(); SubstrateType::Set(v[index as usize].clone()) } RustTypeMarker::Tuple(v) => { - log::trace!("Tuple::cursor={}", *cursor); + log::trace!("Tuple::cursor={}", state.cursor()); let ty = v .iter() - .map(|v| self.decode_single(module, spec, v, data, cursor, is_compact)) + .map(|v| self.decode_single(state, v, is_compact)) .collect::, Error>>(); SubstrateType::Composite(ty?) } RustTypeMarker::Enum(v) => { - log::trace!("Enum::cursor={}", *cursor); - let index = data[*cursor]; - *cursor += 1; + log::trace!("Enum::cursor={}", state.cursor()); + state.observe(line!()); + let index = state.do_index(); let variant = &v[index as usize]; - let value = variant.value - .as_ref() - .map(|v| self.decode_single(module, spec, &v, data, cursor, is_compact)) - .transpose()?; - + let value = variant.value.as_ref().map(|v| self.decode_single(state, v, is_compact)).transpose()?; + log::debug!("Enum: {:?}", value); SubstrateType::Enum(substrate_types::EnumField { name: variant.name.clone(), - value: value.map(|v| Box::new(v)), + value: value.map(Box::new), }) } RustTypeMarker::Array { size, ty } => { - log::trace!("Array::cursor={}", *cursor); + log::trace!("Array::cursor={}", state.cursor()); let mut decoded_arr = Vec::with_capacity(*size); - if *size == 0_usize { - log::trace!("Returning Empty Vector"); + + if *size == 0 { + log::trace!("Returning Empty Array"); return Ok(SubstrateType::Composite(Vec::new())); } else { for _ in 0..*size { - decoded_arr.push(self.decode_single(module, spec, ty, data, cursor, is_compact)?) + decoded_arr.push(self.decode_single(state, ty, is_compact)?) } } // rely on cursor increments in sub-types (U32/substrate specific types) @@ -416,31 +609,28 @@ impl Decoder { } RustTypeMarker::Std(v) => match v { CommonTypes::Vec(v) => { - log::trace!("Vec::cursor={}", *cursor); - let length = Self::scale_length(&data[*cursor..])?; - *cursor += length.1; - // we can just decode this as an "array" now - self.decode_single( - module, - spec, - &RustTypeMarker::Array { size: length.0, ty: v.clone() }, - data, - cursor, - is_compact, - )? + log::trace!("Vec::cursor={}", state.cursor()); + let length = state.scale_length()?; + let mut vec = Vec::new(); + if length == 0 { + return Ok(SubstrateType::Composite(Vec::new())); + } else { + for _ in 0..length { + state.observe(line!()); + let decoded = self.decode_single(state, v, is_compact)?; + vec.push(decoded); + } + } + SubstrateType::Composite(vec) } CommonTypes::Option(v) => { - log::trace!("Option::cursor={}", *cursor); - match data[*cursor] { + log::trace!("Option::cursor={}", state.cursor()); + match state.do_index() { // None - 0x00 => { - *cursor += 1; - SubstrateType::Option(Box::new(None)) - } + 0x00 => SubstrateType::Option(Box::new(None)), // Some 0x01 => { - *cursor += 1; - let ty = self.decode_single(module, spec, v, data, cursor, is_compact)?; + let ty = self.decode_single(state, v, is_compact)?; SubstrateType::Option(Box::new(Some(ty))) } _ => { @@ -449,18 +639,16 @@ impl Decoder { } } CommonTypes::Result(v, e) => { - log::trace!("Result::cursor={}", *cursor); - match data[*cursor] { + log::trace!("Result::cursor={}", state.cursor()); + match state.do_index() { // Ok 0x00 => { - *cursor += 1; - let ty = self.decode_single(module, spec, v, data, cursor, is_compact)?; + let ty = self.decode_single(state, v, is_compact)?; SubstrateType::Result(Box::new(Ok(ty))) } // Err 0x01 => { - *cursor += 1; - let ty = self.decode_single(module, spec, e, data, cursor, is_compact)?; + let ty = self.decode_single(state, e, is_compact)?; SubstrateType::Result(Box::new(Err(ty))) } _ => { @@ -468,154 +656,110 @@ impl Decoder { } } } - // TODO: test CommonTypes::Compact(v) => { - log::trace!("Compact::cursor={}", cursor); - self.decode_single(module, spec, v, data, cursor, true)? + log::trace!("COMPACT SWITCHED! Compact::cursor={}", state.cursor()); + self.decode_single(state, v, true)? } }, RustTypeMarker::Generic(outer, _) => { log::trace!("Generic Type"); // disregard 'inner' type of a generic - self.decode_single(module, spec, outer, data, cursor, is_compact)? - }, + self.decode_single(state, outer, is_compact)? + } RustTypeMarker::Number => { panic!("number decoding not possible"); - }, + } RustTypeMarker::U8 => { let num: u8 = if is_compact { - let num: Compact = Decode::decode(&mut &data[*cursor..])?; - *cursor += Compact::compact_len(&u8::from(num)); + let num: Compact = state.decode()?; num.into() } else { - let num: u8 = Decode::decode(&mut &data[*cursor..])?; - *cursor += 1; + let num: u8 = state.decode()?; num }; num.into() } RustTypeMarker::U16 => { + log::trace!("Decoding u16"); let num: u16 = if is_compact { - let num: Compact = Decode::decode(&mut &data[*cursor..])?; - *cursor += Compact::compact_len(&u16::from(num)); + let num: Compact = state.decode()?; num.into() } else { - let num: u16 = Decode::decode(&mut &data[*cursor..])?; - *cursor += 2; + let num: u16 = state.decode()?; num }; num.into() } RustTypeMarker::U32 => { - log::trace!("{:?}", &data[*cursor..]); + log::trace!("Decoding u32"); + state.observe(line!()); let num: u32 = if is_compact { - let num: Compact = Decode::decode(&mut &data[*cursor..])?; - let len = Compact::compact_len(&u32::from(num)); - log::trace!("Compact len: {}", len); - *cursor += len; + let num: Compact = state.decode()?; num.into() } else { - let num: u32 = Decode::decode(&mut &data[*cursor..])?; - *cursor += 4; + let num: u32 = state.decode()?; + log::trace!("u32:{}", num); num }; num.into() } RustTypeMarker::U64 => { - let num: u64 = if is_compact { - let num: Compact = Decode::decode(&mut &data[*cursor..])?; - *cursor += Compact::compact_len(&u64::from(num)); + log::trace!("Decoding u64"); + let num = if is_compact { + let num: Compact = state.decode()?; num.into() } else { - let num: u64 = Decode::decode(&mut &data[*cursor..])?; - *cursor += 8; + let num: u64 = state.decode()?; num }; num.into() } RustTypeMarker::U128 => { - log::trace!("data = {:?}", &data[*cursor..]); - let num: u128 = if is_compact { - let num: Compact = Decode::decode(&mut &data[*cursor..])?; - *cursor += Compact::compact_len(&u128::from(num)); + log::trace!("Decoding u128"); + state.observe(line!()); + let num = if is_compact { + let num: Compact = state.decode()?; num.into() } else { - let num: u128 = Decode::decode(&mut &data[*cursor..])?; - *cursor += 16; + let num: u128 = state.decode()?; num }; num.into() } - RustTypeMarker::USize => { - panic!("usize decoding not possible!") - /* let size = std::mem::size_of::(); - let num: usize = - Decode::decode(&mut &data[*cursor..=*cursor+size])?; - *cursor += std::mem::size_of::(); - num.into() - */ - } RustTypeMarker::I8 => { - let num: i8 = if is_compact { unimplemented!() } else { Decode::decode(&mut &data[*cursor..])? }; - *cursor += 1; + log::trace!("Decoding i8"); + let num: i8 = if is_compact { unimplemented!() } else { state.decode()? }; num.into() } RustTypeMarker::I16 => { - let num: i16 = if is_compact { unimplemented!() } else { Decode::decode(&mut &data[*cursor..])? }; - *cursor += 2; + log::trace!("Decoding i16"); + let num: i16 = if is_compact { unimplemented!() } else { state.decode()? }; num.into() } RustTypeMarker::I32 => { - let num: i32 = if is_compact { unimplemented!() } else { Decode::decode(&mut &data[*cursor..])? }; - *cursor += 4; + log::trace!("Decoding i32"); + let num: i32 = if is_compact { unimplemented!() } else { state.decode()? }; num.into() } RustTypeMarker::I64 => { + log::trace!("Decoding i64"); let num: i64 = if is_compact { // let num: Compact = Decode::decode(&mut &data[*cursor..*cursor+8])?; // num.into() unimplemented!() } else { - Decode::decode(&mut &data[*cursor..])? + state.decode()? }; - *cursor += 8; num.into() } RustTypeMarker::I128 => { - let num: i128 = if is_compact { unimplemented!() } else { Decode::decode(&mut &data[*cursor..])? }; - *cursor += 16; - num.into() - } - RustTypeMarker::ISize => { - panic!("isize decoding impossible!") - /* - let idx = std::mem::size_of::(); - let num: isize = - Decode::decode(&mut &data[*cursor..=*cursor + idx])?; - *cursor += std::mem::size_of::(); - num.into() - */ - } - RustTypeMarker::F32 => { - /* - let num: f32 = Decode::decode(&mut &data[*cursor..=*cursor + 4])?; - *cursor += 5; - num.into() - */ - panic!("f32 decoding impossible!"); - } - RustTypeMarker::F64 => { - /* - let num: f64 = Decode::decode(&mut &data[*cursor..=*cursor + 8])?; - *cursor += 9; + log::trace!("Decoding i128"); + let num: i128 = if is_compact { unimplemented!() } else { state.decode()? }; num.into() - */ - panic!("f64 decoding impossible!"); } - RustTypeMarker::String => unimplemented!(), RustTypeMarker::Bool => { - let boo: bool = Decode::decode(&mut &data[*cursor..=*cursor])?; - *cursor += 1; + log::trace!("Decoding boolean"); + let boo: bool = state.decode()?; // . - . // ( o o ) // | 0 \ @@ -636,75 +780,60 @@ impl Decoder { /// These types override anything defined in JSON /// Tries to decode a type that is native to substrate /// for example, H256. Returns none if type cannot be deduced - /// Supported types: - /// - H256 - /// - H512 - // TODO: test this with the substrate types used fn decode_sub_type( &self, - spec: SpecVersion, + state: &mut DecodeState, ty: &str, - data: &[u8], - cursor: &mut usize, is_compact: bool, ) -> Result, Error> { match ty { // checks if the metadata includes types for the SignedExtensions // If not defaults to whatever is in extrinsics.json "SignedExtra" => { - let meta = self.versions.get(&spec).ok_or(format!("Metadata for spec {} not found", spec))?; + log::trace!("Decoding SignedExtra"); + let meta = + self.versions.get(&state.spec).ok_or(format!("Metadata for spec {} not found", state.spec))?; if let Some(extensions) = meta.signed_extensions() { let extensions = RustTypeMarker::Tuple(extensions.to_vec()); - self.decode_single("", spec, &extensions, data, cursor, is_compact).map(Option::Some) + self.decode_single(state, &extensions, is_compact).map(Option::Some) } else { let ty = self .types - .get_extrinsic_ty(self.chain.as_str(), spec, "SignedExtra") + .get_extrinsic_ty(self.chain.as_str(), state.spec, "SignedExtra") .ok_or_else(|| Error::from("Could not find type `SignedExtra`"))?; - self.decode_single("", spec, ty, data, cursor, is_compact).map(Option::Some) + self.decode_single(state, ty, is_compact).map(Option::Some) } } // identity info may be added to in the future "IdentityInfo" => { + log::trace!("Decoding IdentityInfo"); let additional = self.decode_single( - "identity", - spec, + state, &RustTypeMarker::Std(CommonTypes::Vec(Box::new(RustTypeMarker::TypePointer( "IdentityInfoAdditional".to_string(), )))), - data, - cursor, is_compact, )?; - let display = self - .decode_sub_type(spec, "Data", data, cursor, is_compact)? - .ok_or_else(|| Error::from("Data not resolved"))?; - let legal = self - .decode_sub_type(spec, "Data", data, cursor, is_compact)? - .ok_or_else(|| Error::from("Data not resolved"))?; - let web = self - .decode_sub_type(spec, "Data", data, cursor, is_compact)? - .ok_or_else(|| Error::from("Data not resolved"))?; - let riot = self - .decode_sub_type(spec, "Data", data, cursor, is_compact)? - .ok_or_else(|| Error::from("Data not resolved"))?; - let email = self - .decode_sub_type(spec, "Data", data, cursor, is_compact)? - .ok_or_else(|| Error::from("Data not resolved"))?; + let display = + self.decode_sub_type(state, "Data", is_compact)?.ok_or_else(|| Error::from("Data not resolved"))?; + let legal = + self.decode_sub_type(state, "Data", is_compact)?.ok_or_else(|| Error::from("Data not resolved"))?; + let web = + self.decode_sub_type(state, "Data", is_compact)?.ok_or_else(|| Error::from("Data not resolved"))?; + let riot = + self.decode_sub_type(state, "Data", is_compact)?.ok_or_else(|| Error::from("Data not resolved"))?; + let email = + self.decode_sub_type(state, "Data", is_compact)?.ok_or_else(|| Error::from("Data not resolved"))?; let pgp_fingerprint = self.decode_single( - "identity", - spec, + state, &RustTypeMarker::Std(CommonTypes::Option(Box::new(RustTypeMarker::TypePointer( "H160".to_string(), )))), - data, - cursor, is_compact, )?; - let image = self - .decode_sub_type(spec, "Data", data, cursor, is_compact)? - .ok_or_else(|| Error::from("Data not resolved"))?; - let twitter = self.decode_sub_type(spec, "Data", data, cursor, is_compact); + let image = + self.decode_sub_type(state, "Data", is_compact)?.ok_or_else(|| Error::from("Data not resolved"))?; + let twitter = self.decode_sub_type(state, "Data", is_compact); Ok(Some(SubstrateType::Struct(vec![ StructField::new(Some("additional"), additional), @@ -722,69 +851,65 @@ impl Decoder { ]))) } "Data" => { - log::trace!("Data::cursor={}", *cursor); - let identity_data: substrate_types::Data = Decode::decode(&mut &data[*cursor..])?; - match &identity_data { - substrate_types::Data::None => (), - substrate_types::Data::Raw(v) => *cursor += v.len(), - _ => *cursor += 32, - }; - // for the enum byte - *cursor += 1; + log::trace!("Decoding Data"); + let identity_data: substrate_types::Data = state.decode()?; Ok(Some(SubstrateType::Data(identity_data))) } + "IdentityFields" => { + log::trace!("Decoding Identity Fields"); + // identity field are just bitflags that can be interpreted by a frontend + let field: u64 = state.decode()?; + Ok(Some(SubstrateType::IdentityField(field))) + } + "BitVec" => { + log::trace!("Decoding BitVec"); + let bit_vec: bitvec::vec::BitVec = state.decode()?; + Ok(Some(SubstrateType::BitVec(bit_vec))) + } "Call" | "GenericCall" => { - let types = self.decode_call(spec, data, cursor)?; + log::trace!("Decoding Call | GenericCall"); + state.load_module()?; + let types = self.decode_call(state)?; + log::trace!("Call is {:?}", types); Ok(Some(SubstrateType::Call(types))) } "GenericVote" => { - let vote: pallet_democracy::Vote = Decode::decode(&mut &data[*cursor..])?; - // a vote is one byte - *cursor += 1; + log::trace!("Decoding GenericVote"); + let vote: pallet_democracy::Vote = state.decode()?; Ok(Some(SubstrateType::GenericVote(vote))) } // Old Address Format for backwards-compatibility https://github.com/paritytech/substrate/pull/7380 "Lookup" | "GenericAddress" | "GenericLookupSource" | "GenericAccountId" => { - // a specific type that is ::Lookup concatenated to just 'Lookup' - log::trace!("cursor={}, data length={}", cursor, data.len()); - - let val: substrate_types::Address = decode_old_address(data, cursor)?; + log::trace!("Decoding Lookup | GenericAddress | GenericLookupSource | GenericAccountId"); + state.observe(line!()); + let val: substrate_types::Address = decode_old_address(state)?; + log::trace!("Decode Successful {:?}", &val); Ok(Some(SubstrateType::Address(val))) } + "::Source" => { + log::trace!("Decoding ::Source"); + state.observe(line!()); + Ok(Some(self.decode_single(state, &RustTypeMarker::TypePointer("LookupSource".into()), is_compact)?)) + } "GenericMultiAddress" => { - let val: substrate_types::Address = Decode::decode(&mut &data[*cursor..])?; - let cursor_offset = match &val { - substrate_types::Address::Id(_) => 32, - substrate_types::Address::Index(_) => 1, - substrate_types::Address::Raw(v) => v.len(), - substrate_types::Address::Address32(_) => 32, - substrate_types::Address::Address20(_) => 20, - }; - *cursor += cursor_offset; + let val: substrate_types::Address = state.decode()?; + log::trace!("Address: {:?}", val); Ok(Some(SubstrateType::Address(val))) } "Era" => { - log::trace!("ERA DATA: {:X?}", &data[*cursor..]); - let val: runtime_primitives::generic::Era = Decode::decode(&mut &data[*cursor..])?; + log::trace!("ERA DATA: {:X?}", &state.data[state.cursor()]); + let val: runtime_primitives::generic::Era = state.decode()?; log::trace!("Resolved Era: {:?}", val); - match val { - // although phase and period are both u64, era is Encoded - // in only two bytes - runtime_primitives::generic::Era::Immortal => *cursor += 1, - runtime_primitives::generic::Era::Mortal(_, _) => *cursor += 2, - }; Ok(Some(SubstrateType::Era(val))) } "H256" => { - let val: primitives::H256 = Decode::decode(&mut &data[*cursor..])?; - *cursor += 32; + let val: primitives::H256 = state.decode()?; Ok(Some(SubstrateType::H256(val))) } "H512" => { - let val: primitives::H512 = Decode::decode(&mut &data[*cursor..])?; + let val: primitives::H512 = state.decode()?; log::trace!("H512: {}", hex::encode(val.as_bytes())); - *cursor += 64; Ok(Some(SubstrateType::H512(val))) } _ => Ok(None), @@ -797,28 +922,24 @@ impl Decoder { /// in the encoded data fn scale_length(mut data: &[u8]) -> Result<(usize, usize), Error> { // alternative to `DecodeLength` trait, to avoid casting from a trait - let u32_length = u32::from(Compact::::decode(&mut data)?); - let length_of_prefix: usize = Compact::compact_len(&u32_length); - let usize_length = - usize::try_from(u32_length).map_err(|_| Error::from("Failed convert decoded size into usize."))?; - Ok((usize_length, length_of_prefix)) + let length = u32::from(Compact::::decode(&mut data)?); + let prefix = Compact::::compact_len(&length); + let length = usize::try_from(length).map_err(|_| Error::from("Failed convert decoded size into usize."))?; + Ok((length, prefix)) } - /// internal api to decode a vector of struct IdentityFields + /// internal api to decode a vector of struct fn decode_structlike( &self, fields: &[crate::StructField], - module: &str, - spec: SpecVersion, - data: &[u8], - cursor: &mut usize, + state: &mut DecodeState, is_compact: bool, ) -> Result, Error> { fields .iter() .map(|field| { log::trace!("name={:?}, field={}", field.name, field.ty); - let ty = self.decode_single(module, spec, &field.ty, data, cursor, is_compact)?; + let ty = self.decode_single(state, &field.ty, is_compact)?; Ok(StructField { name: Some(field.name.clone()), ty }) }) .collect::, Error>>() @@ -827,7 +948,7 @@ impl Decoder { /// Decodes old address pre-refactor (https://github.com/paritytech/substrate/pull/7380) /// and converts it to a MultiAddress, where "old" here means anything before v0.8.26 or 26/2026/46 on polkadot/kusama/westend respectively. -fn decode_old_address(data: &[u8], cursor: &mut usize) -> Result { +fn decode_old_address(state: &DecodeState) -> Result { /// Kept around for backwards-compatibility with old address struct fn need_more_than(a: T, b: T) -> Result { if a < b { @@ -838,33 +959,36 @@ fn decode_old_address(data: &[u8], cursor: &mut usize) -> Result { inc = 0; substrate_types::Address::Index(x as u32) } 0xfc => { inc = 2; - substrate_types::Address::Index(need_more_than(0xef, u16::decode(&mut &data[(*cursor + 1)..])?)? as u32) + substrate_types::Address::Index( + need_more_than(0xef, u16::decode(&mut &state.data[(state.cursor())..])?)? as u32 + ) } 0xfd => { inc = 4; - substrate_types::Address::Index(need_more_than(0xffff, u32::decode(&mut &data[(*cursor + 1)..])?)?) + substrate_types::Address::Index(need_more_than(0xffff, u32::decode(&mut &state.data[(state.cursor())..])?)?) } 0xfe => { inc = 8; substrate_types::Address::Index(need_more_than( 0xffff_ffff_u32, - Decode::decode(&mut &data[(*cursor + 1)..])?, + Decode::decode(&mut &state.data[(state.cursor())..])?, )?) } 0xff => { inc = 32; - substrate_types::Address::Id(Decode::decode(&mut &data[(*cursor + 1)..])?) + substrate_types::Address::Id(Decode::decode(&mut &state.data[(state.cursor())..])?) } _ => return Err(Error::Fail("Invalid Address".to_string())), }; - *cursor += inc + 1; // +1 for byte 0x00-0xff + state.add(inc); Ok(addr) } @@ -872,8 +996,9 @@ fn decode_old_address(data: &[u8], cursor: &mut usize) -> Result Option<&RustTypeMarker> { + fn try_fallback(&self, _module: &str, _ty: &str) -> Option<&RustTypeMarker> { None } @@ -911,7 +1036,7 @@ mod tests { let mut decoder = Decoder::new(GenericTypes, Chain::Kusama); let rt_version = test_suite::mock_runtime(0); let meta = meta_test_suite::test_metadata(); - decoder.register_version(rt_version.spec_version.clone(), &meta); + decoder.register_version(rt_version.spec_version, &meta); let _other_meta = decoder.get_version_metadata(rt_version.spec_version); assert_eq!(Some(&meta), _other_meta.clone()) } @@ -930,10 +1055,11 @@ mod tests { ( $v: expr, $x:expr, $r: expr) => {{ let val = $v.encode(); let decoder = Decoder::new(GenericTypes, Chain::Kusama); - let res = decoder.decode_single("", 1031, &$x, val.as_slice(), &mut 0, false).unwrap(); - + let meta = meta_test_suite::test_metadata(); + let mut state = DecodeState::new(None, None, &meta, 0, 1031, val.as_slice()); + let res = decoder.decode_single(&mut state, &$x, false).unwrap(); assert_eq!($r, res) - }}; + }}; } #[test] @@ -1097,14 +1223,8 @@ mod tests { decode_test!( val, RustTypeMarker::Enum(vec![ - RustEnumField::new( - "Zoo".into(), - Some(RustTypeMarker::TypePointer("TestStruct".into())), - ), - RustEnumField::new( - "Wraith".into(), - Some(RustTypeMarker::TypePointer("TestStruct".into())), - ), + RustEnumField::new("Zoo".into(), Some(RustTypeMarker::TypePointer("TestStruct".into())),), + RustEnumField::new("Wraith".into(), Some(RustTypeMarker::TypePointer("TestStruct".into())),), ]), SubstrateType::Enum(EnumField::new("Wraith".into(), Some(Box::new(SubstrateType::I128(0x1337))))) ); @@ -1143,18 +1263,27 @@ mod tests { ])), ), ]), - SubstrateType::Enum( - EnumField::new( - "Wraith".into(), - Some(Box::new(SubstrateType::Struct(vec![ - StructField { - name: Some("name".into()), - ty: SubstrateType::Composite(vec![SubstrateType::U16(0x13), SubstrateType::U16(0x37)]) - }, - StructField { name: Some("id".into()), ty: SubstrateType::U64(15) } - ]))) - ) - ) + SubstrateType::Enum(EnumField::new( + "Wraith".into(), + Some(Box::new(SubstrateType::Struct(vec![ + StructField { + name: Some("name".into()), + ty: SubstrateType::Composite(vec![SubstrateType::U16(0x13), SubstrateType::U16(0x37)]) + }, + StructField { name: Some("id".into()), ty: SubstrateType::U64(15) } + ]))) + )) ); } + + #[test] + fn should_chunk_extrinsic() { + let test = vec![vec![0u8, 1, 2], vec![3, 4, 5], vec![6, 7, 8]]; + let encoded: Vec = test.encode(); + let (_length, prefix) = Decoder::scale_length(encoded.as_slice()).unwrap(); // get the overall length first + let mut chunked = ChunkedExtrinsic::new(&encoded[prefix..]); + assert_eq!(chunked.next(), Some(vec![0, 1, 2].as_slice())); + assert_eq!(chunked.next(), Some(vec![3, 4, 5].as_slice())); + assert_eq!(chunked.next(), Some(vec![6, 7, 8].as_slice())); + } } diff --git a/core/src/decoder/metadata.rs b/core/src/decoder/metadata.rs index 2c64aa6c..2bd76a7c 100644 --- a/core/src/decoder/metadata.rs +++ b/core/src/decoder/metadata.rs @@ -33,21 +33,19 @@ mod version_09; mod version_10; mod version_11; mod version_12; -mod versions; +mod version_13; -pub use frame_metadata::decode_different::DecodeDifferent; +pub use frame_metadata::{decode_different::DecodeDifferent, RuntimeMetadata, RuntimeMetadataPrefixed}; use super::storage::{StorageInfo, StorageLookupTable}; use crate::RustTypeMarker; use codec::{Decode, Encode, EncodeAsRef, HasCompact}; -use codec1::Decode as Decode1; -// use codec411::Decode as OldDecode; -use serde::{Serialize, Deserialize}; use primitives::{storage::StorageKey, twox_128}; +use serde::{Deserialize, Serialize}; use std::{ collections::{HashMap, HashSet}, - convert::TryInto, + convert::{TryFrom, TryInto}, fmt, marker::PhantomData, str::FromStr, @@ -98,11 +96,11 @@ pub enum ModuleIndex { /// Metadata struct encompassing calls, storage, and events pub struct Metadata { /// Hashmap of Modules (name -> module-specific metadata) - modules: HashMap>, + modules: HashMap>, /// modules by their index in the event enum modules_by_event_index: HashMap, /// modules by their index in the Call Enum - modules_by_call_index: HashMap, + pub modules_by_call_index: HashMap, /// Optional extrinsic metadata. Only chains which use meta /// version 11+ support this. extrinsics: Option, @@ -126,7 +124,7 @@ impl From<&Metadata> for Metadata { } } -impl Metadata { +impl<'a> Metadata { /// Create a new Metadata type from raw encoded bytes /// /// # Panics @@ -145,33 +143,28 @@ impl Metadata { let version = bytes[4]; match version { - /* 0x07 => { - let meta: runtime_metadata07::RuntimeMetadataPrefixed = - OldDecode::decode(&mut &*bytes).expect("Decode failed"); - meta.try_into().expect("Conversion failed") - } */ 0x08 => { log::debug!("Metadata V8"); let meta: runtime_metadata08::RuntimeMetadataPrefixed = - Decode1::decode(&mut &*bytes).expect("Decode failed"); + Decode::decode(&mut &*bytes).expect("Decode failed"); meta.try_into().expect("Conversion failed") } 0x09 => { log::debug!("Metadata V9"); let meta: runtime_metadata09::RuntimeMetadataPrefixed = - Decode1::decode(&mut &*bytes).expect("Decode Failed"); + Decode::decode(&mut &*bytes).expect("Decode Failed"); meta.try_into().expect("Conversion Failed") } 0xA => { log::debug!("Metadata V10"); let meta: runtime_metadata10::RuntimeMetadataPrefixed = - Decode1::decode(&mut &*bytes).expect("Decode failed"); + Decode::decode(&mut &*bytes).expect("Decode failed"); meta.try_into().expect("Conversion failed") } 0xB => { log::debug!("Metadata V11"); let meta: runtime_metadata11::RuntimeMetadataPrefixed = - Decode1::decode(&mut &*bytes).expect("Decode failed"); + Decode::decode(&mut &*bytes).expect("Decode failed"); meta.try_into().expect("Conversion failed") } 0xC => { @@ -179,19 +172,19 @@ impl Metadata { let meta: frame_metadata::RuntimeMetadataPrefixed = Decode::decode(&mut &*bytes).expect("Decode failed"); meta.try_into().expect("Conversion failed") - }, + } 0xD => { log::debug!("Metadata V13"); let meta: frame_metadata::RuntimeMetadataPrefixed = - Decode::decode(&mut &bytes[..]).expect("decode failed"); + Decode::decode(&mut &*bytes).expect("decode failed"); meta.try_into().expect("Conversion failed") - }, + } 0xE => { log::debug!("Metadata V14"); let meta: frame_metadata::RuntimeMetadataPrefixed = - Decode::decode(&mut &bytes[..]).expect("decode failed"); + Decode::decode(&mut &*bytes).expect("decode failed"); meta.try_into().expect("Conversion failed") - }, + } /* TODO remove panics */ e => panic!("substrate metadata version {} is unknown, invalid or unsupported", e), } @@ -233,21 +226,21 @@ impl Metadata { } /// get a module by it's index - pub fn module_by_index(&self, module_index: ModuleIndex) -> Result, MetadataError> { + pub fn module_by_index(&'a self, module_index: ModuleIndex) -> Result<&'a ModuleMetadata, MetadataError> { Ok(match module_index { ModuleIndex::Call(i) => { let name = self .modules_by_call_index .get(&i) .ok_or(MetadataError::ModuleIndexNotFound(ModuleIndex::Call(i)))?; - self.modules.get(name).ok_or_else(|| MetadataError::ModuleNotFound(name.to_string()))?.clone() + self.modules.get(name).ok_or_else(|| MetadataError::ModuleNotFound(name.to_string()))? } ModuleIndex::Event(i) => { let name = self .modules_by_event_index .get(&i) .ok_or(MetadataError::ModuleIndexNotFound(ModuleIndex::Event(i)))?; - self.modules.get(name).ok_or_else(|| MetadataError::ModuleNotFound(name.to_string()))?.clone() + self.modules.get(name).ok_or_else(|| MetadataError::ModuleNotFound(name.to_string()))? } ModuleIndex::Storage(_) => { // TODO remove panics @@ -462,12 +455,17 @@ pub enum StorageType { value: RustTypeMarker, key2_hasher: StorageHasher, }, + NMap { + keys: Vec, + hashers: Vec, + value: RustTypeMarker, + }, } #[derive(Clone, Debug, PartialEq, Eq, Encode, Decode)] pub enum StorageEntryModifier { Optional, - Default + Default, } #[derive(Clone, Debug, PartialEq)] @@ -585,6 +583,19 @@ impl EventArg { } } +impl TryFrom for Metadata { + type Error = Error; + + fn try_from(metadata: RuntimeMetadataPrefixed) -> Result { + match metadata.1 { + RuntimeMetadata::V12(meta) => meta.try_into(), + RuntimeMetadata::V13(meta) => meta.try_into(), + RuntimeMetadata::V14(_meta) => unimplemented!(), + _ => Err(Error::InvalidVersion), + } + } +} + #[derive(Error, Debug)] pub enum Error { #[error("Invalid Prefix")] diff --git a/core/src/decoder/metadata/test_suite.rs b/core/src/decoder/metadata/test_suite.rs index f33bb5a2..080341a7 100644 --- a/core/src/decoder/metadata/test_suite.rs +++ b/core/src/decoder/metadata/test_suite.rs @@ -72,7 +72,7 @@ fn storage_mock() -> HashMap { let mut map = HashMap::new(); let moment = RustTypeMarker::TypePointer("T::Moment".to_string()); let precision = RustTypeMarker::U32; - let usize_t = RustTypeMarker::USize; + let u64_t = RustTypeMarker::U64; map.insert( "TestStorage0".to_string(), @@ -90,7 +90,7 @@ fn storage_mock() -> HashMap { StorageMetadata { prefix: "TestStorage1".to_string(), modifier: StorageEntryModifier::Default, - ty: StorageType::Plain(usize_t), + ty: StorageType::Plain(u64_t), default: vec![0, 0, 0, 0, 0, 0, 0, 0], documentation: vec!["Some Kind of docs 2".to_string()], }, @@ -150,14 +150,6 @@ fn call_mock() -> HashMap { }], }, ); - map.insert( - "TestCall3".to_string(), - CallMetadata { - name: "foo_function3".to_string(), - index: 0, - arguments: vec![CallArgMetadata { name: "foo_arg".to_string(), ty: RustTypeMarker::F32 }], - }, - ); map } diff --git a/core/src/decoder/metadata/version_07.rs b/core/src/decoder/metadata/version_07.rs deleted file mode 100644 index 3c0a1956..00000000 --- a/core/src/decoder/metadata/version_07.rs +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// This file is part of substrate-desub. -// -// substrate-desub is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// substrate-desub is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with substrate-desub. If not, see . - -// taken directly and modified from substrate-subxt: -// https://github.com/paritytech/substrate-subxt - -use super::{ - CallArgMetadata, CallMetadata, Error, EventArg, Metadata, ModuleEventMetadata, - ModuleMetadata, StorageMetadata, -}; -use crate::regex; -use runtime_metadata07::{ - DecodeDifferent, RuntimeMetadata, RuntimeMetadataPrefixed, StorageEntryModifier, - StorageEntryType, StorageHasher, META_RESERVED, -}; - -use std::{ - collections::{HashMap, HashSet}, - convert::TryFrom, -}; - -type DecodeDifferentStr = DecodeDifferent<&'static str, String>; -type LatestDecodeDifferentStr = - runtime_metadata_latest::DecodeDifferent<&'static str, String>; - -impl TryFrom for Metadata { - type Error = Error; - - fn try_from(metadata: RuntimeMetadataPrefixed) -> Result { - if metadata.0 != META_RESERVED { - // 'meta' warn endiannes - return Err(Error::InvalidPrefix); - } - let meta = match metadata.1 { - RuntimeMetadata::V7(meta) => meta, - _ => return Err(Error::InvalidVersion), - }; - let mut modules = HashMap::new(); - let (mut modules_by_event_index, mut modules_by_call_index) = - (HashMap::new(), HashMap::new()); - let (mut event_index, mut call_index) = (0, 0); - for (i, module) in convert(meta.modules)?.into_iter().enumerate() { - let module_name = convert(module.name.clone())?; - if module.calls.is_some() { - modules_by_call_index.insert(call_index, module_name.clone()); - call_index += 1; - } - if module.event.is_none() { - modules_by_event_index.insert(event_index, module_name.clone()); - event_index += 1; - } - let module_metadata = convert_module(i, module)?; - modules.insert(module_name, module_metadata); - } - Ok(Metadata { - modules, - modules_by_event_index, - modules_by_call_index, - }) - } -} - -fn convert(dd: DecodeDifferent) -> Result { - match dd { - DecodeDifferent::Decoded(value) => Ok(value), - _ => Err(Error::ExpectedDecoded), - } -} - -fn convert_module( - index: usize, - module: runtime_metadata07::ModuleMetadata, -) -> Result { - let mut storage_map = HashMap::new(); - if let Some(storage) = module.storage { - let storage = convert(storage)?; - let prefix = convert(storage.prefix)?; - for entry in convert(storage.entries)?.into_iter() { - let entry_name = convert(entry.name.clone())?; - let entry_prefix = format!("{} {}", prefix, entry_name); - let entry = convert_entry(entry_prefix, entry)?; - storage_map.insert(entry_name, entry); - } - } - let mut call_map = HashMap::new(); - if let Some(calls) = module.calls { - for (index, call) in convert(calls)?.into_iter().enumerate() { - let name = convert(call.name)?; - let args = convert(call.arguments)? - .iter() - .map(|a| { - let ty = convert(a.ty.clone())?; - let name = convert(a.name.clone())?; - let arg = CallArgMetadata { - name, - ty: regex::parse(&ty).ok_or(Error::InvalidType(ty))?, - }; - Ok(arg) - }) - .collect::, Error>>()?; - let meta = CallMetadata { - name: name.clone(), - index: index as u8, - arguments: args, - }; - call_map.insert(name, meta); - } - } - let mut event_map = HashMap::new(); - if let Some(events) = module.event { - for (index, event) in convert(events)?.into_iter().enumerate() { - event_map.insert(index as u8, convert_event(event)?); - } - } - - Ok(ModuleMetadata { - index: index as u8, - name: convert(module.name)?, - storage: storage_map, - calls: call_map, - events: event_map, - }) -} - -fn convert_event( - event: runtime_metadata07::EventMetadata, -) -> Result { - let name = convert(event.name)?; - let mut arguments = HashSet::new(); - for arg in convert(event.arguments)? { - let arg = arg.parse::()?; - arguments.insert(arg); - } - Ok(ModuleEventMetadata { name, arguments }) -} - -fn convert_entry( - prefix: String, - entry: runtime_metadata07::StorageEntryMetadata, -) -> Result { - let default = convert(entry.default)?; - let documentation = convert(entry.documentation)?; - Ok(StorageMetadata { - prefix, - modifier: StorageEntryModifierTemp(entry.modifier).into(), - ty: StorageEntryTypeTemp(entry.ty).into(), - default, - documentation: documentation - .iter() - .map(|s| s.to_string()) - .collect::>(), - }) -} - -/// Temporary struct for converting between `StorageEntryModifier` -/// and `runtime_metadata_latest::StorageEntryModifier` -struct StorageEntryModifierTemp(StorageEntryModifier); -impl From for runtime_metadata_latest::StorageEntryModifier { - fn from( - entry: StorageEntryModifierTemp, - ) -> runtime_metadata_latest::StorageEntryModifier { - let entry = entry.0; - match entry { - StorageEntryModifier::Optional => { - runtime_metadata_latest::StorageEntryModifier::Optional - } - StorageEntryModifier::Default => { - runtime_metadata_latest::StorageEntryModifier::Default - } - } - } -} - -/// Temporary struct for converting between `StorageEntryType` -/// and `runtime_metadata_latest::StorageEntryType` -struct StorageEntryTypeTemp(StorageEntryType); -impl From for runtime_metadata_latest::StorageEntryType { - fn from(entry: StorageEntryTypeTemp) -> runtime_metadata_latest::StorageEntryType { - let entry = entry.0; - match entry { - StorageEntryType::Plain(d) => { - runtime_metadata_latest::StorageEntryType::Plain( - TempDecodeDifferentStr(d).into(), - ) - } - StorageEntryType::Map { - hasher, - key, - value, - is_linked, - } => runtime_metadata_latest::StorageEntryType::Map { - hasher: TempStorageHasher(hasher).into(), - key: TempDecodeDifferentStr(key).into(), - value: TempDecodeDifferentStr(value).into(), - unused: is_linked, - }, - StorageEntryType::DoubleMap { - hasher, - key1, - key2, - value, - key2_hasher, - } => runtime_metadata_latest::StorageEntryType::DoubleMap { - hasher: TempStorageHasher(hasher).into(), - key1: TempDecodeDifferentStr(key1).into(), - key2: TempDecodeDifferentStr(key2).into(), - value: TempDecodeDifferentStr(value).into(), - key2_hasher: TempStorageHasher(key2_hasher).into(), - }, - } - } -} - -/// Temprorary struct for converting between `StorageHasher` and -/// `runtime_metadata_latest::StorageHasher` -struct TempStorageHasher(StorageHasher); -impl From for runtime_metadata_latest::StorageHasher { - fn from(hasher: TempStorageHasher) -> runtime_metadata_latest::StorageHasher { - let hasher = hasher.0; - match hasher { - StorageHasher::Blake2_128 => { - runtime_metadata_latest::StorageHasher::Blake2_128 - } - StorageHasher::Blake2_256 => { - runtime_metadata_latest::StorageHasher::Blake2_256 - } - StorageHasher::Twox128 => runtime_metadata_latest::StorageHasher::Twox128, - StorageHasher::Twox256 => runtime_metadata_latest::StorageHasher::Twox256, - StorageHasher::Twox64Concat => { - runtime_metadata_latest::StorageHasher::Twox64Concat - } - } - } -} - -/// Temporary struct for converting between `DecodeDifferentStr` and -/// `DecodeDifferentStrLatest` -struct TempDecodeDifferentStr(DecodeDifferentStr); -impl From for LatestDecodeDifferentStr { - fn from(decode_str: TempDecodeDifferentStr) -> LatestDecodeDifferentStr { - let decode_str = decode_str.0; - match decode_str { - DecodeDifferent::Encode(b) => { - runtime_metadata_latest::DecodeDifferent::Encode(b) - } - DecodeDifferent::Decoded(o) => { - runtime_metadata_latest::DecodeDifferent::Decoded(o) - } - } - } -} diff --git a/core/src/decoder/metadata/version_08.rs b/core/src/decoder/metadata/version_08.rs index 58e9cdb8..5e94006b 100644 --- a/core/src/decoder/metadata/version_08.rs +++ b/core/src/decoder/metadata/version_08.rs @@ -18,22 +18,20 @@ // https://github.com/paritytech/substrate-subxt use super::{ - CallArgMetadata, CallMetadata, Error, EventArg, Metadata, ModuleEventMetadata, ModuleMetadata, StorageMetadata, - StorageType, StorageEntryModifier as DesubStorageEntryModifier, StorageHasher as DesubStorageHasher + CallArgMetadata, CallMetadata, Error, EventArg, Metadata, ModuleEventMetadata, ModuleMetadata, + StorageEntryModifier as DesubStorageEntryModifier, StorageHasher as DesubStorageHasher, StorageMetadata, + StorageType, }; use crate::regex; +use frame_metadata::decode_different::*; use runtime_metadata08::{ - DecodeDifferent, RuntimeMetadata, RuntimeMetadataPrefixed, StorageEntryModifier, StorageEntryType, StorageHasher, - META_RESERVED, + RuntimeMetadata, RuntimeMetadataPrefixed, StorageEntryModifier, StorageEntryType, StorageHasher, META_RESERVED, }; use std::{ collections::{HashMap, HashSet}, convert::{TryFrom, TryInto}, }; -type DecodeDifferentStr = DecodeDifferent<&'static str, String>; -type LatestDecodeDifferentStr = frame_metadata::decode_different::DecodeDifferent<&'static str, String>; - impl TryFrom for Metadata { type Error = Error; @@ -170,19 +168,6 @@ impl From for DesubStorageHasher { } } -/// Temporary struct for converting between `DecodeDifferentStr` and -/// `DecodeDifferentStrLatest` -struct TempDecodeDifferentStr(DecodeDifferentStr); -impl From for LatestDecodeDifferentStr { - fn from(decode_str: TempDecodeDifferentStr) -> LatestDecodeDifferentStr { - let decode_str = decode_str.0; - match decode_str { - DecodeDifferent::Encode(b) => super::DecodeDifferent::Encode(b), - DecodeDifferent::Decoded(o) => super::DecodeDifferent::Decoded(o), - } - } -} - impl TryFrom for StorageType { type Error = Error; fn try_from(entry: StorageEntryType) -> Result { diff --git a/core/src/decoder/metadata/version_09.rs b/core/src/decoder/metadata/version_09.rs index f3728b38..d2bb9c7b 100644 --- a/core/src/decoder/metadata/version_09.rs +++ b/core/src/decoder/metadata/version_09.rs @@ -18,22 +18,20 @@ // https://github.com/paritytech/substrate-subxt use super::{ - CallArgMetadata, CallMetadata, Error, EventArg, Metadata, ModuleEventMetadata, ModuleMetadata, StorageMetadata, - StorageType, StorageEntryModifier as DesubStorageEntryModifier, StorageHasher as DesubStorageHasher + CallArgMetadata, CallMetadata, Error, EventArg, Metadata, ModuleEventMetadata, ModuleMetadata, + StorageEntryModifier as DesubStorageEntryModifier, StorageHasher as DesubStorageHasher, StorageMetadata, + StorageType, }; use crate::regex; +use frame_metadata::decode_different::*; use runtime_metadata09::{ - DecodeDifferent, RuntimeMetadata, RuntimeMetadataPrefixed, StorageEntryModifier, StorageEntryType, StorageHasher, - META_RESERVED, + RuntimeMetadata, RuntimeMetadataPrefixed, StorageEntryModifier, StorageEntryType, StorageHasher, META_RESERVED, }; use std::{ collections::{HashMap, HashSet}, convert::{TryFrom, TryInto}, }; -type DecodeDifferentStr = DecodeDifferent<&'static str, String>; -type LatestDecodeDifferentStr = super::DecodeDifferent<&'static str, String>; - impl TryFrom for Metadata { type Error = Error; @@ -171,19 +169,6 @@ impl From for DesubStorageHasher { } } -/// Temporary struct for converting between `DecodeDifferentStr` and -/// `DecodeDifferentStrLatest` -struct TempDecodeDifferentStr(DecodeDifferentStr); -impl From for LatestDecodeDifferentStr { - fn from(decode_str: TempDecodeDifferentStr) -> LatestDecodeDifferentStr { - let decode_str = decode_str.0; - match decode_str { - DecodeDifferent::Encode(b) => super::DecodeDifferent::Encode(b), - DecodeDifferent::Decoded(o) => super::DecodeDifferent::Decoded(o), - } - } -} - impl TryFrom for StorageType { type Error = Error; fn try_from(entry: StorageEntryType) -> Result { diff --git a/core/src/decoder/metadata/version_10.rs b/core/src/decoder/metadata/version_10.rs index 97ea2659..0f5e0b46 100644 --- a/core/src/decoder/metadata/version_10.rs +++ b/core/src/decoder/metadata/version_10.rs @@ -15,22 +15,20 @@ // along with substrate-desub. If not, see . use super::{ - CallArgMetadata, CallMetadata, Error, EventArg, Metadata, ModuleEventMetadata, ModuleMetadata, StorageMetadata, - StorageType, StorageEntryModifier as DesubStorageEntryModifier, StorageHasher as DesubStorageHasher + CallArgMetadata, CallMetadata, Error, EventArg, Metadata, ModuleEventMetadata, ModuleMetadata, + StorageEntryModifier as DesubStorageEntryModifier, StorageHasher as DesubStorageHasher, StorageMetadata, + StorageType, }; use crate::regex; +use frame_metadata::decode_different::*; use runtime_metadata10::{ - DecodeDifferent, RuntimeMetadata, RuntimeMetadataPrefixed, StorageEntryModifier, StorageEntryType, StorageHasher, - META_RESERVED, + RuntimeMetadata, RuntimeMetadataPrefixed, StorageEntryModifier, StorageEntryType, StorageHasher, META_RESERVED, }; use std::{ collections::{HashMap, HashSet}, convert::{TryFrom, TryInto}, }; -type DecodeDifferentStr = DecodeDifferent<&'static str, String>; -type LatestDecodeDifferentStr = super::DecodeDifferent<&'static str, String>; - impl TryFrom for Metadata { type Error = Error; @@ -167,19 +165,6 @@ impl From for DesubStorageHasher { } } -/// Temporary struct for converting between `DecodeDifferentStr` and -/// `DecodeDifferentStrLatest` -struct TempDecodeDifferentStr(DecodeDifferentStr); -impl From for LatestDecodeDifferentStr { - fn from(decode_str: TempDecodeDifferentStr) -> LatestDecodeDifferentStr { - let decode_str = decode_str.0; - match decode_str { - DecodeDifferent::Encode(b) => super::DecodeDifferent::Encode(b), - DecodeDifferent::Decoded(o) => super::DecodeDifferent::Decoded(o), - } - } -} - impl TryFrom for StorageType { type Error = Error; fn try_from(entry: StorageEntryType) -> Result { diff --git a/core/src/decoder/metadata/version_11.rs b/core/src/decoder/metadata/version_11.rs index 347bc022..62465518 100644 --- a/core/src/decoder/metadata/version_11.rs +++ b/core/src/decoder/metadata/version_11.rs @@ -31,14 +31,14 @@ use super::{ CallArgMetadata, CallMetadata, Error, EventArg, ExtrinsicMetadata, Metadata, ModuleEventMetadata, ModuleMetadata, - StorageMetadata, StorageType, StorageEntryModifier as DesubStorageEntryModifier, StorageHasher as DesubStorageHasher + StorageEntryModifier as DesubStorageEntryModifier, StorageHasher as DesubStorageHasher, StorageMetadata, + StorageType, }; use crate::{regex, RustTypeMarker}; +use frame_metadata::decode_different::*; use runtime_metadata11::{ - DecodeDifferent, RuntimeMetadata, RuntimeMetadataPrefixed, StorageEntryModifier, StorageEntryType, StorageHasher, - META_RESERVED, + RuntimeMetadata, RuntimeMetadataPrefixed, StorageEntryModifier, StorageEntryType, StorageHasher, META_RESERVED, }; - use std::{ collections::{HashMap, HashSet}, convert::{TryFrom, TryInto}, diff --git a/core/src/decoder/metadata/version_12.rs b/core/src/decoder/metadata/version_12.rs index c2dea799..9c8a7595 100644 --- a/core/src/decoder/metadata/version_12.rs +++ b/core/src/decoder/metadata/version_12.rs @@ -1,4 +1,4 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. +// Copyright 2019-2021 Parity Technologies (UK) Ltd. // This file is part of substrate-desub. // // substrate-desub is free software: you can redistribute it and/or modify @@ -31,21 +31,18 @@ use super::{ CallArgMetadata, CallMetadata, Error, EventArg, ExtrinsicMetadata, Metadata, ModuleEventMetadata, ModuleMetadata, - StorageMetadata, StorageType, StorageEntryModifier as DesubStorageEntryModifier, StorageHasher as - DesubStorageHasher, + StorageEntryModifier as DesubStorageEntryModifier, StorageHasher as DesubStorageHasher, StorageMetadata, + StorageType, }; use crate::{regex, RustTypeMarker}; use frame_metadata::{ + decode_different::DecodeDifferent, v12::{ - StorageEntryType, META_RESERVED, - ModuleMetadata as ModuleMetadatav12, - EventMetadata as EventMetadatav12, - StorageEntryMetadata as StorageEntryMetadatav12, - StorageEntryModifier as StorageEntryModifierv12, StorageHasher as StorageHasherv12 + EventMetadata as EventMetadatav12, ModuleMetadata as ModuleMetadatav12, RuntimeMetadataV12, + StorageEntryMetadata as StorageEntryMetadatav12, StorageEntryModifier as StorageEntryModifierv12, + StorageEntryType, StorageHasher as StorageHasherv12, }, - decode_different::DecodeDifferent, - RuntimeMetadataPrefixed, RuntimeMetadata }; use std::{ @@ -53,43 +50,33 @@ use std::{ convert::{TryFrom, TryInto}, }; -impl TryFrom for Metadata { +impl TryFrom for Metadata { type Error = Error; - - fn try_from(metadata: RuntimeMetadataPrefixed) -> Result { - if metadata.0 != META_RESERVED { - // 'meta' warn endiannes - return Err(Error::InvalidPrefix); - } - let meta = match metadata.1 { - RuntimeMetadata::V12(meta) => meta, - _ => return Err(Error::InvalidVersion), - }; + fn try_from(metadata: RuntimeMetadataV12) -> Result { let mut modules = HashMap::new(); let (mut modules_by_event_index, mut modules_by_call_index) = (HashMap::new(), HashMap::new()); - let (mut event_index, mut call_index) = (0, 0); - for (i, module) in convert(meta.modules)?.into_iter().enumerate() { + let mut event_index = 0; + for module in convert(metadata.modules)?.into_iter() { let module_name = convert(module.name.clone())?; if module.calls.is_some() { - modules_by_call_index.insert(call_index, module_name.clone()); - call_index += 1; + modules_by_call_index.insert(module.index, module_name.clone()); } if module.event.is_none() { modules_by_event_index.insert(event_index, module_name.clone()); event_index += 1; } - let module_metadata = convert_module(i, module)?; + let module_metadata = convert_module(module)?; modules.insert(module_name, std::sync::Arc::new(module_metadata)); } let mut extensions: Vec = Vec::new(); - for ext in meta.extrinsic.signed_extensions.iter() { + for ext in metadata.extrinsic.signed_extensions.iter() { let name: String = convert(ext.clone())?; let ty = regex::parse(&name).ok_or(Error::InvalidType(name))?; extensions.push(ty); } - let extrinsics = ExtrinsicMetadata::new(meta.extrinsic.version, extensions); + let extrinsics = ExtrinsicMetadata::new(metadata.extrinsic.version, extensions); Ok(Metadata { modules, modules_by_event_index, modules_by_call_index, extrinsics: Some(extrinsics) }) } @@ -102,7 +89,7 @@ fn convert(dd: DecodeDifferent) -> Result Result { +fn convert_module(module: ModuleMetadatav12) -> Result { let mut storage_map = HashMap::new(); if let Some(storage) = module.storage { let storage = convert(storage)?; @@ -139,7 +126,7 @@ fn convert_module(index: usize, module: ModuleMetadatav12) -> Result Result Ok(ModuleEventMetadata { name, arguments }) } -fn convert_entry( - prefix: String, - entry: StorageEntryMetadatav12, -) -> Result { +fn convert_entry(prefix: String, entry: StorageEntryMetadatav12) -> Result { let default = convert(entry.default)?; let documentation = convert(entry.documentation)?; Ok(StorageMetadata { diff --git a/core/src/decoder/metadata/version_13.rs b/core/src/decoder/metadata/version_13.rs new file mode 100644 index 00000000..1d247d3d --- /dev/null +++ b/core/src/decoder/metadata/version_13.rs @@ -0,0 +1,237 @@ +// Copyright 2019-2021 Parity Technologies (UK) Ltd. +// This file is part of substrate-desub. +// +// substrate-desub is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// substrate-desub is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with substrate-desub. If not, see . +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of substrate-desub. +// +// substrate-desub is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// substrate-desub is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with substrate-desub. If not, see . + +use super::{ + CallArgMetadata, CallMetadata, Error, EventArg, ExtrinsicMetadata, Metadata, ModuleEventMetadata, ModuleMetadata, + StorageEntryModifier as DesubStorageEntryModifier, StorageHasher as DesubStorageHasher, StorageMetadata, + StorageType, +}; +use crate::{regex, RustTypeMarker}; + +use frame_metadata::{ + decode_different::DecodeDifferent, + v13::{ + EventMetadata as EventMetadataV13, ModuleMetadata as ModuleMetadataV13, RuntimeMetadataV13, + StorageEntryMetadata as StorageEntryMetadataV13, StorageEntryModifier as StorageEntryModifierV13, + StorageEntryType, StorageHasher as StorageHasherV13, + }, +}; + +use std::{ + collections::{HashMap, HashSet}, + convert::{TryFrom, TryInto}, +}; + +impl TryFrom for Metadata { + type Error = Error; + + fn try_from(metadata: RuntimeMetadataV13) -> Result { + let mut modules = HashMap::new(); + let (mut modules_by_event_index, mut modules_by_call_index) = (HashMap::new(), HashMap::new()); + let mut event_index = 0; + for module in convert(metadata.modules)?.into_iter() { + let module_name = convert(module.name.clone())?; + if module.calls.is_some() { + modules_by_call_index.insert(module.index, module_name.clone()); + } + if module.event.is_none() { + modules_by_event_index.insert(event_index, module_name.clone()); + event_index += 1; + } + let module_metadata = convert_module(module)?; + modules.insert(module_name, std::sync::Arc::new(module_metadata)); + } + + let mut extensions: Vec = Vec::new(); + for ext in metadata.extrinsic.signed_extensions.iter() { + let name: String = convert(ext.clone())?; + let ty = regex::parse(&name).ok_or(Error::InvalidType(name))?; + extensions.push(ty); + } + + let extrinsics = ExtrinsicMetadata::new(metadata.extrinsic.version, extensions); + + Ok(Metadata { modules, modules_by_event_index, modules_by_call_index, extrinsics: Some(extrinsics) }) + } +} + +fn convert(dd: DecodeDifferent) -> Result { + match dd { + DecodeDifferent::Decoded(value) => Ok(value), + _ => Err(Error::ExpectedDecoded), + } +} + +fn convert_module(module: ModuleMetadataV13) -> Result { + let mut storage_map = HashMap::new(); + if let Some(storage) = module.storage { + let storage = convert(storage)?; + let prefix = convert(storage.prefix)?; + for entry in convert(storage.entries)?.into_iter() { + let entry_name = convert(entry.name.clone())?; + let entry_prefix = format!("{} {}", prefix, entry_name); + let entry = convert_entry(entry_prefix, entry)?; + storage_map.insert(entry_name, entry); + } + } + let mut call_map = HashMap::new(); + if let Some(calls) = module.calls { + for (index, call) in convert(calls)?.into_iter().enumerate() { + let name = convert(call.name)?; + let args = convert(call.arguments)? + .iter() + .map(|a| { + let ty = convert(a.ty.clone())?; + let name = convert(a.name.clone())?; + let arg = CallArgMetadata { name, ty: regex::parse(&ty).ok_or(Error::InvalidType(ty))? }; + Ok(arg) + }) + .collect::, Error>>()?; + let meta = CallMetadata { name: name.clone(), index: index as u8, arguments: args }; + call_map.insert(name, meta); + } + } + let mut event_map = HashMap::new(); + if let Some(events) = module.event { + for (index, event) in convert(events)?.into_iter().enumerate() { + event_map.insert(index as u8, convert_event(event)?); + } + } + + Ok(ModuleMetadata { + index: module.index, + name: convert(module.name)?, + storage: storage_map, + calls: call_map, + events: event_map, + }) +} + +fn convert_event(event: EventMetadataV13) -> Result { + let name = convert(event.name)?; + let mut arguments = HashSet::new(); + for arg in convert(event.arguments)? { + let arg = arg.parse::()?; + arguments.insert(arg); + } + Ok(ModuleEventMetadata { name, arguments }) +} + +fn convert_entry(prefix: String, entry: StorageEntryMetadataV13) -> Result { + let default = convert(entry.default)?; + let documentation = convert(entry.documentation)?; + Ok(StorageMetadata { + prefix, + modifier: StorageEntryModifierTemp(entry.modifier).into(), + ty: entry.ty.try_into()?, + default, + documentation: documentation.iter().map(|s| s.to_string()).collect::>(), + }) +} + +/// Temporary struct for converting between `StorageEntryModifier` +/// and `DesubStorageEntryModifier` +struct StorageEntryModifierTemp(StorageEntryModifierV13); +impl From for DesubStorageEntryModifier { + fn from(entry: StorageEntryModifierTemp) -> DesubStorageEntryModifier { + let entry = entry.0; + match entry { + StorageEntryModifierV13::Optional => DesubStorageEntryModifier::Optional, + StorageEntryModifierV13::Default => DesubStorageEntryModifier::Default, + } + } +} + +/// Temprorary struct for converting between `StorageHasher` and +/// `DesubStorageHasher` +struct TempStorageHasher(StorageHasherV13); +impl From for DesubStorageHasher { + fn from(hasher: TempStorageHasher) -> DesubStorageHasher { + let hasher = hasher.0; + match hasher { + StorageHasherV13::Blake2_128 => DesubStorageHasher::Blake2_128, + StorageHasherV13::Blake2_128Concat => DesubStorageHasher::Blake2_128, + StorageHasherV13::Blake2_256 => DesubStorageHasher::Blake2_256, + StorageHasherV13::Twox128 => DesubStorageHasher::Twox128, + StorageHasherV13::Twox256 => DesubStorageHasher::Twox256, + StorageHasherV13::Twox64Concat => DesubStorageHasher::Twox64Concat, + StorageHasherV13::Identity => DesubStorageHasher::Identity, + } + } +} + +impl TryFrom for StorageType { + type Error = Error; + fn try_from(entry: StorageEntryType) -> Result { + let entry = match entry { + StorageEntryType::Plain(v) => { + let ty = convert(v)?; + StorageType::Plain(regex::parse(&ty).ok_or(Error::InvalidType(ty))?) + } + StorageEntryType::Map { hasher, key, value, unused } => { + let key = convert(key)?; + let value = convert(value)?; + StorageType::Map { + hasher: TempStorageHasher(hasher).into(), + key: regex::parse(&key).ok_or(Error::InvalidType(key))?, + value: regex::parse(&value).ok_or(Error::InvalidType(value))?, + unused, + } + } + StorageEntryType::DoubleMap { hasher, key1, key2, value, key2_hasher } => { + let key1 = convert(key1)?; + let key2 = convert(key2)?; + let value = convert(value)?; + StorageType::DoubleMap { + hasher: TempStorageHasher(hasher).into(), + key1: regex::parse(&key1).ok_or(Error::InvalidType(key1))?, + key2: regex::parse(&key2).ok_or(Error::InvalidType(key2))?, + value: regex::parse(&value).ok_or(Error::InvalidType(value))?, + key2_hasher: TempStorageHasher(key2_hasher).into(), + } + } + StorageEntryType::NMap { keys, hashers, value } => { + let keys = convert(keys)?; + let hashers = convert(hashers)?; + let value = convert(value)?; + let hashers = + hashers.into_iter().map(|h| TempStorageHasher(h).into()).collect::>(); + let keys = keys + .into_iter() + .map(|k| regex::parse(&k).ok_or(Error::InvalidType(k))) + .collect::>()?; + let value = regex::parse(&value).ok_or(Error::InvalidType(value))?; + StorageType::NMap { hashers, keys, value } + } + }; + Ok(entry) + } +} diff --git a/core/src/decoder/metadata/versions.rs b/core/src/decoder/metadata/versions.rs deleted file mode 100644 index 8e9347cf..00000000 --- a/core/src/decoder/metadata/versions.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// This file is part of substrate-desub. -// -// substrate-desub is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// substrate-desub is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with substrate-desub. If not, see . diff --git a/core/src/decoder/storage.rs b/core/src/decoder/storage.rs index 4138430d..93c80494 100644 --- a/core/src/decoder/storage.rs +++ b/core/src/decoder/storage.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with substrate-desub. If not, see . -use super::metadata::{ModuleMetadata, StorageMetadata, StorageHasher}; +use super::metadata::{ModuleMetadata, StorageHasher, StorageMetadata}; use crate::RustTypeMarker; use serde::Serialize; use std::collections::HashMap; diff --git a/core/src/error.rs b/core/src/error.rs index 02c05815..c84552c6 100644 --- a/core/src/error.rs +++ b/core/src/error.rs @@ -18,6 +18,8 @@ pub enum Error { Regex(#[from] onig::Error), #[error("Conversion from {0} to {1} not possible")] Conversion(String, String), + #[error("Spec version {0} not present in Decoder")] + MissingSpec(u32), } impl From<&str> for Error { diff --git a/core/src/lib.rs b/core/src/lib.rs index a28369b8..1df6490c 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -16,7 +16,6 @@ #[forbid(unsafe_code)] #[deny(unused)] - pub mod decoder; mod error; pub mod regex; @@ -37,7 +36,7 @@ pub trait TypeDetective: fmt::Debug + dyn_clone::DynClone + Send + Sync { /// Some types have a fallback type that may be decoded into if the original /// type fails. - fn try_fallback(&self, chain: &str, spec: u32, module: &str, ty: &str) -> Option<&RustTypeMarker>; + fn try_fallback(&self, module: &str, ty: &str) -> Option<&RustTypeMarker>; /// get a type specific to decoding extrinsics fn get_extrinsic_ty(&self, chain: &str, spec: u32, ty: &str) -> Option<&RustTypeMarker>; @@ -82,13 +81,12 @@ impl SetField { } } -/// TODO: Allow mixed struct-unit types #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] pub struct EnumField { /// name of the Variant /// if the variant is a Unit enum, it will not have a name pub name: String, - pub value: Option + pub value: Option, } impl EnumField { @@ -204,9 +202,6 @@ pub enum RustTypeMarker { U64, /// primitive unsigned 128 bit integer U128, - /// primitive unsigned word-sized integer - USize, - /// primitive signed 8 bit integer I8, /// primitive signed 16 bit integer @@ -217,20 +212,10 @@ pub enum RustTypeMarker { I64, /// primitive signed 128 bit integer I128, - /// primitive signed word-sized integer - ISize, - - /// primitive IEEE-spec 32-bit floating-point number - F32, - /// primitive IEEE-spec 64-bit floating-point number - F64, /// Boolean true/false type Bool, - /// String type - String, - /// Used for fields that don't exist (ex Unit variant in an enum with both /// units/structs) Null, @@ -280,22 +265,13 @@ impl Display for RustTypeMarker { RustTypeMarker::U32 => type_marker.push_str("u32"), RustTypeMarker::U64 => type_marker.push_str("u64"), RustTypeMarker::U128 => type_marker.push_str("u128"), - RustTypeMarker::USize => type_marker.push_str("usize"), RustTypeMarker::I8 => type_marker.push_str("i8"), RustTypeMarker::I16 => type_marker.push_str("i16"), RustTypeMarker::I32 => type_marker.push_str("i32"), RustTypeMarker::I64 => type_marker.push_str("i64"), RustTypeMarker::I128 => type_marker.push_str("i128"), - RustTypeMarker::ISize => type_marker.push_str("isize"), - - RustTypeMarker::F32 => type_marker.push_str("f32"), - RustTypeMarker::F64 => type_marker.push_str("f64"), - RustTypeMarker::Bool => type_marker.push_str("bool"), - - RustTypeMarker::String => type_marker.push_str("string"), - RustTypeMarker::Null => type_marker.push_str("null"), } write!(f, "{}", type_marker) diff --git a/core/src/regex.rs b/core/src/regex.rs index fa7a89b6..895b17f8 100644 --- a/core/src/regex.rs +++ b/core/src/regex.rs @@ -14,13 +14,13 @@ // You should have received a copy of the GNU General Public License // along with substrate-desub. If not, see . -// TODO: write tests for all 'parse_xxx' functions use super::{CommonTypes, RustTypeMarker}; use onig::{Regex, Region, SearchOptions}; #[derive(Debug, Clone, PartialEq, Eq)] enum RegexSet { ArrayPrimitive, + ArrayPrimitiveExtra, BitSize, ArrayStruct, Vec, @@ -38,6 +38,8 @@ impl RegexSet { fn get_type(s: &str) -> Option { if rust_array_decl_prim().is_match(s) { Some(RegexSet::ArrayPrimitive) + } else if rust_array_with_extra_type().is_match(s) { + Some(RegexSet::ArrayPrimitiveExtra) } else if rust_bit_size().is_match(s) { Some(RegexSet::BitSize) } else if rust_array_decl_struct().is_match(s) { @@ -64,6 +66,7 @@ impl RegexSet { fn parse_type(&self, s: &str) -> Option { match self { RegexSet::ArrayPrimitive => parse_primitive_array(s), + RegexSet::ArrayPrimitiveExtra => parse_array_with_extra_type(s), RegexSet::BitSize => parse_bit_size(s), RegexSet::ArrayStruct => parse_struct_array(s), RegexSet::Vec => parse_vec(s), @@ -77,6 +80,13 @@ impl RegexSet { } } +/// Matches an array like: [u8; 20; H160] +fn rust_array_with_extra_type() -> Regex { + Regex::new( + r"^\[\s*?(?[uif]{1})(?8)?(?16)?(?32)?(?64)?(?128)?;\s*?(?[\d]+)+\s*?;?\s*?([\d\w]*)\s*?]", + ).expect("Regex Array with extra type info invalid") +} + // primitive array declaration with named capture groups, ie [u8; 99] // width of number and unsigned/signed are all in their own capture group // size of array is in the last capture group @@ -135,14 +145,56 @@ pub fn rust_generic_decl() -> Regex { /// Transforms a prefixed generic type (EX: T::Moment) /// into a non-prefixed type (T::Moment -> Moment) -pub fn remove_prefix<'a, S: Into<&'a str>>(s: S) -> Option { - let s: &str = s.into(); +pub fn remove_prefix>(s: S) -> Option { + let s: &str = s.as_ref(); let re = Regex::new(r"[\w><]::([\w><]+)").expect("Regex expressions should be infallible; qed"); let caps = re.captures(s)?; caps.iter().nth(1)?.map(|s| s.to_string()) } +/// Removes a path from a string that is a rust type. +/// Ex: removes 'schedule' from schedule::Period +pub fn remove_path>(s: S) -> Option { + let s: &str = s.as_ref(); + + let re = Regex::new(r"\b(?\w+)<(?[\w<>,: ]+)>") + .expect("Regex expression should be infallible; qed"); + let caps = re.captures(s)?; + caps.iter().nth(1)?.map(|s| s.to_string()) +} + +/// Removes the trait preceding the type. +/// I.E Removes `::` from ::Call +pub fn remove_trait>(s: S) -> Option { + let s: &str = s.as_ref(); + + let re = Regex::new(r"^(?:|)[><\w]+:*([\W\w]*)") + .expect("Regex expression should be infallible; qed"); + let caps = re.captures(s)?; + caps.iter().nth(1)?.map(|s| s.to_string()) +} + +pub fn remove_empty_generic>(s: S) -> Option { + let s: &str = s.as_ref(); + + let re = Regex::new(r"(\w*)<\(\)>").expect("Regex expression should be infallible; qed"); + let caps = re.captures(s)?; + caps.iter().nth(1)?.map(|s| s.to_string()) +} + +/// Sanitizes a type and returns parts that might correspond to PolkadotJS types +pub fn sanitize_ty(ty: &str) -> Option { + log::trace!("sanitizing ty {}", ty); + let ty = if let Some(no_empty_gen) = remove_empty_generic(&ty) { no_empty_gen } else { ty.to_string() }; + let ty = if let Some(no_trait) = remove_trait(&ty) { no_trait } else { ty }; + let ty = if let Some(no_path) = remove_path(&ty) { no_path } else { ty }; + let ty = if let Some(un_prefixed) = remove_prefix(&ty) { un_prefixed } else { ty }; + + log::trace!("Possibly sanitized type: {}", ty); + Some(ty) +} + /// Only captures text within the tuples, /// need to use 'Matches' (ie `find_iter`) iterator to get all matches /// max tuple size is 32 @@ -189,13 +241,25 @@ pub fn parse_struct_array(s: &str) -> Option { /// /// # Panics /// -/// TODO: Use errors instead of returning option pub fn parse_primitive_array(s: &str) -> Option { let re = rust_array_decl_prim(); if !re.is_match(s) { return None; } + parse_array(s, re) +} + +/// Parse an array that's in the form [u8; 20; H160] +/// the extra type information 'H160' is discarded. +fn parse_array_with_extra_type(s: &str) -> Option { + let re = rust_array_with_extra_type(); + if !re.is_match(s) { + return None; + } + parse_array(s, re) +} +fn parse_array(s: &str, re: Regex) -> Option { let mut region = Region::new(); let (mut t, mut size, mut ty) = (None, None, None); @@ -230,6 +294,7 @@ pub fn parse_primitive_array(s: &str) -> Option { true }); }; + let t = t?; let size = size?; let ty = ty?; @@ -238,31 +303,26 @@ pub fn parse_primitive_array(s: &str) -> Option { 8 => match t { "u" => RustTypeMarker::U8, "i" => RustTypeMarker::I8, - "f" => panic!("type does not exist 'f8'"), _ => panic!("impossible match encountered"), }, 16 => match t { "u" => RustTypeMarker::U16, "i" => RustTypeMarker::I16, - "f" => panic!("type does not exist 'f16'"), _ => panic!("impossible match encountered"), }, 32 => match t { "u" => RustTypeMarker::U32, "i" => RustTypeMarker::I32, - "f" => RustTypeMarker::F32, _ => panic!("impossible match encountered"), }, 64 => match t { "u" => RustTypeMarker::U64, "i" => RustTypeMarker::I64, - "f" => RustTypeMarker::F64, _ => panic!("impossible match encountered"), }, 128 => match t { "u" => RustTypeMarker::U128, "i" => RustTypeMarker::I128, - "f" => panic!("type does not exist: 'f128'"), _ => panic!("impossible match encountered"), }, _ => panic!("Couldn't determine bit-width of types in array"), @@ -408,17 +468,12 @@ pub fn parse(s: &str) -> Option { "u32" => Some(RustTypeMarker::U32), "u64" => Some(RustTypeMarker::U64), "u128" => Some(RustTypeMarker::U128), - "usize" => Some(RustTypeMarker::USize), "i8" => Some(RustTypeMarker::I8), "i16" => Some(RustTypeMarker::I16), "i32" => Some(RustTypeMarker::I32), "i64" => Some(RustTypeMarker::I64), "i128" => Some(RustTypeMarker::I128), - "isize" => Some(RustTypeMarker::ISize), - - "f32" => Some(RustTypeMarker::F32), - "f64" => Some(RustTypeMarker::F64), "bool" => Some(RustTypeMarker::Bool), "Null" => Some(RustTypeMarker::Null), @@ -595,14 +650,6 @@ mod tests { parse_primitive_array("[i128; 32]").unwrap(), RustTypeMarker::Array { size: 32, ty: Box::new(RustTypeMarker::I128) } ); - assert_eq!( - parse_primitive_array("[f32; 32]").unwrap(), - RustTypeMarker::Array { size: 32, ty: Box::new(RustTypeMarker::F32) } - ); - assert_eq!( - parse_primitive_array("[f64; 32]").unwrap(), - RustTypeMarker::Array { size: 32, ty: Box::new(RustTypeMarker::F64) } - ); assert_eq!( parse_primitive_array("[i128; 999999]").unwrap(), RustTypeMarker::Array { size: 999_999, ty: Box::new(RustTypeMarker::I128) } @@ -612,7 +659,7 @@ mod tests { #[test] fn should_match_struct_array() { let re = rust_array_decl_struct(); - assert_eq!(true, re.is_match("[Foo; 10]")) + assert!(re.is_match("[Foo; 10]")) } #[test] @@ -775,17 +822,12 @@ mod tests { assert_eq!(parse("u32").unwrap(), RustTypeMarker::U32); assert_eq!(parse("u64").unwrap(), RustTypeMarker::U64); assert_eq!(parse("u128").unwrap(), RustTypeMarker::U128); - assert_eq!(parse("usize").unwrap(), RustTypeMarker::USize); assert_eq!(parse("i8").unwrap(), RustTypeMarker::I8); assert_eq!(parse("i16").unwrap(), RustTypeMarker::I16); assert_eq!(parse("i32").unwrap(), RustTypeMarker::I32); assert_eq!(parse("i64").unwrap(), RustTypeMarker::I64); assert_eq!(parse("i128").unwrap(), RustTypeMarker::I128); - assert_eq!(parse("isize").unwrap(), RustTypeMarker::ISize); - - assert_eq!(parse("f32").unwrap(), RustTypeMarker::F32); - assert_eq!(parse("f64").unwrap(), RustTypeMarker::F64); assert_eq!(parse("bool").unwrap(), RustTypeMarker::Bool); assert_eq!(parse("Null").unwrap(), RustTypeMarker::Null); @@ -847,6 +889,8 @@ mod tests { fn should_remove_prefix() { assert_eq!(remove_prefix("T::Moment").unwrap(), "Moment"); assert_eq!(remove_prefix("T::Generic").unwrap(), "Generic"); + // assert_eq!(remove_prefix("schedule::Period").unwrap(), "Period"); + // assert_eq!(remove_prefix("Period").unwrap(), "BlockNumber"); } #[test] @@ -879,4 +923,20 @@ mod tests { let ty = "Int<64, Balance>"; assert_eq!(parse_bit_size(ty).unwrap(), RustTypeMarker::I64); } + + #[test] + fn should_match_array_with_extra_info() { + let _ = pretty_env_logger::try_init(); + let ty = "[u8; 20; H160]"; + let re = rust_array_with_extra_type(); + assert!(re.is_match(ty)); + } + + #[test] + fn should_parse_array_with_extra_info() { + let _ = pretty_env_logger::try_init(); + let ty = "[u8; 20; H160]"; + let ty = parse_array_with_extra_type(ty); + assert_eq!(ty, Some(RustTypeMarker::Array { size: 20, ty: Box::new(RustTypeMarker::U8) })); + } } diff --git a/core/src/substrate_types.rs b/core/src/substrate_types.rs index 91239bcf..56a6b315 100644 --- a/core/src/substrate_types.rs +++ b/core/src/substrate_types.rs @@ -19,11 +19,12 @@ //! Serialization and Deserialization Implementations (to serialize as if it were a native type) //! Display Implementation -mod remote; mod data; +mod remote; use self::remote::*; use crate::{Error, SetField}; +use bitvec::order::Lsb0 as BitOrderLsb0; use primitives::crypto::AccountId32; use primitives::crypto::{Ss58AddressFormat, Ss58Codec}; use serde::Serialize; @@ -34,7 +35,6 @@ pub use self::data::Data; pub type Address = runtime_primitives::MultiAddress; pub type Vote = pallet_democracy::Vote; pub type Conviction = pallet_democracy::Conviction; - /// A 'stateful' version of [RustTypeMarker](enum.RustTypeMarker.html). /// 'Std' variant is not here like in RustTypeMarker. /// Instead common types are just apart of the enum @@ -46,6 +46,9 @@ pub enum SubstrateType { /// 256-bit hash type H256(primitives::H256), + /// BitVec type + BitVec(bitvec::vec::BitVec), + /// Recursive Call Type Call(Vec<(String, SubstrateType)>), /// Era @@ -56,12 +59,14 @@ pub enum SubstrateType { GenericVote(pallet_democracy::Vote), /// Substrate Indices Address Type - // TODO: this is not generic for any chain that doesn't use a - // u32 and [u8; 32] for its index/id #[serde(with = "RemoteAddress")] Address(Address), /// Data Identity Type Data(Data), + + /// Identity fields but as just an enum. + IdentityField(u64), + /// SignedExtension Type SignedExtra(String), @@ -125,6 +130,7 @@ impl fmt::Display for SubstrateType { match self { SubstrateType::H512(v) => write!(f, "{}", v), SubstrateType::H256(v) => write!(f, "{}", v), + SubstrateType::BitVec(v) => write!(f, "{}", v), SubstrateType::Call(c) => { write!(f, "CALL")?; for arg in c.iter() { @@ -149,6 +155,7 @@ impl fmt::Display for SubstrateType { SubstrateType::Data(d) => write!(f, "{:?}", d), SubstrateType::SignedExtra(v) => write!(f, "{}", v), SubstrateType::Unit(u) => write!(f, "{}", u), + SubstrateType::IdentityField(field) => write!(f, "{:?}", field), SubstrateType::Composite(v) => { let mut s = String::from(""); for v in v.iter() { @@ -194,7 +201,7 @@ pub struct EnumField { /// name of the field. pub name: String, /// Optional field value. An enum field without a value are unit fields. - pub value: Option> + pub value: Option>, } impl EnumField { diff --git a/core/src/substrate_types/data.rs b/core/src/substrate_types/data.rs index 4325ece6..28e9b402 100644 --- a/core/src/substrate_types/data.rs +++ b/core/src/substrate_types/data.rs @@ -17,16 +17,14 @@ //! Copy of this: https://substrate.dev/rustdocs/latest/pallet_identity/enum.Data.html //! For the purpose of Decoding the Data field. //! Because of the specificity/complexity of decoding: -//! - `BoundedVec` includes private tuple fields with no getters so Serde `remote` does not work -//! - `Data` has a special way of encoding/decoding -//! Data impl is copied over and must be maintaned against substrate master. - +//! - `BoundedVec` includes private tuple fields with no getters so Serde `remote` does not work +//! - `Data` has a special way of encoding/decoding +//! Data impl is copied over and must be maintaned against substrate master. use codec::{Decode, Encode}; -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use std::iter::once; - /// Either underlying data blob if it is at most 32 bytes, or a hash of it. If the data is greater /// than 32-bytes then it will be truncated when encoding. /// @@ -56,7 +54,7 @@ impl Decode for Data { let b = input.read_byte()?; Ok(match b { 0 => Data::None, - n @ 1 ..= 33 => { + n @ 1..=33 => { let mut r = vec![0u8; n as usize - 1]; input.read(&mut r[..])?; Data::Raw(r) @@ -94,4 +92,3 @@ impl Default for Data { Self::None } } - diff --git a/core/src/substrate_types/remote.rs b/core/src/substrate_types/remote.rs index 3d0b41a8..1de799bb 100644 --- a/core/src/substrate_types/remote.rs +++ b/core/src/substrate_types/remote.rs @@ -19,7 +19,6 @@ use serde::{Deserialize, Serialize}; use super::{Address, Conviction, Vote}; - #[derive(Serialize, Deserialize)] #[serde(remote = "Address")] pub enum RemoteAddress { diff --git a/extras/Cargo.toml b/extras/Cargo.toml index d2da5f6d..63e4f094 100644 --- a/extras/Cargo.toml +++ b/extras/Cargo.toml @@ -9,10 +9,12 @@ repository = "https://github.com/paritytech/desub" [dependencies] thiserror = "1.0" core = { path = "../core", package = "desub-core" } -codec = { version = "1", features = ["derive"], package = "parity-scale-codec" } +codec = { version = "2", features = ["derive"], package = "parity-scale-codec" } log = { version = "0.4" } serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0", features = ["preserve_order"] } +syn = { version = "1", features = ["parsing", "derive"] } +phf = { version = "0.10.0", features = [ "macros" ] } [features] default = ["default_definitions"] diff --git a/extras/README.md b/extras/README.md new file mode 100644 index 00000000..318a96d4 --- /dev/null +++ b/extras/README.md @@ -0,0 +1 @@ +Add `StorageKey': 'Vec' in definitions if it is not already. diff --git a/extras/src/definitions/definitions.json b/extras/src/definitions/definitions.json index a40d084c..fb6f8537 100644 --- a/extras/src/definitions/definitions.json +++ b/extras/src/definitions/definitions.json @@ -2752,7 +2752,7 @@ "NewConfiguration": "Option" } }, - "ConsensusEngineId": "GenericConsensusEngineId", + "ConsensusEngineId": "[u8; 4]", "CodecHash": "Hash", "Digest": { "logs": "Vec" @@ -2889,7 +2889,8 @@ "SealV0": "(u64, Signature)", "Seal": "(ConsensusEngineId, Bytes)", "Consensus": "(ConsensusEngineId, Bytes)", - "Bytes": "Vec" + "Bytes": "Vec", + "StorageKey": "Vec" } }, "scaleinfo": { diff --git a/extras/src/definitions/extrinsics.json b/extras/src/definitions/extrinsics.json index 0d9998a7..ea278989 100644 --- a/extras/src/definitions/extrinsics.json +++ b/extras/src/definitions/extrinsics.json @@ -1,62 +1,94 @@ { - "default": { - "signature": "(Address, MultiSignature, SignedExtra)", - "empty_extra": "[u8; 0]", - "OnlyStakingAndClaims": "empty_extra", - "CheckSpecVersion": "empty_extra", - "CheckVersion": "empty_extra", - "CheckTxVersion": "empty_extra", - "CheckGenesis": "empty_extra", - "CheckWeight": "empty_extra", - "LimitParathreadCommits": "empty_extra", - "TransactionCallFilter": "empty_extra", - "ValidateDoubleVoteReports": "empty_extra", - "ValidateEquivocationReport": "empty_extra", - "RestrictFunctionality": "empty_extra", - "PrevalidateAttests": "empty_extra", - "ChargeTransactionPayment": "Compact", - "AccountIndex": "u32", - "AccountId": "[u8; 32]", - "Lookup": "LookupSource", + "default":{ + "signature":"(Address, MultiSignature, SignedExtra)", + "empty_extra":null, + "OnlyStakingAndClaims":null, + "CheckSpecVersion":null, + "CheckVersion":null, + "CheckTxVersion":null, + "CheckGenesis":null, + "CheckWeight":null, + "LimitParathreadCommits":null, + "TransactionCallFilter":null, + "ValidateDoubleVoteReports":null, + "ValidateEquivocationReport":null, + "RestrictFunctionality":null, + "PrevalidateAttests":null, + "ChargeTransactionPayment":"Compact", + "AccountIndex":"u32", + "AccountId":"[u8; 32]", + "Lookup":"LookupSource", "CheckEra": "Era", - "CheckNonce": "Compact", - "Address": "LookupSource", - "GenericAddress": "LookupSource" - }, - "kusama": [ - { - "minmax": [ - 0, - 1006 - ], - "types": { - "signature": "(Address, AnySignature, SignedExtra)", - "Address": "AccountId", - "AnySignature": "H512", - "TakeFees": "empty_extra", - "SignedExtra": "(OnlyStakingAndClaims, CheckSpecVersion, CheckGenesis, CheckEra, CheckNonce, CheckWeight, TakeFees)" - } + "CheckMortality": "Era", + "CheckNonce":"Compact", + "Address":"LookupSource", + "GenericAddress":"LookupSource" + }, + "kusama":[ + { + "minmax":[ + 0, + 1006 + ], + "types":{ + "signature":"(Address, AnySignature, SignedExtra)", + "Address":"AccountId", + "AnySignature":"H512", + "TakeFees":null, + "SignedExtra":"(OnlyStakingAndClaims, CheckSpecVersion, CheckGenesis, CheckEra, CheckNonce, CheckWeight, TakeFees)" + } }, { - "minmax": [ - 1007, - 1045 - ], - "types": { - "AccountIndex": "u32", - "AccountId": "[u8; 32]", - "SignedExtra": "(OnlyStakingAndClaims, CheckSpecVersion, CheckGenesis, CheckEra, CheckNonce, CheckWeight, ChargeTransactionPayment, LimitParathreadCommits)" - } + "minmax":[ + 1007, + 1045 + ], + "types":{ + "AccountIndex":"u32", + "AccountId":"[u8; 32]", + "SignedExtra":"(OnlyStakingAndClaims, CheckSpecVersion, CheckGenesis, CheckEra, CheckNonce, CheckWeight, ChargeTransactionPayment, LimitParathreadCommits)" + } }, { - "minmax": [ - 1046, - null - ], - "types": { - "Address": "AccountId", - "SignedExtra": "(OnlyStakingAndClaims, CheckSpecVersion, CheckGenesis, CheckEra, CheckNonce, CheckWeight, ChargeTransactionPayment, LimitParathreadCommits)" - } - } - ] + "minmax":[ + 1046, + 1049 + ], + "types":{ + "Address":"AccountId", + "SignedExtra":"(OnlyStakingAndClaims, CheckSpecVersion, CheckGenesis, CheckEra, CheckNonce, CheckWeight, ChargeTransactionPayment, LimitParathreadCommits)" + } + }, + { + "minmax": [ + 1050, + 2014 + ], + "types": { + "Address": "AccountId", + "SignedExtra": "(CheckVersion, CheckGenesis, CheckEra, CheckNonce, CheckWeight, ChargeTransactionPayment, LimitParathreadCommits)" + } + }, + { + "minmax": [ + 2015, + 2027 + ], + "types": { + "Address": "AccountId", + "SignedExtra": "(CheckVersion, CheckGenesis, CheckMortality, CheckNonce, CheckWeight, ChargeTransactionPayment, LimitParathreadCommits)" + } + }, + { + "minmax": [ + 2028, + null + ], + "types": { + "signature": "(MultiAddress, MultiSignature, SignedExtra)", + "Address": "MultiAddress", + "SignedExtra": "(CheckVersion, CheckGenesis, CheckMortality, CheckNonce, CheckWeight, ChargeTransactionPayment, LimitParathreadCommits)" + } + } + ] } diff --git a/extras/src/lib.rs b/extras/src/lib.rs index 74c07fbf..d2927e7a 100644 --- a/extras/src/lib.rs +++ b/extras/src/lib.rs @@ -6,6 +6,7 @@ mod extrinsics; mod modules; mod overrides; mod resolver; +pub mod runtimes; pub use self::error::*; pub use self::extrinsics::*; @@ -29,8 +30,8 @@ pub struct TypeRange { fn is_in_range(spec: u32, over_ride: &TypeRange) -> bool { match over_ride.min_max { [Some(min), Some(max)] => (min..=max).contains(&(spec as usize)), - [Some(min), None] => (spec as usize) > min, - [None, Some(max)] => (spec as usize) < max, + [Some(min), None] => (spec as usize) >= min, + [None, Some(max)] => (spec as usize) <= max, // presumably, this would be for null -> null, // so for every spec [None, None] => true, diff --git a/extras/src/modules.rs b/extras/src/modules.rs index df08736e..a80049ea 100644 --- a/extras/src/modules.rs +++ b/extras/src/modules.rs @@ -18,7 +18,7 @@ use serde::{ de::{self, Deserializer, MapAccess, Visitor}, Deserialize, Serialize, }; -use serde_json::{Value, map::Map}; +use serde_json::{map::Map, Value}; use std::{collections::HashMap, fmt}; /// Types for each substrate Module @@ -58,7 +58,7 @@ impl Modules { pub struct ModuleTypes { /// Type Name -> Type types: HashMap, - fallbacks: HashMap + fallbacks: HashMap, } impl ModuleTypes { @@ -78,7 +78,6 @@ impl ModuleTypes { types.extend(other.types.into_iter()); fallbacks.extend(other.fallbacks.into_iter()); - ModuleTypes { types, fallbacks } } } @@ -161,7 +160,6 @@ impl<'de> Visitor<'de> for ModuleTypeVisitor { type TypeMap = HashMap; - /// In Polkadot-JS Definitions, an _object_ can be: /// - Struct (no identifier), /// - Enum (`_enum` identifier) @@ -173,33 +171,32 @@ fn parse_mod_types( module_types: &mut TypeMap, fallbacks: &mut TypeMap, key: &str, - val: &mut Value + val: &mut Value, ) -> Result<(), Error> { - match val { Value::String(s) => { - module_types.insert(key.to_string(), regex::parse(s).ok_or(Error::from(s.to_string()))?); - }, + module_types.insert(key.to_string(), regex::parse(s).ok_or_else(|| Error::from(s.to_string()))?); + } Value::Object(ref mut obj) => { if obj.len() == 1 && obj.keys().any(|k| k == "_enum" || k == "_set") { - let ty = match obj.iter().nth(0).map(|(s, v)| (s.as_str(), v)) { + let ty = match obj.iter().next().map(|(s, v)| (s.as_str(), v)) { Some(("_enum", v)) => parse_enum(v)?, Some(("_set", v)) => parse_set(v.as_object().expect("set is always an object"))?, Some((_, _)) => return Err(Error::UnexpectedType), - None => panic!("This should never occur, checked for object length.") + None => panic!("This should never occur, checked for object length."), }; module_types.insert(key.to_string(), ty); } else { if let Some(fallback) = clean_struct(obj)? { fallbacks.insert(key.to_string(), fallback); } - let ty = parse_struct(&obj)?; + let ty = parse_struct(obj)?; module_types.insert(key.to_string(), ty); } - }, + } Value::Null => { module_types.insert(key.to_string(), RustTypeMarker::Null); - }, + } _ => return Err(Error::UnexpectedType), } Ok(()) @@ -216,7 +213,7 @@ fn clean_struct(map: &mut Map) -> Result, Value::Object(o) => parse_struct(&o)?, Value::Array(a) => parse_tuple(&a)?, Value::Null => RustTypeMarker::Null, - _ => return Err(Error::UnexpectedType) + _ => return Err(Error::UnexpectedType), }; Ok(Some(ty)) } else { @@ -224,7 +221,6 @@ fn clean_struct(map: &mut Map) -> Result, } } -// TODO: Account for 'bitlength' in _set fn parse_set(obj: &Map) -> Result { let mut set_vec = Vec::new(); for (key, value) in obj.iter() { @@ -241,22 +237,24 @@ fn parse_set(obj: &Map) -> Result { fn parse_enum(value: &Value) -> Result { if value.is_array() { let arr = value.as_array().expect("checked before cast; qed"); - let rust_enum = arr.iter().map(|u| { - let name = u.as_str().expect("Will be string according to polkadot-js defs").to_string(); - EnumField::new(name, None) - }).collect::>(); + let rust_enum = arr + .iter() + .map(|u| { + let name = u.as_str().expect("Will be string according to polkadot-js defs").to_string(); + EnumField::new(name, None) + }) + .collect::>(); Ok(RustTypeMarker::Enum(rust_enum)) } else if value.is_object() { let value = value.as_object().expect("Checked before casting; qed"); // If all the values are numbers then we need to order the enum according to those numbers. // Some types like `ProxyType` in the runtime may vary from chain-to-chain. // So afaict Polkadot-Js types solve this by attaching a number to each variant according to index. - let rust_enum = if value.values().fold(true, |_, v| v.is_number()) { // TODO: TEST THIS AGAINST PROXYTYPE - let mut tuples = value.values() + let rust_enum = if value.values().fold(true, |_, v| v.is_number()) { + let mut tuples = value + .values() .map(|v| v.as_u64().expect("Must be u64")) - .zip( - value.keys().map(|k| EnumField::new(k.into(), None)) - ) + .zip(value.keys().map(|k| EnumField::new(k.into(), None))) .collect::>(); tuples.sort_by_key(|(num, _)| *num); tuples.into_iter().map(|t| t.1).collect::>() @@ -266,13 +264,13 @@ fn parse_enum(value: &Value) -> Result { match value { Value::Null => rust_enum.push(EnumField::new(key.into(), Some(RustTypeMarker::Null))), Value::String(s) => { - let field = regex::parse(s).ok_or(Error::from(s.to_string()))?; + let field = regex::parse(s).ok_or_else(|| Error::from(s.to_string()))?; rust_enum.push(EnumField::new(key.into(), Some(field))); - }, + } Value::Object(o) => { let rust_struct = parse_struct(o)?; rust_enum.push(EnumField::new(key.into(), Some(rust_struct))); - }, + } _ => return Err(Error::UnexpectedType), }; } @@ -292,22 +290,24 @@ fn parse_struct(rust_struct: &Map) -> Result { let field = StructField::new(key, RustTypeMarker::Null); fields.push(field); - }, - Value::String(s) => { // points to some other type - let ty = regex::parse(s).ok_or(s.to_string())?; + } + Value::String(s) => { + // points to some other type + let ty = regex::parse(s).ok_or_else(|| s.to_string())?; let field = StructField::new(key, ty); fields.push(field); - }, - Value::Object(o) => { // struct-within-a-struct + } + Value::Object(o) => { + // struct-within-a-struct let inner_struct = parse_struct(o)?; let field = StructField::new(key, inner_struct); fields.push(field); - }, + } Value::Array(a) => { let tuples = parse_tuple(a)?; let field = StructField::new(key, tuples); fields.push(field); - }, + } _ => return Err(Error::UnexpectedType), } } @@ -320,10 +320,10 @@ fn parse_tuple(json_tuple: &[Value]) -> Result { match value { Value::Null => tuple.push(RustTypeMarker::Null), Value::String(s) => { - let ty = regex::parse(s).ok_or(s.to_string())?; + let ty = regex::parse(s).ok_or_else(|| s.to_string())?; tuple.push(ty); - }, - _ => return Err(Error::UnexpectedType) + } + _ => return Err(Error::UnexpectedType), } } Ok(RustTypeMarker::Tuple(tuple)) @@ -337,7 +337,7 @@ mod tests { use crate::ModuleTypes; use core::{EnumField, RustTypeMarker, SetField, StructField}; use std::collections::HashMap; - const RAW_JSON: &'static str = r#" + const RAW_JSON: &str = r#" { "runtime": { "types": { diff --git a/extras/src/overrides.rs b/extras/src/overrides.rs index b3ae0588..8ff0ea62 100644 --- a/extras/src/overrides.rs +++ b/extras/src/overrides.rs @@ -1,4 +1,4 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. +// Copyright 2019-2021 Parity Technologies (UK) Ltd. // substrate-desub is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or diff --git a/extras/src/resolver.rs b/extras/src/resolver.rs index 91d54a89..bde37519 100644 --- a/extras/src/resolver.rs +++ b/extras/src/resolver.rs @@ -119,24 +119,22 @@ impl TypeResolver { /// # Return /// returns None if the type cannot be resolved pub fn get(&self, chain: &str, spec: u32, module: &str, ty: &str) -> Option<&RustTypeMarker> { - let (module, ty, chain) = sanitize_types(module, ty, chain); log::trace!("Getting Type: {}, module: {}, spec: {}", ty, module, spec); - if let Some(t) = self.check_overrides(&module, ty.as_str(), spec, &chain) { + if let Some(t) = self.check_overrides(module, ty, spec, chain) { log::trace!("Resolving to Override"); Some(t) - } else if let Some(t) = self.extrinsics.get(ty.as_str(), spec, &chain) { + } else if let Some(t) = self.extrinsics.get(ty, spec, chain) { log::trace!("Resolving to Extrinsic Type"); Some(t) } else { log::trace!("Resolving to Type Pointer"); - self.resolve_helper(&module, &ty) + self.resolve_helper(module, ty) } } - pub fn try_fallback(&self, chain: &str, module: &str, ty: &str) -> Option<&RustTypeMarker> { - let (module, ty, _) = sanitize_types(module, ty, chain); - self.mods.try_fallback(&module, &ty) + pub fn try_fallback(&self, module: &str, ty: &str) -> Option<&RustTypeMarker> { + self.mods.try_fallback(module, ty) } /// Get type for decoding an Extrinsic @@ -156,7 +154,7 @@ impl TypeResolver { log::trace!("Helper resolving {}, {}", module, ty_pointer); if let Some(t) = self.mods.get_type(module, ty_pointer) { - log::trace!("Type {} found in module {}", ty_pointer, module); + log::trace!("Type {} found in module {}", &ty_pointer, module); Some(t) } else if let Some(t) = self.mods.get_type("runtime", ty_pointer) { log::trace!("Type not found in {}, trying `runtime` for type {}", module, ty_pointer); @@ -190,26 +188,27 @@ impl TypeResolver { } } -fn sanitize_types(module: &str, ty: &str, chain: &str) -> (String, String, String) { - let module = module.to_ascii_lowercase(); - let chain = chain.to_ascii_lowercase(); - let ty = if let Some(un_prefixed) = regex::remove_prefix(ty) { un_prefixed } else { ty.to_string() }; - - log::trace!("Possibly de-prefixed type: {}", ty); - (module, ty, chain) -} - impl TypeDetective for TypeResolver { fn get(&self, chain: &str, spec: u32, module: &str, ty: &str) -> Option<&RustTypeMarker> { - TypeResolver::get(self, chain, spec, module, ty) + log::trace!("Getting type {}", ty); + let ty = regex::sanitize_ty(ty)?; + let module = module.to_ascii_lowercase(); + let chain = chain.to_ascii_lowercase(); + TypeResolver::get(self, &chain, spec, &module, &ty) } - fn try_fallback(&self, chain: &str, spec: u32, module: &str, ty: &str) -> Option<&RustTypeMarker> { - TypeResolver::get(self, chain, spec, module, ty) + fn try_fallback(&self, module: &str, ty: &str) -> Option<&RustTypeMarker> { + let ty = regex::sanitize_ty(ty)?; + let module = module.to_ascii_lowercase(); + + TypeResolver::try_fallback(self, &module, &ty) } fn get_extrinsic_ty(&self, chain: &str, spec: u32, ty: &str) -> Option<&RustTypeMarker> { - TypeResolver::get_ext_ty(self, chain, spec, ty) + let ty = regex::sanitize_ty(ty)?; + let chain = chain.to_ascii_lowercase(); + + TypeResolver::get_ext_ty(self, &chain, spec, &ty) } } diff --git a/extras/src/runtimes.rs b/extras/src/runtimes.rs new file mode 100644 index 00000000..964196e1 --- /dev/null +++ b/extras/src/runtimes.rs @@ -0,0 +1,150 @@ +// Copyright 2019-2021 Parity Technologies (UK) Ltd. +// substrate-desub is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// substrate-desub is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with substrate-desub. If not, see . + +use phf::phf_ordered_map; + +pub fn kusama_upgrade_block(version: &u32) -> Option { + KUSAMA_RUNTIMES.get(version).copied() +} + +static KUSAMA_RUNTIMES: phf::OrderedMap = phf_ordered_map! { + 1020u32 => 0, + 1021u32 => 26669, + 1022u32 => 38245, + 1023u32 => 54248, + 1024u32 => 59659, + 1025u32 => 67651, + 1027u32 => 82191, + 1028u32 => 83238, + 1029u32 => 101503, + 1030u32 => 203466, + 1031u32 => 295787, + 1032u32 => 461692, + 1033u32 => 504329, + 1038u32 => 569327, + 1039u32 => 587687, + 1040u32 => 653183, + 1042u32 => 693488, + 1045u32 => 901442, + 1050u32 => 1375086, + 1051u32 => 1445458, + 1052u32 => 1472960, + 1053u32 => 1475648, + 1054u32 => 1491596, + 1055u32 => 1574408, + 1058u32 => 2064961, + 1062u32 => 2201991, + 2005u32 => 2671528, + 2007u32 => 2704202, + 2008u32 => 2728002, + 2011u32 => 2832534, + 2012u32 => 2962294, + 2013u32 => 3240000, + 2015u32 => 3274408, + 2019u32 => 3323565, + 2022u32 => 3534175, + 2023u32 => 3860281, + 2024u32 => 4143129, + 2025u32 => 4401242, + 2026u32 => 4841367, + 2027u32 => 5961600, + 2028u32 => 6137912, + 2029u32 => 6561855, + 2030u32 => 7100891, + 9010u32 => 7468792, + 9030u32 => 7668600, + 9040u32 => 7812476, + 9050u32 => 8010981, + 9070u32 => 8073833, + 9080u32 => 8555825, + 9090u32 => 8945245 +}; + +pub fn polkadot_upgrade_block(version: &u32) -> Option { + POLKADOT_RUNTIMES.get(version).copied() +} + +static POLKADOT_RUNTIMES: phf::OrderedMap = phf_ordered_map! { + 0u32 => 0, + 1u32 => 29231, + 5u32 => 188836, + 6u32 => 199405, + 7u32 => 214264, + 8u32 => 244358, + 9u32 => 303079, + 10u32 => 314201, + 11u32 => 342400, + 12u32 => 443963, + 13u32 => 528470, + 14u32 => 687751, + 15u32 => 746085, + 16u32 => 787923, + 17u32 => 799302, + 18u32 => 1205128, + 23u32 => 1603423, + 24u32 => 1733218, + 25u32 => 2005673, + 26u32 => 2436698, + 27u32 => 3613564, + 28u32 => 3899547, + 29u32 => 4345767, + 30u32 => 4876134, + 9050u32 => 5661442, + 9080u32 => 6321619, + 9090u32 => 6713249 +}; + +pub fn westend_upgrade_block(version: &u32) -> Option { + WESTEND_RUNTIMES.get(version).copied() +} + +static WESTEND_RUNTIMES: phf::OrderedMap = phf_ordered_map! { + 4u32 => 214356, + 7u32 => 392764, + 8u32 => 409740, + 20u32 => 809976, + 24u32 => 877581, + 25u32 => 879238, + 26u32 => 889472, + 27u32 => 902937, + 28u32 => 932751, + 29u32 => 991142, + 31u32 => 1030162, + 32u32 => 1119657, + 33u32 => 1199282, + 34u32 => 1342534, + 35u32 => 1392263, + 36u32 => 1431703, + 37u32 => 1433369, + 41u32 => 1490972, + 43u32 => 2087397, + 44u32 => 2316688, + 45u32 => 2549864, + 46u32 => 3925782, + 47u32 => 3925843, + 48u32 => 4207800, + 49u32 => 4627944, + 50u32 => 5124076, + 900u32 => 5478664, + 9000u32 => 5482450, + 9010u32 => 5584305, + 9030u32 => 5784566, + 9031u32 => 5879822, + 9032u32 => 5896856, + 9033u32 => 5897316, + 9050u32 => 6117927, + 9070u32 => 6210274, + 9080u32 => 6379314, + 9090u32 => 6979141, +}; diff --git a/integration_tests/data/extrinsics/kusama/spec1020_block10994/EXTRINSIC_spec_1020_block_10994_index_0.bin b/integration_tests/data/extrinsics/kusama/spec1020_block10994/EXTRINSIC_spec_1020_block_10994_index_0.bin deleted file mode 100644 index 089477f02705fd012945fa31f8d7cf91ed1832f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 TcmdO3VPfERnEiKK9wQe35d{N5 diff --git a/integration_tests/data/extrinsics/kusama/spec1020_block10994/EXTRINSIC_spec_1020_block_10994_index_1.bin b/integration_tests/data/extrinsics/kusama/spec1020_block10994/EXTRINSIC_spec_1020_block_10994_index_1.bin deleted file mode 100644 index 7c908071cb6acd12237953bd065683e31b6a044c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7 OcmWe(;bb_tnhO8~djXgL diff --git a/integration_tests/data/extrinsics/kusama/spec1020_block10994/EXTRINSIC_spec_1020_block_10994_index_2.bin b/integration_tests/data/extrinsics/kusama/spec1020_block10994/EXTRINSIC_spec_1020_block_10994_index_2.bin deleted file mode 100644 index bf51eab782a4c1cb186ebc426ce5c163aff84280..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6 NcmWe&5n*890ssKi05bpp diff --git a/integration_tests/data/extrinsics/kusama/spec1020_block6144/EXTRINSIC_spec_1020_block_6144_index_0.bin b/integration_tests/data/extrinsics/kusama/spec1020_block6144/EXTRINSIC_spec_1020_block_6144_index_0.bin deleted file mode 100644 index c024bb4f55efcb8b890ab859c07ebb0da77ae598..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 TcmdO3VPfDmkaOIc$H)Z$3HJf_ diff --git a/integration_tests/data/extrinsics/kusama/spec1020_block6144/EXTRINSIC_spec_1020_block_6144_index_1.bin b/integration_tests/data/extrinsics/kusama/spec1020_block6144/EXTRINSIC_spec_1020_block_6144_index_1.bin deleted file mode 100644 index db39ca2c7629a07f22e16a0cb27deb4192dce22a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7 OcmWe(;biz3&jkPkivffH diff --git a/integration_tests/data/extrinsics/kusama/spec1020_block6144/EXTRINSIC_spec_1020_block_6144_index_2.bin b/integration_tests/data/extrinsics/kusama/spec1020_block6144/EXTRINSIC_spec_1020_block_6144_index_2.bin deleted file mode 100644 index bf51eab782a4c1cb186ebc426ce5c163aff84280..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6 NcmWe&5n*890ssKi05bpp diff --git a/integration_tests/data/extrinsics/kusama/spec1020_block6144/spec_1020_block_6144_METADATA.bin b/integration_tests/data/extrinsics/kusama/spec1020_block6144/spec_1020_block_6144_METADATA.bin deleted file mode 100644 index c2522c5e5da35eda6deda22d855c8588910db014..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61379 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 diff --git a/integration_tests/data/extrinsics/kusama/spec1030_block233816/EXTRINSIC_spec_1030_block_233816_index_0.bin b/integration_tests/data/extrinsics/kusama/spec1030_block233816/EXTRINSIC_spec_1030_block_233816_index_0.bin deleted file mode 100644 index 4186ad7171565bae4cb66bba802f6af1242937da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 TcmdO3VPfFEu5jn diff --git a/integration_tests/data/extrinsics/kusama/spec1030_block233816/EXTRINSIC_spec_1030_block_233816_index_1.bin b/integration_tests/data/extrinsics/kusama/spec1030_block233816/EXTRINSIC_spec_1030_block_233816_index_1.bin deleted file mode 100644 index 4ba355eb8e6af874b496208ac4a7f3424245dea3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9 Qcmb1P;be$%eZc_hm~`a_7Fm~ft>QyJ8c>V@4k08V5968J-y?Z6-06_AV*<#X>K4&VQpn|AXjg1WB>pG000W)`8oLj diff --git a/integration_tests/data/extrinsics/kusama/spec1030_block233816/spec_1030_block_233816_METADATA.bin b/integration_tests/data/extrinsics/kusama/spec1030_block233816/spec_1030_block_233816_METADATA.bin deleted file mode 100644 index 309237965ac4a5c82448f8c7af3ce13e5a9eb5dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 69792 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 diff --git a/integration_tests/data/extrinsics/kusama/spec1031_block342962/EXTRINSIC_spec_1031_block_342962_index_0.bin b/integration_tests/data/extrinsics/kusama/spec1031_block342962/EXTRINSIC_spec_1031_block_342962_index_0.bin deleted file mode 100644 index a202bd8dfca7b9419e65ee6e99e9067a83f0b92e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 TcmdO3VPfEJc(>UgpOFgy5ikP< diff --git a/integration_tests/data/extrinsics/kusama/spec1031_block342962/EXTRINSIC_spec_1031_block_342962_index_1.bin b/integration_tests/data/extrinsics/kusama/spec1031_block342962/EXTRINSIC_spec_1031_block_342962_index_1.bin deleted file mode 100644 index bf51eab782a4c1cb186ebc426ce5c163aff84280..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6 NcmWe&5n*890ssKi05bpp diff --git a/integration_tests/data/extrinsics/kusama/spec1031_block342962/spec_1031_block_342962_METADATA.bin b/integration_tests/data/extrinsics/kusama/spec1031_block342962/spec_1031_block_342962_METADATA.bin deleted file mode 100644 index f34a5e839ca13a569d7029cec0fab441332a07de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72894 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 diff --git a/integration_tests/data/extrinsics/kusama/spec1031_block422871/EXTRINSIC_spec_1031_block_422871_index_0.bin b/integration_tests/data/extrinsics/kusama/spec1031_block422871/EXTRINSIC_spec_1031_block_422871_index_0.bin deleted file mode 100644 index cd97207f5310d859277798d0fe2773cddc848d5f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 TcmdO3VPfD`2xs%lXXF9^2ps`` diff --git a/integration_tests/data/extrinsics/kusama/spec1031_block422871/EXTRINSIC_spec_1031_block_422871_index_1.bin b/integration_tests/data/extrinsics/kusama/spec1031_block422871/EXTRINSIC_spec_1031_block_422871_index_1.bin deleted file mode 100644 index 7f0026b8aeaff41efa30e0d9f920326277603e6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9 Qcmb1P;baIqFUi0K00yH0asU7T diff --git a/integration_tests/data/extrinsics/kusama/spec1031_block422871/EXTRINSIC_spec_1031_block_422871_index_2.bin b/integration_tests/data/extrinsics/kusama/spec1031_block422871/EXTRINSIC_spec_1031_block_422871_index_2.bin deleted file mode 100644 index bf51eab782a4c1cb186ebc426ce5c163aff84280..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6 NcmWe&5n*890ssKi05bpp diff --git a/integration_tests/data/extrinsics/kusama/spec1031_block422871/spec_1031_block_422871_METADATA.bin b/integration_tests/data/extrinsics/kusama/spec1031_block422871/spec_1031_block_422871_METADATA.bin deleted file mode 100644 index f34a5e839ca13a569d7029cec0fab441332a07de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72894 zcmeIbJ8)dtndh0Q&fbN#(Xr45JC+@Rj=0iLTZtOrHcO4}U{f3}A3zl`#a9zxRrPc! zkO|}kkknFvTQaP0(BGPP@#gb69+%*u8Re>1qQA{)cAuBzrt`I*hXRLHBTy zb%*8Ay)?=CLJ3XUpH4Epyp*5!tuz}mdvm<`H1M1~<*@i{r|1tKWryR@ZZVk@y*%42 zz=PwgQ#>nnkEX@8;Y25I-|q@V41|pcvUi>bEq&KI%=CspCOkVF7f<@5qe(!t5??0| zMx$x-V~h(9CLm9;F>l8?YPh_dbqAACcGw-K?`=QXe$nj}FmgRRja%%u6L=3ILz zp6a_=cDqg_%f3dNZs}^X)mZ&}Q^as6?Aa-%Pm5xhbwNso%i80Dlb!$swgN7N%`Sn+ zJsx^e>`q}@EYUEzn0)n=9-8VyQ3jc>K9_AtmkN=?R3V)!RSe` z%^vpp&pLVI@0uCBDs0YIKgssHPYNcO7UP5d5P-7p3ES#EDl&LYciJBfwSdE7*wdgR zKL!JkFLS*Kat=mMC!7Zyc4c?KI-qC>d%)S*NFtiu{q7JX&EWh+nqoTc?mpJI2Zg@x zPYwj!pX;=DyA#_?d~dIq?(Q27=-exywgX`O5J29z+rdVE-9o#&xK zhr{3P9x-EoFMC=5L7+Vv4vr1T460!q_Y8MB`e2xr$xAkmp-r51(mi0;Bd|x{2!Iz8~XxiWFJDjtpeU4{`^^W_G9}BF9SFjDVlZN}&BgW}Z#Zjf zv_8x6W;^{yS+74i>^iWzQy-L%?2v%&aW-PWF_UzMlkTn#SZBqc{o(H5s0Z^r59V~o zk6Vk|{!8TftpT+1nA01vv(a#cqv4?Znf%hEm~O+54z~|Mo=NMR{g^-co7L8Dj2mkk zC0X0I0-!#Av)H)~+dkL<;KlGse>@rGtlZSG4Ab#nZH!Tjj9DQy|?d z@?||4@V9ji9&|8S6&rZHIDSJYag{AdGT096Yavp2A;0)o;Eb;?K%0{+ynVIxEPGwY zQ+ac5JUU44F5A0KYpwJCbDn9XX4s3sKR%4aV_}>ONSF zDvirUSg4LjupD&Z8JAvh(i2GmZ;&6Q1hH#t0?B~YL72sP8zaMhyJMbs#FsqV%}`ts z6-Rq}(2$*A$3*dVK<&>ni@1rN(!?ek_!kn>pB>iTVV!IC*J#j#Yl%I+|b#~}Bdf7-5h_^KTvgr!M^c{wO#FK6~h-dN859cag={poSzk0o~4)SZW$ zTiM-vTVkgsLuA-I>cZH-2ede}-YJp|J3yGR2S-9=n{v_pHMlqE@0wnT`0Aq(^KM{} z6Al(r1Rp-{<#XWBh71fAMHm*5_0NK(JOi^V$vNSyX_UU zqlp+Aj5DrbWp@M&{;3#`Rvr&WPvL3kF6@4^hbeg%dHdTTMCx^0#W-znB z%%o+Ss^jKkj>5p}dJGK#0@x+c)ps-Q0Tc z@aERWy}R3+>#yBezq_@4d;RWfTer{?f0^BrBH4`tfG6Eu3_@n*0DU#f(vo%x_`a>h z)EZDK$3|n3(wbokl6Y|q+ReC_9*s@g=v?fGXJ{KX$WV9&;TzU11`=C)C>Y+XY%tiM zCekBi%MxuYZw%pkP|ZITy+#8q<#?xfW4zaD%mKBn;@}XCc6^+hGT$CSpMz9l` zjmF&Sx;XaQ(b!%#e)`s@oGs0P@mm0-)RA6(S&VJ+^2-29@(S^8{C)}wO>zMm{|AHz zlqVBY)Tg80_%l#_KgW>Zl#KI=22qm2gHSUEEa>Y)AJooalCP~lJ47rOy&G~hZ1oR{ z3y9h~00RB<@PGBCo-=+2lL*gd7!juEJA|gZRf>cg*Ke$6Ft8(x8Q9(~pqg^rpJ@hR zjIEC5S!DK{ILmmn)7|L{^%(b1HJJQZxTm*=gfoPVe5 zy1l(3_=2*%a2`f;8fp?4yG(A>co=WiL2kF5pLJfzRxl3w!io+=NxCu@ML92_8fMlC>Ln55ba$72vpZnDd zZ<*FyomhkBjlU0aPdHyWQE1W>3fPJyg2;_&sXI|-FLF3SR!zX?8(meb7(Gfh%WwPW>9D17^{eG1(zlGd+}U^neDi;B7fu>#B~VJ)Q4ySyPJdcV&Oz6V5s(rz3$O~ z11hHCA(OnZh#2l8F`Mz1xn+s%b+{;oUb7)Aj-F^a9HR?*3m}-(+8Y+uT%%h4--E#gDu0 z2nWUGAbl#U1NJUUD^H3hf|8Tw*aK$_{sQ{xAr>ixJPb7od~Y z0)93y5e8j&@uZo4JGW|1_l?QqNZ;VF1EArtYmrOEpLmu9*QvSbkC2nX%*hdS6!Zkg zog5S1me-hx6nr~;zKOcgI~o*%eVEI9jW;Bd?wY&Wp#IZLmhTv&O#Htw5bn6;{X_7d;Awd8* zWGf#VYOMLe1*VFF1sy^NBPx4{I1c;SgP@TM1x`I%ylYLsv9m6;0`U;TYiJEPc{|H` z#2M;KQ78pCzr<1r5%dakLtKtrRjeGxeB}%}FoB~n<6xp_Bb|H0%D4Xs&Awv-UV>nM}PH$?PVoI&I?+U+9^dd9D|Y|^mI zNPT$&fOqyJ{kI)!6Cbf4S4Yb*uY7zFQPp{X;)^r4cf&zhJ|y#m0Faboj4NU5YU zFmy?2HoY^h$sbgEW6^JivfH z$lV3^Z=(^-Ey&0AzGk>R8a;*wAW%1_u-IMy`|9P(ncQ>aDcE464>zEGr%NeN^WimhyrzI;`BGDukzh#zGc97NH6 zb}(<`ehZUAN%@M88WF|a+d&N!Hx0*XGHA*vYSB_B6olI;0AAsE zZQ-+@utNUpKy3GhrQUn_@@Tk?YP%fx8s?S_&>h%hN5eptJseE{+E-K|IcXL4q-c0MJiIL-+{rfrpd)^7 zKQ4;HZ9GIz3Wyjp$CWw@@BwnsMoHx^J`CKfx(ByH>FN%CZA(S3-F*z529HIYz#%BO zDvD%u9E{4a?Ywajck`9M4A^gBuCV6$`KSA%7h!L*Ew;7W(>UBkeHlghX%DP^HMs!7 z#HO-#LzF756K=I7J;1m?cK{C7RXsnA2X&Lklu!O2L0+qnO?h7vsF4v zIlL!uJoe}88V5?;XJXwS#r>9>Xq~}lp_iS5N0jswruOqBF^-?_z5o|w9UUcsV2dfd z5SiUO;xy20;&#r&6UWPczymiw4j;;E=yVAx-YvExHqM`)m^^$Dr1}Je>l}P-JvfSH zD5-e1TO2yD13g5yilxekuubOKaubU7(DlnHc`l#XD%P~8gpLJ!CdE=HX5cP~f?{|--RF$5i)|wn~%ykEyv42Qf&=~Jg z`A1gS!d!Kv8)&$^b}^iuC9_>?%|6ExahZo{9g2xL_g`&BlT+fWilc19~LM(o=PqIVh_xbY=NxMibKWETjYiF@MLeLF`8VPs(NSYw;GCR~ z9wZXi5d#Px$~gqs#zY#mLSjkidNI@`A~7G6WT%#xH(PB!-1diCZ7CG~`=#J9y=BRY zS6Rt@cQK=oY8V#e4=M*@5z|cP*NngHUwR`(!$ZoT(oo%v`z^x(EPcE^rP57w#V|nW zk_6NVGE67=R&c$aIv5eeMhll+c;+L0QEfOy<4ypwP0Y|k2Qp6%JlqUx z+C$2Io3Sce@>EDPA{27P3^f^6&UA>QCqI7!s1&_fA8!pW8z3gSmC})2(MS6gGBMQW zIL68T=ORZ0ES^Clduy!Rp_DP6pTDh`|9Ez$Zw6HIZ$(RqWRwhJo^E3<=3&6GSX)N> zXy_|h%05@ld2&6Zag1QQRo8Ps!2BFMu{eYASnD?)CTT|PmS#X zIGSu~z2B2iTI9VF(gNz)|eC&ymDzfpB|?i?TDRc3gbZZuV98(iO*7;gSq|JMiW z&tMT)@im~#V&yz+X#qMe;cEh}Yl-0f-6N8MBYF77m>iz$B9BBhC5sZ!wLqSBOzadV z1kr^8yJ)&UHZ!{dKp~)OtkNz8B4V?^1;k70ZO(2@)fIp zy5Rb;j~9SxYbg^Z1i;GZJ}s>Nt#X$8q&!V0>)kPKZ1M)!tbcOOmy5>YOs33Vs|=WD z4=q8QX%#uGDg+VckXwFXlk5ec@|d9Cj4l?y5`WCU;)Gm=5u!RRRD4p%*=6aiWIjnl zD@Z3Q3D>eDmg9~|QEhx5=r~f9fi6fmGDdf(9TH!h?3>5WV#vD%P@wkWRSC%9BUl}Y zJ6mJYzzM1dq!#Us2{4{j?p_L%N6(HCUN|R5TpL^*OKxu}is2A_Rnas^o0;wxW71Rx zcB1pYwi89H?#i=B23qvT>eWP@I6)DW_~RfI}aNP76{li#CErg3al{ z5v;ghic8q!S{3U4xJwuYVL-CgZhyRcbO6nm*l1g<{}BZV#OC;9DZln`NYVjjfiD~d z2~B`AG^+W~mEr0G&tsJ)!Lj3D-A8fMpfv@3N_yFsj|#=2g@W?wjxi8TMPX93v#F+R z#|11$R%gqxJlW4H!5+bB#Uds=Et<5lV}pnhBqhc3StGI;7WuJ42RxVGej}=Tc4!+z zrfqzx+u(sQio{VaZj!-#hcJ-}L!J;<*KtdMW)F>v&Knc@{qvNASLIl8=8|1i`|)pgEy zBKth+=N!Rve^X-J)OB&5tcw@loni;wXO<>pvjsA>l`AeFO`t>!?QQvca#TGnKp1|K z6`UO?lQyWEa#>qym08kEk-vq2fj%dghE+mrl+qRWx!5M5(w;QgDgp~ELPa<*Zd4W` zHGqA2mOk@Ko32s40UI>FTAFuKE|kb&Uub(#`O*YIZOfb2Fj$AZ`F5$Kzlh_~gMC{u z*jGCmN>|X^PwMGcq_8S|SK_4Zq7y)YwxbQ?Bhx|o1|7pxW&ERh0bjQ|afZIXmcjtY#?~b$cDoD;osNE&K(p&T zSg^{h90);9oAu%Z1w&^mWnz_K9wCS_n5Cdfu$iMec67KJ*_%8hRucHo!pTy%Oicnj z0#Uif5Ql@CpjZ(8u5w04QgcP4i%GC(uQ}^~IJ7E)f9U9g&X=GT9MS~k{4X<;VnCIW zMwCzmzua#ESQY6flxoJYWkHE9EH(3XpbKmhsck*%w!HE1cgEypn_tIY(q$d1fANu6 zy+MNGqoGyvp(34z+Si2RWN-zPKCa`*c?VDHd7SBOwi=V;#8h2km!x32rny6-_X6&& z%ye-~^M@*hLE@vkr_h{stTRFLLUmQDDQsHlX2JzrULDNfk~m)TcDpQ%An;? z+@xeLmoLw-qV^L0c`KPTUlWch))g|JvPmxIp2~JuGT`0Y{ zLU&(-+-@RfpP!u}ZncuF%Oo{qqUzg1D6$)5aUSrxa&iJ71KvlDDwfAicLeVf;&+YhC}y5`QNTj8owP(Gf)pj_r{l(%`y?f2O5!wMo;d^%(&@}4=}7&ftV#4zKMwO6 z1S@$)UXheOx@{#R=37@#-@*g`Vx*vY;~7$jVz7??(4x>aRLNAxz>{k`Q7ws4f73pa z4qt_2fU+@}d>tg&FwrXg-1N@L$U+ST+|oVVXrNZSIT(#-(*Y`zvvC6dsQ9vn`jcNN zS*mC5P>62^g>u_(Mb=C5n3_s80QJN9vG4Pv$PyMG(kvzvb&2|XdMcj0jtJ)`UY1nN z(}4pL1L)*G1dMNbvXvB>n3Dx*7{(i!qQ&T5v) z@1WtlAgBGEk0!eJTZ?#NrFnltJ{viPJ|eaA>hforXPjFclN2r=6U|@B(!aqIL`z$Hynx?)Op+#^hflL5OJ!L48gZ7I+?hjoHGx4VxQwXyuebU=h1OS&p>Wx$XU zd2u%J$o~5!s4bHPfkz^~O+o#gS=$B0=gkmScaBqC9Jq+u4~mr~#oI&zJZ1{A(}qz7 zwH8rf_ybG(U0IrSO)25o`j}p<0RcPYC(sL}kb;s2^DV(a5QW z%JS@ba251bR35TmcZzSolZ;EKi4mD3B#w{>yJB1HEnyYmr=pp~Oy2(U7rrJy*D_36 z?Gk=#682T!`_m5(90FoV3c1OPSPIQCB)(-&i8DW1X+sgn3|TjvZ-YXKK! zd^y12b)nOWJ#6JgUYHf6s*VQx#=fP>sef=#^i)~Kf!#MySlTE0{^BXFifAPZz z5v1p#!hKLdPNitynIE)<4qE_&7~M9=RL~%?w{0Mqn`c!i-nMF=0ecS#3(~^rMa+kr z_BM_o6bh3C##!QE4&Pi)$r28(2n7ROZcB(*CS_2EM`M|6n0_4OreZNZ{5?x}?c_j5 zi4^jv=qW8x3PoI3Fv9&zV{jY%)pO`F%AT(iiUjEi=+vpDIe*?myK^ziH2zd(@^$=6 z72GoCt3^pXY64;fLo>9naRT#+ zu)()&(G>Uem^YL|g?97y>fO=wX3}+9`>;kOD4wcZu^r8Rnus8wCD!6u%y*0S`0Nvdc08u^a0f(>{5 zq4zwx3bv?oq(5i=XHL?Jk?1&rNK__Oj^)Jto-@ zD-qgGjt(ueCqe7L8|dJ2CHYWK^~m6I8HcA+E5Q?M4U8=4WsM^i1H#RncBFIeyJsXZ z5qNV#o-na(DmD@92(X<5z<7q8z)U6gi)U6T_qQ|v)59yFdS-XY55Nu?JZ3h}0pb_! z6h~#H*=sMdh@f^6vn8Y3)7;4D_FopO8LN%kL92uEJpr18c5w46Ml(tKLd#=AfIcKi z=NE6fVz!}`pPFL_?+m(|?N09-TKgjM)xWcBpqs?5=GvsjwepwR;pBEWk6za+1uIndFk$_6fi zTv{zYrGPm0UVaO;LBW?^S}PmKjDlnrHRj(@`C801L^-gB%kjXHzxK_@pa8KH#87bi zsUn6QYDXiUdJ>5`FR7Clh;PP{-r{u2V?iDhHy5NDpK3++qn^@ffg8O={?rpN!iBFJ zB&$}BZ7jGu(!N8#BV4?xcdv-g6#J~Rw!Zf8{`TwZf4_bI!TPHkZ&?h|gY~dE0Z>h@ zBL*1z+`&&r+-bB&Vw4_GnnO;jY42&lTW7ry+8U{a5i&s>_^A-EM_+@`-W9a4oC#%% z-=o{XxB`j$Z9d$BVW}%*V023};1O6*HMdxmnk88L%X*cngCp$LRolmKWk8^{chZ=h z?BClbNLCU(dIIIYMaVT)I?qpZnkFIrybZtCz#bmkl)vl3kR@z(^%qzKq z)63b~IwI%h^{w@_29m^BK@{O~ z3yDZ@%>-@8PhL$_U~e(1o02~v0_o*B@@(y7ypX zYkgDV4i3ZHH2E<`e-6u5Z3qXOnz(0w$!S+bM%23xtObk3bkeSs*K|%4QE<9L-w81dtk3wOQs(Iz;9y)_pEcQc>#8wYW zstIrnl|+y`Zd^PAHl9`eC?luQc*n|iOFA?St^$fB0|iy%M|76JK^csLa8$S!aU*D? zr0ybWHc(d2+0P8(vj673G)rN=67rFD6rB@N(mU8pJ25Tushy_T;?g~&RI9J{o6>KW zeh~GQ&w(tT6T1k=SqdNcp1N$S6(EhG)gG5625ycK?MtmWbua{5|EFxvXmI%ej{d?* z%6VdF(ztizgD+c$H0K^KC!ru_8*&p6nz5y^Rja1`(7UPGy5$Dr_CbFV+|y(0aWAG4 z#W@ZT=Q5r?Re3aT&eKl#X{0`&)0!d04@_3o=*yIUbHs%V>iqnD-80Z@w7#C~lQZ5p zv5)&+D-uT8xy}@?%WDZZTSwf5VPXlWLuef;xRi}kW%(z=wj%(VY#QIwLrcS8w z$+xn0@aX!oWckEeVEh7d!1+*1`9)uFnEcP4H@PqP`Lp|c-%RssHK)z)W8vR-b`f|$ z>zB{jyHkm~8Wd%n*-*Z?H5zS>M#I+kazu%hK0F_I?lvYdZx z!$fW`YJzHw>P`5ou-KY1!mntPKc4Q;6hQ79Yd6)SNZUWcbZXY9_JZcYjw_x;TERw` z`?;bSUePt9aItLfYLLjBb#&4oo%e-|9sCwRu|K3?kh!ex((05BJ0>?e`6b_5=tisy zUTRAc7%L{7DhHYdOVu}hymi$_G93+a_+dq9v4eqiT6cU7KluHFM?Lh+KZea*NMM~S ze=Pw!E3w+!Mv?LeeyHz!%gASL&O)htAO-%QxPEwe-&(G#U73(j&o`R$Yw5t^3AU2D zzzAUOb+eJvn#@5j777{R=N9X>L%{&hl$}LPlGjEf*v(I%9Mc>sk->1rQl~*H_g7jY zkkJ7N+vpAXvYKY&xf1fX%#C)MU$pg#*ut5kqom>jP%RwZ*;3Tl+NndAlf@D*S%T)l z%XBM&4QIrza@dX=O$o;fYa}A>qA?#g%U`cuabVJj;E%6XmX)V~)~7yN<-t5#|FU_&M?cFt zGaEHsl;xUtSq_EnX#-p<-%=Z1JA~QAe!c$84DU;XU~!V~;w40|hHkz%TX)G7GfxLO z#Li~Redg)j8uOYq8y^~tam*FOP2(@4)WsvQgELyY-puS}A$564PJ)qzly@*DgO3E} zhSegg2K9rKaF+p9yv;AXL6BiQLG(~4I17uD`3pkBZ)UF{qJ|Jv@>dz>_BVFg` zHTb;3D@!PXSwq^BE~sWT--q2XxTo zFeucpd~wyPJl)6w6V&}ZEA;J!VN+$r$B%iLtcS( z`0i*69kG6*e%A8!X@5f1uu4-@a6}mhcxfH55Cz^^tGXIiX# zqApGdWnH^)0mT??(tA{od4UF*pmOxm$74KthB&Erims)M0PH!~z?<+AU}cpEEK5MJ z^MuD7i#^?O2W;hXXqGQtX48$WtF%Aw+w&i*Bqe&G;-ZP#0UR z4gMoASosIl zZbS5OyZlYutesN<3|SJ*q?U0~biN4R+Sij6<;1@C06({j;#btY8x@7Ys-0^rRebh@ zG__P2wqa3z)+wR-q?nH2k-DEFm+oL!3z+I;DunjPA%$wBNQ#8~4aZzi{vx9dk1mNa zI00;Hi=?~&v5|xb-iN3%C*`uMSZriH4H9`o70CKqiSrWvMrT%9f*2rND012pnjI7U zqkQSCxYG2gGJf9NTJ*Pzxz#w#wiKl}>+`Dm&VNH4v4DhpNDw)F)n(&)0(U|MT3Od~ zn=*61Q!@Jwzo;S>_qto8g!P0kr@PzFd+er_wwo^e&>~DaUj1EHq%=QeDV@H81u=xV z3m|<6JV&SXgG2_t413Uo+2UU}GZCpvu##L%9vI)x`;%>Qn%hg>lHPeQxUVx)>Y9nz zcr;)9u#_pHVexE#gU8Kk6^q9CrVBB?d^9=(@Lwsn>41M8+}lk4?0EaP*!$m|zIV;I#rmTF0wU*7-Ds*k z+c>|4eG-KhO4#udX}MToz4^7suemeT$gy=gElbjuYpINoXjQ>*j)%D%xg-h+_TVRq z*+>=XP+J4mg3GkH2CjPjN3+e(Sj;&@Rb?^p=@k<2>`ufI81>beweq|rDr{9suyPo? zWc8ufcXwu23-RqlDI(Di3zVxM#3DghLQK#a0xd9e3>BV-*?k>;RIEh!(6RZ%(3V`9 zpZHvPtx_4!g3m?`K0{MVo)jxeAfOOXC{Kb!gRLX`qVKV_669@XG@B~XrT(sZ=_C`80VTFsgc{hB?m zNtlyVymIKuX{9y5dC|r!#mC=80RGZi!8--YdE0&dqC$DPZaF0*<=61`PLvlW$~%`$ zCzMn-RjdR-T4j={IhGgi*MJ<}4~6#TJQ6J^0|0IztHd7{UpF#|v%}LX_3~e%>bJ8V z+20#>jAYL0YAOT3NS8c5&CxVjfE{F*xb!`^isj+aFsBF=^MZxQMm%I{)Y;&yVU@uF zy;FS1>?TiT4Vx+(lMX!9CFNy$N^`y{El}MrOi@3BMv1V!!DBXEVjsq%-fkBoJgtGA9V>U<>i4S^%XNk0MY1R^q7UO2me{~nWty8xqB08J)r6-otzwq4q`=dKXQ zH@nl_DIXt<*c-ueEgI+6@VdsoOg*fRmlW_?xy4%syKT2VgA~X7vPP$8U^!<|+C|t( z^pKH-W6t>pWg>UJ3Kz2r-OaDtx)w65(j+l3BWLY{;B^fc;J#VoGI9qV?yA=&A-gd1 z3@wKq2oZaHaS-TEf!{HtI7GKtsN7dm2J7S!-%Wm0bU0a*4lB~}K=W(T{i`H|$N^C|7)S*)K z6QKDe9EFr1-2i2VC9))XopsNLF;=S)_udY=TF=?FTvQxfWcbF(Lj+zjIV4NtGS^>e zE*v8G)&y@ADXA9~QG%!gC$Ej?Bx5^E2-_o^Vajk0zMbG$<7+Htt?oO1^B-7MX&Tg7 zkL5yfr5NIL+-qKorfzSpblAs&8;e#Qut6lC1d_KSb6wm5Zqca|mzkJ9|fv8?NK z>GE&=j6m2-RHd9FxOK$HOOfIfe`!6)E}yBv9e39&dU3+0v|b;}l0f9vpPQ8=tDIoz zY-)8_S7lBg=F!nmi30Sy=(T3wrw2Yesc;Mjlgn%{4KY%VmtVL$ntr^2#)W(xCkJxz zhhcMaMem-r2OL{2Se3uR4G&zYdKx&q-T3s>Jw;AIoX43uNRy7V{H^t0s+S80f{|&* zP!mdynSC>U%6z%x@4Z%Kz+cP`n08`PJ6s$ZW)ZfgTl?_Ro7<~$;lRQzG{)tM5A7pS zNIDZhTfHB61!q|F=53sEk%?&7eZmLGx=Qqsp@+)z&P$V>G+c|;UlwMY5vzjq&LgLV`Fce~@qOzIY zQaY-X*mABrWIDht|0U)kGe|?{m*T!2*cBKHXPi=bZY?;mNInHcYX?>ZX%(13QaD-a z3rQjz&~0;+D-OJrFJ779x-%BsLgW7;b?nRT+71o6VrMNpNbJ1f!1_N)TQ3FFjUXRg`j1G#@w=ysIdtK3c4dX zuZnHUH7bfz+LkUEwZ2CVH_5bvNik558u-`%3m#fUoTA$7)hRFj@U?W1}7ZCf|BGZn;JAo^tAALSYai_6@t#?=pLBz?MUx8xZdM* zDF4@)>sbgi2+C!VZ)#Vi1d^Cb9M~rG1SpW=NGxzLF$YWJr3tu45y=r~T?zrksayOo zShpeq(?hd}pSWT!Hfn)Qm8kL+2I@uq8VynIMDW5rMt(SaOy_uAvyDUYN=Suv4FClI zaNTr8HFWW)q_w63KB(YTP-TjiQ!vYpaq0IIJ&g`k*aP(JI|b|%+A(OYBPn-;^p z6WycVwxXX?4p;jQ@!sf^S`I=;lDV~td&OgSs1EzwW)K&HzW^)X1h&LtUKjM_ae9Ii zd?-ezgenfzU^&U{d@(?g(SiImNCqKOfv00JofytomJE%vNoqV08Vo%X%Qt#(GfBe{J1PSzq!0kf=i zA^n;pcto(<Vj=yr#4J^WG=gdT~#4XANLl9Hvubjybj6ik# zs_FAWL51HCHEEW-&EeRDmgy1$d%Y`LO4Fkzqd&c}ah3GE_?TjhKgzCqp=lf@Fi{7F zCM@l-;LEf;4>nl|!rn$o6!nVZkTGLlNPNY#jyO*kR*@|*NyVm8Cw=`PnW=2Fd@E5J zo<2`tTf9>o>>zK?xUAuCou$Pbm6&uLKo^u1z!&@q@*sNVOsLas|D*Xh?B1Ir(mI+8 zcBf$&r?reg+YW!6Oq*GdC)zVcq6N)VsJ`J1u2_N;RaFZjLy4WrXxue@gEXv47|7C3 zrNg|fvwlJqp<)xD-AYKfYrKU$A9_MoT3O_aK_M+8sn2eVp3#o%41Bmc|0`}03H4SL zZORlCeA5PS#4cxL9JO=DKB0NEmGS3|Z)f+spg)R?^wLSVr*QNIF8c7ihWpVk>f;&~ zTuu1>5o@Q)q`Z*u16<2DMC}MGohwO((no9Ezw+<#(Dhi8)k&*R6|yY*uH7^W=6d~X z-PdS=-}$t*NNeXz98vpza0qoKf#<>E#b5!OL0Mbw`)4fI6j$#X?e6k7=^r9Zbuv(m z4#-2+>=W)S3xS2S9*Y-8?e{O0AeO9e_tHr1ls;D9Rr7qHv!b_9+5?F!Z5wVZR!(S+ zOe-oS+$qv7`9`J3htoV~(Z=@oCxWwP$@7|&dl--)^C7O$%+0XNuz;H~&xw=t&Xvou zg%~WCD^FH`pZoMju1qjcAXH9?+QOEV->Wj$Kj)TD%u!Kl`xxe{H#|T{@W=n~7g;}k z^LU*IIW3h{vHt9OIFFVsyroP10?;fQD4teuvImc#`~v|nWK)&L7zQB&x;lu2Tsr8p z2P%CXB@A1CT!EDq6ph(0W}O|hSxduF8IVvd8qIciYF13!9{Q17@*O8nN@esFjV{I^ z>&p3vZt4w}W6PiRG3IHUm($26lY1(3%7lj-0Kx=S&BMhC4X~2Jmq;bN~M>wk{PzL8O+Ddt|u~)S_>UM1BrFU^B#{4Mqbm6SPoa14D6Nca!a+_dfy6@Y^ZQ!(XA{ zk-V>T&ybl+pjvh3o>9Tl(;D*Tc~AB}XYe@*_UEO=U%_V5`309*sANuK6X9V^I*xSY zel9@I2m{K?8}|)39h;u}uq-Tf`4&lRD=Dm~_J{em?IUdevcsT;E_3F}dGiJlyodBj zkih}kamN(yV|8#)G|I52LoGrFhg5X*12u(&0FhwW^|po~9>8}xx-sRrIRg_s;}gTO zYBPr8h-g+#Wle-+jfLb{rDB-ZlCsJ)XT1GMGk?P-w#;@j3I)2oqcPJk6pa@`w|Md% zt9~AS=Rb7_L~*UvDf0)4uZt^;)7gDxI_k>+i^xv6Nr=o4P0D zV#p=a|F)T!{XLLq?l*Bqa^nT=LB#=$hU=V!W=c*AhrL9uQU=ltFM`=Uhyj2+>*sigasCACJ+LQ+ zqwg|i2F1{s53W@)E$p@SFtS0 z6)Ta5qQr%Mp8ZvM_0%ByR7Pr$$i`$ws6+W z5hc&ub7fjX<}?%AN%-Re!pGwBXq0S1G@K~fh=3fpZHY5US+GNOMS*tkN=4BPU|B{q z+3qL-9sZ$H6;GWnSu8CSs`zzrt_b_7dk;;|BO#y~`@dWMgc3$AY1$XsnukBWxDYXk zSW`rOm`Z93Z9`FTz#RVPMK+3AR+k|}iQ*A9`;Pqq-dapBkZq0W17*@bD^#ym-sQ9pAQ+{v%_%#rt3CvSa&6A1LAxue)HYC#^BBHI#n$F9?n zCs~Hb%HJ$brmXwxuGVEVW~6g~;4X$i7|v#pTF1%>)46;PT~y1bqJb$~buG|2+56T0 z6aoI^TK1`3jxXouRPpRu$PE;^n#p-0^Q+N*!)%vRo}7O1n}1R@P%o|79cMiU<;2YO zKh*=*!WTg&cz9@Ek=)g2Tom|YL;l(PuWOg|$n6wr2?OK3C}SZQ~RE%_C*{VJf&K}N1QwFbXA`iDAYgrezwUw-k~22F0RJkbwj2L@yl%N@G{p(fA8#7 zX{gyX0Sh1)b30m#;k-_stXeSKw0?>P_VAoiJ2(iJ77Vnk;5)grTv`zwK&Fc6kMfl= z=K~6%&L4jTw{;p*nsnqjNvR$mp1qp~TKMdC+FtjqF2Q~yP_;9{{7*}0I_f~5X<^1C z%@}uhs`ZC5Re$)CU*{NILtw+&))7~IM-+mE% zmQ3aUr5C_f2F~ZJcML|3U5xb0(?@db_=vGW^m-zsIMlL!W<3kSDUbz1NLKjDch6r` zkR}s5kJMZ?j3fMTUdv%UcO2WaWG)Y);pFOx?fAyp-m~rn?ox?(^pZEx^8@eY=hlu6 z4vt$NP7b#x(;gQdcgN%>ll=wGPDcl8^!mQiuE_p%8D02r53}$@7#HDP$l<2^dHR@< zNJitcqwz6bz3|(7$`A>OTj_7l7!fz6jnLiHS}Nv%1-+r(p-g?jLf#x1X7!;yh+kc) zqH)~~ZHZ@JNpbr#=J0F`%HEodThfB!z@DnpYP5cxMnE6&-teVwH#W>99ZQ0q3&<7+$J=Imbob7 z(58fv$vQ#fL`}jTH=xr(X+)#hC@ah@NRG8Mq2S^(izZ&mL#~HN&t9dYoImH)H<)GS z2u!&kR;tg_TeZg{JZf$`8SnSnGzRJMOT09>mZz0}RgZXs4o7I}r}>jy*KzlZt{qpr zFenupwwB|%xBI=baRgPSM<_-kBDtWd?#LI|*R{&NRR3Cc zJ6;RfJ0EKg8GbiMXZb?no;iB3kwktJc&oZ|vps&DtRdyIONTdqnGU;xi{Cb6(1&Nj zAs&C-R(SzHtW^NvU5V>fN|}n*s`CJ47^`d{FbM((p}lJ>6&(E{d$aI546hi6KJ-ki z;E=^>=ST**mA7mEe$`UGc-;xOPsM$qGdu&J`j&^K&<-DV>(9 zdf#7wY3u&z+4pwzF#aoDNea6yU!z_n?$9z5ac=h2&01G@LAU%*2NWwKWPFYp124ZZ zZEH?sR;6S0;+nIAa{M#)5fC1pzd#w5Gh`{_idMu@U2KdPCH*s5(K_4<>8uGc7~ zMbmIp$ai`z$UA>WbQUMA?^*XM>`R=HtA23pAHXsA@)Zgt-dnh5L-zb1}bZsJGvU{NUP$nS@Icz>!p zFk+!F0y8|Fhq*)e2QgYa%g^5&bo&RBX81WDej@6xtaGyC;^+Xi5NR~29TmCijdNQH zypkLrR%hKauldPU{-wyAatzB)pB?f$GmST^16hm0N)e=ba4tNf?}H6i_EV93#cirx zx72A6YQVHi+KX=bWhIqC(!J^Bd+{=KufCD*DF2bE zyEQ)&?7&))iJZa&k^0P2l{e?k+1lq8a79gP#?`GN96;Id_tN@qZ_-WueBr%!bahAE ze;c37blb+8m+NpA-mdi2&nv8IJ9g6f@x4Q_k1HSNXs$vtU4WQ-DK5+ZHU6_D5=AlxOXx-@xYIw}^zNS1>pD%la%Rt%@+q2?&auRI*$ zr9=#F3?GRt0&HsxSz%SnnIGVibzC=0(alM>2$(JDG#3!laTM6F4HG&Zwrj)C3CGZl zCemEsX!!jPZEf8@CY8nB-4=Z(&XeP?}h^ZIM++c)n$ zyt@@{(0P*^P9EI3{^0fW?dHaRTJPjmg})d zJaMJo&jcU*W+7ygg5(uCUdR=%{c*|W9lQzu>AJ{B8oLBAt!;m#gWr5QxQYWZy8s*%!$)K!S;aBsqUDWK z;We=Acrb!Ly9HO z-MITbzb&URGrh|$*ptt z<1N8acWcn!ycgW>)8eWm6e^q5l7%>eQrH{?To4JhT=XDW(Zwfdnua!xSFDJHJy7+c zj~=?1*8ZBmM*C9uftGG;M!ai=nXl0~jO4g@fx?w7Bi4Ub=mT3=h-tWeFzOu*=oV!_ zk4aDMVfJ~uJOj-}Duk=pOFxoWuHE&J*hoa2a?eCoFemb@w8rXo8lRe7u9dXhx6M=^ z^kuicRb36j2(TGYp_K$q-$Df!Q-@)$%UV;oce`unFZIXMG8y#mn&HN{@@vu$#e2i+_1R?82x3uI z-^Ndj5^PO6kS20$=n}~9uqJw7n4TVALAr+Y2)kATMbX|O+mDc?wikEqJ_R~`(|Ca( zs;veEBf!bzfR<2F8%25{P0O??E}UYO=FtAG>sLjO=FG4>mO}fWEbV|RA(CJKQwUD17U3|*()SdJP0w2>j%k%raTH%6X20AXxXHhugA%m672Qp0LIn0pORo&hKbvWy#^2U%WTm8DWe> zGv(R|imB+jT20{S3i~mY1Ypu7tAdJTJ#=Q_7FGMs3C&{Uki&#$JIosZqZCd1d!`d}^lv^*w@I-3>biP}+9M&`V!i zTn3CEi;3p-Jf{@V1m~IcaV}m*tPo%{`K4W3`tr;)Kp%cRuyA3Ig6eRBdwcN+^JT85 zvg2f$Qr)Qe>KgAvGx4mS!Xw7x-IsW z4IFwydyoDe1<}@Y;kLwpvjr1KSI@nb-NfR@z;SnBejSLYqlsyY-xD4sUec}lcT!By&A0aCe zR^BgxluP4!*%~I2)ufZ9Dvsq4F)*IX$973r0$FUGAtE!4w z_LLVRtQ)} zY&&lV-)ta3lv<7Q7<1#x5qjhLv$cGlP(_ zQ{d|~3SdO(pT>te9GG`v(6SIR%pynI#+n=vu3y`(wHMnKocORXZOazqXkZt?ft={k zJ+cVotP`?wUryX@0AY^ACr!GB6KQ@I>;c=tBZg<36qQZcrnlJhMmo-cgWGrzVuQTP z)qYiTvl9}tO$Ku~Fss6oR7(SJ zg*e%6pR5dMa}QyhuNy29TBn7XM)I$?F6cyOWC~1Ll>ZsQ;m2<59y~pp-3JK>#C~K1 zhejh6O?=6QPZk1QNtEj=?LjzWu+J}mVst!*$`=0HVIx;S;Zxa2$p{iZk&S=!Zbf3Rbr!Ej{DQfp@tp%OU-1IhH z47)C_5QGRY@##*1M&%kvxUKkmc+_>3sezJ)t#hZb>MTu?dWxwB4mLFk0L!|6-%%SLZ|#0yb3`?y;(mnWRTsb5Mc6y8qAa{E(n`-CIMzgtf*2)>j5Xp z*ETPz*5P5=Xr8!f%sXXMICEH;+bF12)lHpL!K4)77OfA+3f!ZR-sR-cjbqWLsmStE zXsJGCa{XX6Vz*l0KDZ^WW&Z2s3FqT3)#Y@RdT^XL zZ!TWCTRgp8TCuI=>K|%lFMFs887(#)obDtyve@*>wE0>9r#ja14aEsOE!(>ImF8`T z+~hGz2%s?MU0V*OX+0K)%`9`7+a~>_AIXt8`g2TSdRC(rg(AO`7!(PeyMB9P#h8T_ z;09X?HU-wtYP1qGSg%#v5qI+tKnc&v&&ufWM@5b``s!&}YMx9T zG<&%_)!_jV#EW=69sg^YY|$l3nrd*4R*KEy0^?6%)T@>pYo!zM-5}K~q9A4(>;!0q znNO_F8c=MVw!XYgc1u`M#`-lAh;7srU*+Fmw~`K}oZWzbZO9hDjd?!<6WCAII$CTvNV;-e8TeI_@t z{-5%D)b6iK3E4((=_*+gcEu@_FdoYn<*re?GD?4-sQG6;X`Im!QHYGAK=@>gc%q9~ zk-z1^BIsqP@ zP68rY!0i-b=No}?qnEeuLT9gXC;SFCxd-O6@QXhpwfjG~W8U_7G_>SJf5)9SFbc^R zhqHB6Vkw>*0!CXS7wyRL-QrJM;i7{T*c`O?cuH%*YJr##ql^3rl?E>g_s z3dgp-Uzj^-pe)GXN`R{=w`W@_b6s@wob#1uerVlpFeSdVP)97L0i{wVOr3W&9nTVa&Ox0xH&r~ z-@@Dr9>&5qXAi^QH$j_}VPzkiJrb8mn+QfiPP5T6v9Phb5rETeMDEQm@gK2GLgm#r*tfrZs2me46|9 zq9AO$SuG1P_2m9z^jDik!IER4(YLMc6g{0c7wTNo@w2SuJBZ6tJExF2Sf~C3{4l_UV6DhR%7__m_JtCcT%T8p|5MC0O8}AtOktWTDq)sJ z4-d0@BPpEKUrd%RpO(go5{Tk8@1SUP*9Wu-gsbr`oK4}Jp)T13#2A(;m_^lC$`@1@ z+&X8nf7Sz(Va`gnon%{GW$j>|YTeF1YeK|ytO&^HKL|6EmbA~>8K+4)2wS*=vfGi7ucwrun|%EmsR!a*ZYS}kg{iRHmaP8!p$%~;gk9|q8PDq-&xD^YAQD&<*s>7O!bE^Hq4My>OAIY7IIq^9A#-Im%&DefsJM|-2olLRq_}Hxw_L!xJ=!CH z&mAc@<0s}AeYL=W2!o3f`kEv{W!${+V*_<6C?|E1k(L7O!H3X;PCS1SN+`z^KFYokq2%5UyHamq$W zFl@>rZHrMzm6~T|=mN|O$1nj($}P|dqbI+)MTcwgUs$tujmfs^RvFQ77{iB*d!(n1MA#I zvPOtN9K8Wve_g=0rHSKBGtb99sma@7sdmYNjsEJ0ve$dwOXdu${8>1TqhXl7hZ<}1 zXM}V|JGd1nxk#sFniw~AFa4Id3gytxPavB67^hX^V;4Oj))fVgdn5vnvH$BF&EYI( zOK==EzCri_zG782#-mJ3aV(Y{=MLB798kC^wAthdmGS6PiDz9~)o&8!P-A(6u z!$LdWRd-T%*mn&GeF(kn$_Im6$rDUN=_7QKLT)_Qyz3YrpuBExCubKdaf>exGd=7WsY0!abt9Dh}=ZLL- zE-ZovrXx}(r9~S5G;IxtdK+((*xf0DPi}lv-l(ESp5XrKkf`s5M9D3b8Wz_PGzCk; z>R8!netwgBi<3>j-<>JJma10WF$ueCCGLdZ=D$a<<%}(=b_LzUbc(RJyzv(fERO_v zGQWo!0#~#3LZ2}TLFZoY?rkF_<%otz5g&93+)uUG;6+ZK3mn1Q!Hv`T+eqS0SOjh| zO%nc!c12o5jz?{sOO2?6Oq-?3U){toX3MmNy3GH%Cb-vru+&lK18lL*gHCyjE9L>@ zQn6&alcsD5k4yR2gOU&xQxY;gv7jx>ayN{+^gJ!~B4~qe%2`RvoT(Q#!k@yvTOp^T z+8t44sO)b;FCAr zkGK)xyICl;=WN9IV~fY%YrmEK`>cW;Z{erxQQ>UH{|f$qK`$an*m#K{@3FFI+)SV1 z5uP<}CiLa6TQ{d5QCPrp5y`Au*!HBgpnrQ}XQzpqtJgj-bJvI!E+1$qRi!x4&9O$8 z3Z3m`;>GZtN93wM5;Da-MC(vtBAka$tYWbveAWUw@E>&%iq&aRWkGqDV^H|)8KE6y z$#v(bYp#|;hn@qF3{b-^%Ylx?Tgoz;z#V>17$!>hDK9&(4J0a`a|MWX#_~(Obg#Wx zGL}s)XkgtDU9h8ibe0DkzYXHxttyf0Ui%B#%h@KF`pQx=lp`t;j&+8lWbOf>e{=^H z_DXnTlb^3Fb(X&P7G0vH_y>OGd8?DUS$)aP>PTXZD|qiuF|FhG#-jYh38PhDWuFDR zTM@PZ0V+2CnP^f(JPW-UPa_)Xv}5IURVmPgWk>A#Jt9O9G?AGY3_e2A+;W6?z$xjZ z-dgJ9GI=UyKMpbH;HCFts+aWm7eF4|pla5n+mXe8)F=K-2gsVPfFxsa`yY>bkE~1Y z+yzM33o}w-OcIo)6s&Q!Tn7lsCY-Eu_sSCRw(^>Lpq#k_DRp=qIQ}`BEzzh^kV^?n-NQ51K&> zOAX1(ND&0iMfl4s8@b@j+;Ce6p-O86_J_0$A>dd8K|`L=%HimcUIt16>P{{<=m*{D z3`ZjE{-F3K%zdzT`Eml^q@7m3lpj4Ej=P8LrJNZT^d4F00gwMTMB z7e?a`d12Gh_j2|M&?bG-wXS9UG){%)m4xl{5c?9E?QStZNj2cMO033qt?IaI1GUTH zQLr^hsPIj47nxU-N>%)M4jWsPMghLgoihXHEXFl|Ceylz!HBA7O0g(S z+w6Q-Y&r}Y`wfNX*FpyW!;K+-B-plz z?8E!ouXJ|LMZjhCmR{%6U`a_^=dZfn($+I(5anNa-q|6(Y99AXI;o&fV$*!ofiZW@ zsJ!_7%zbH9$iU(zBZB1OcIM?!LzF<{CT9MPpNC0zAW=DwXx)+}S8ICv+a62X2uNni z2j4-C9WeD^v;X+bY-cItr=I^?C`@@*QU1ODY?9~WS z)c618X!5%s%_BJ$*KXmHpFbfrb#TvRmI)YQnSQ^H3SEQh=8gISLPQ$%g#NgBV_daS zj<`fGXmTk7BZ2K1=2nfT)s;^#%S^+CnbY4V!GR3${dGz}P`0WX%XHOO=^^`%QQ>=y z!r|e^5&3dzRBe_R{3=r`^RMy9L%Ya8_GEz8N(jxDw#|zwg;C9Xj+(G)@y>V>ALl;1 z+w02gI~nwhW0|E|wOr+Ciu_N;yM<2d>`NmSzeKWPJwk#2OBSr9993K;8pZyMbK+vc zstqw2TYyI&m6MA;*s=I%hieFFb3}!)dmV%3l1ynEL(%GJ9a{qwLRVf_jSAw5G{K{H z3BwG%n4Cg#QdK&29UFrBgrlx*5B=VWs>J_|;KK3f*>my#6SLc+>ib-~y}7s?*M{0! zjVr3FU5Z2^)#WCawW6zN_xrTqF~6C|`7CWYF^kDkekBeXJQbf<3^J(;pJ*KNR^m?& zqFGW|@rb%7 diff --git a/integration_tests/data/extrinsics/kusama/spec1031_block50970/EXTRINSIC_spec_1031_block_50970_index_0.bin b/integration_tests/data/extrinsics/kusama/spec1031_block50970/EXTRINSIC_spec_1031_block_50970_index_0.bin deleted file mode 100644 index d58b230754fdc2b1e1ef24fa69f0d321ff9a096b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 TcmdO3VPfDuaCYg@JVq`66g2~? diff --git a/integration_tests/data/extrinsics/kusama/spec1031_block50970/EXTRINSIC_spec_1031_block_50970_index_1.bin b/integration_tests/data/extrinsics/kusama/spec1031_block50970/EXTRINSIC_spec_1031_block_50970_index_1.bin deleted file mode 100644 index 351872fb15d4f2be0b3bc238f31e7566df9836b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9 Qcmb1P;bcgXVP@b000YqgwEzGB diff --git a/integration_tests/data/extrinsics/kusama/spec1031_block50970/EXTRINSIC_spec_1031_block_50970_index_2.bin b/integration_tests/data/extrinsics/kusama/spec1031_block50970/EXTRINSIC_spec_1031_block_50970_index_2.bin deleted file mode 100644 index bf51eab782a4c1cb186ebc426ce5c163aff84280..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6 NcmWe&5n*890ssKi05bpp diff --git a/integration_tests/data/extrinsics/kusama/spec1031_block50970/EXTRINSIC_spec_1031_block_50970_index_3.bin b/integration_tests/data/extrinsics/kusama/spec1031_block50970/EXTRINSIC_spec_1031_block_50970_index_3.bin deleted file mode 100644 index a636aee438f097010ea9bd6e2db98cfb49e0fb3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120 zcmV-;0Ehq80fhf#_c+n=8evZ9k-DudeXrPnA_Y$H0SS+Ux>P(9r#(Rd0$Lc8R@>Cl zRfQJae(w8EPT%=e%VRZ1Hkg*E-*EoCt diff --git a/integration_tests/data/extrinsics/kusama/spec1031_block50970/spec_1031_block_50970_METADATA.bin b/integration_tests/data/extrinsics/kusama/spec1031_block50970/spec_1031_block_50970_METADATA.bin deleted file mode 100644 index a06ac40bcdf73a69853e06bd949719f2ea765d45..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63386 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 Ui#pFY`pPv6(?SJ|I0OGk%&j0`b diff --git a/integration_tests/data/extrinsics/kusama/spec1039_block607421/EXTRINSIC_spec_1039_block_607421_index_0.bin b/integration_tests/data/extrinsics/kusama/spec1039_block607421/EXTRINSIC_spec_1039_block_607421_index_0.bin deleted file mode 100644 index 821084cc3522ff696977df8b5aa8c0405dac2f27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 TcmdO3VPfER2wXikpOFgy4Nd}$ diff --git a/integration_tests/data/extrinsics/kusama/spec1039_block607421/EXTRINSIC_spec_1039_block_607421_index_1.bin b/integration_tests/data/extrinsics/kusama/spec1039_block607421/EXTRINSIC_spec_1039_block_607421_index_1.bin deleted file mode 100644 index 6f55d66ae2f5d986efef5d9b99dcbcaee59a3c5c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9 Qcmb1P;beFxq{_er00zqeSpWb4 diff --git a/integration_tests/data/extrinsics/kusama/spec1039_block607421/EXTRINSIC_spec_1039_block_607421_index_2.bin b/integration_tests/data/extrinsics/kusama/spec1039_block607421/EXTRINSIC_spec_1039_block_607421_index_2.bin deleted file mode 100644 index bf51eab782a4c1cb186ebc426ce5c163aff84280..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6 NcmWe&5n*890ssKi05bpp diff --git a/integration_tests/data/extrinsics/kusama/spec1039_block607421/EXTRINSIC_spec_1039_block_607421_index_3.bin b/integration_tests/data/extrinsics/kusama/spec1039_block607421/EXTRINSIC_spec_1039_block_607421_index_3.bin deleted file mode 100644 index 900ed1510edb2970d1657ac72591a966cd51e245..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 175 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 d!u7%)YLP(;$4R0O zMe`65pDw*_-HYG^3X_$ZSNbjitVa__o~7g-=N96}-i(1tSp4h2+HUf;-V1i7p4Dcm zp2Cgc@bVtFC_1^MH~i11y+KQ}$Xyg-91RMI$pj`6iVw(dPp=!pgi(1HQ{>yelcm$O@TM0|Z z;FWwKo{~2{q)7vz1&(y62Et+sspVL&=U7rPie1ignl)3O?|l?!uv#4cFlAYnt4Y6i z_N4y$?7StKOJToG?yUNX+^~j+hW7BB>Xq0CH+vXpMHM9!h;zqGjB1)sp+Cx3 z%0ecXk>(Wy-ndWLeY=jrfvJA!yJxTFz5t(HPTQLqsKK}2SypZLG5?bin@&1Nhy<9a zdy6VLKGn}gx;g9 z8G4p+$bV%x%OHd1^NY6)M^0Ug^vlyna_V@-SfM0iBBD4HSUw!YG?2C25eukmK+`%jCAyZIu2O}XWjLX zFRmXQ92~d4J2~8$OnY3(-W^kPPe~&*I~^UY)29DQyJEy{D0)C*;xG$OgmJM#3$@2l z4LKKGP#sBsz@zaoq3ZD4Vk&zI)rjeDFN2chKyR!&sb88GIdPDZHO3r(oexv}u$tY4 zVo=H^>qEUCzq(Q-<9cqzswuymic!v(W6i3A0HN8qDRVv!?Dc1@M(a0e1Pp7x)?o(N zvV4fL9;q8$S=@bWw@Kv-+xJ8f;#XsCwMqh&;-8c*s03vTECpp*mpQns=_ z<+=<`cQJl}i^YKtY&jpwqMHh=P@6=P2R$o^Kx8~b9zzk%JK4jdF1$L$uu4IgFs5Kq zTV26Z#ZElz%0lNzRCzVHBw{#v3r{pb?h7K?V`~h0&jk+ICUu%8AM&u z-GjI=e??YkmC(0e+aR0RrbJ>Z{S!ilUad7&2n<{V+}KugK!kmkdQ(oqLNFmXa9T}d zJUU1m$ubwIkj?sxfRb&WiSC&eNCuPkTvO5f zfj=qKA9v4aIdsKAODCmUD^Z^8^m}I&l>QbA#`-?RVqHO^4RhbQBpyF&lcF9ed{WJy zJjc4ORo11$`}I7@wIDk_(i$=n1unJ}yp3yS>t*N;h$oQpp@H8BH=;rN94$UK_^>p-<*!Z z2LmPrPGm%QS11@JBB(ytZ;V{v4;=Y}<1&Q^NAPaMZygsc(iR9Dg zjGsR~IT(kabWX{Q+@ee2xg9Jb-W=DT>kA&Zt*6u)Nb}*`<2y8tMSg82lsE~ztn{CKYX@WqTsy*Q>&3|k2+3cf5#{K zg93-flWYT_fUT=YPyf)Go|N4?>$LWPCc4|cj|%hCU!D6MA_BvQB=Ql@JrQ1(2HCi&AT+CUO403R-!+V3MZ2+MV}-VU)yi!PcsZdRMG%Ae7j3e}1&BP~#u zZ4u7d<@-gR*fICu#_$NU>dsuMz#D|`*>RiGX)9cPl~U&HEcq3{)QUp$O8eW?owO3W z%Ej|Cjm*a36CNd$51T;EZt!RVL%7zg>kQ)`3CEful2<}cMSP}(Zm#Ez_ajMfOBNWh z$Q_~-yxhY&VV~DB@3yy>J7<&b_jyKb0VC;}M1x;52Jzt9&KOSJo?rnxr)|yLu>0gsyK!T= zE8~=(K=#fYGGzTw9CHXuX_MR!4~C;j_Kzl~*9>w5H5a5oiBA>Ql-O+haS7<5lG1UI z^6)JZC(B6w9JyB7!+1j2$gq#Due@qDnc>h0aQPtEno+D&Vh5`eE=$V)TtHSCO74Lf z&9Ia)5=zOG4PzQ_F1ukWR?{ahEq9)#C+5NGTuncm#Y-R3<;a9oU?<-mF_j7;{LtrW zlyqip{5$Z@zqcr^%IN17%a8_|ni8y4$E8#?O)Pf zw?9^k!&@hHdoS7 z$W}dErxWgKn-Su96tK$U#x!iDhBv>+URQjH;s)t33vuX~*g-@zZUqQ*Fi=66xv+kT zdA_vfF^Bp3q;cpni`#mK%2_I&ENA4C86(BN($7+2@fF&*?#BaT`(#v5~ z4-eD8g~M(6;`O63m(N8=$e-E#=-knf>N8dST$<0jdKeHm-cJ65i?L#U@g*W*0b$0{ zk$PW-?NM_4EB23#KIHn283XUZ!nM|G+X^E*&ao7H(sKMW&=LYktmB-!W#Jem&9Vpu zQyMO1>-R^>c}j9gN{W}-r9cZWs$JJ9FGV?4N;~Z~tCHN1>vKMg^pu81s$@K6Xxm;B zKeT0Glw^nph`#!i*Tg88MsgZxs^pPqrD~V(zbPdeEZqBl8VwbCyrRd10ohWCI*2B? z3ODzxb&z|-p+YtBb1%8$Ns2J7ln?l0fUbNf zCQ9?N1qYMf_9ikl3;tT;+W-5(h5uE7dH<(H)HOU935r!YrOqtGptgn7yU84Mz2i`V zhYN{By`T-HG+Qk2&Og#?=PR+X%Px0MNwozRNwrQ!w3B>6tdvkMU|ZmbF?Eln&Z+|@ z$MA_)JFsmWE#f@fXCQvi=f+;vhsA~rlEuiv(iPI2v(TxOp@rGGt-bNqNwYpC;*tO} z%*Gl+Zy88e%z$=A(6W0aVMC$}L%teXe8oJY$ty*nWoa3$MP16Ixyq7XQ3d?25H9TI z&h0}kzKs#xWCaE1+paFwOFW+6W19OGYN*7aW(Z(mrhSm#lp6qeR1ECENe~6*U~Ava zt2c;z+WgJgnOKs7R5O$P{Li*O5h%^JkkjUs<<8Cqsywu%k_s3mEDMTP^hEX#5yCv9 zzkOLh;G7DMqwtIwAdBzCSdc_!=&5@zlnz7|--JD%(5Hq&qiad9eVYERnC#b z=gsJV>Js-MXgT-Lz55`n~*O-k|q2xgpx)=C!{5h5$4ff0F|HL;%abj)veH`x1qwJ}uARFfkS5LWb3XheX?SJBz&bi0!A#I~Qlmz4OpV2DolBy3OrRFK zTA+2$L zZ&N8X-Lc>274)CQx2M(W`xT(tiH+ueboWsD_{vAwnyWA}R013_ZESuk3)a0vqG~mX z;by_58&3X}D#2L@li4;fYfny*4F{eT9?RD6Zcp;oIS!)i_n-JJ+wXjt)Is*@*6k$L zUp?Y#X8OuGKVNSBrL&^H6oe6iK<5Er3x&e?EmAwtkjVs{7*9}%-~Cd@M*AKqSrTk$ ztY+o+^XbMyE>&$dt|=4#TD))FFSW!}QbHo!vdCkh%)n%$`u{2QkuTgJf)3}==ycrO z?8WpAgik5gHWY-44)Y_HQoBS3A<3(=ZuuhD0`_#h-6=yjb<)5EyE%xgXO7o?T^TVI zJyZsr(er>e|62p^aeO%368-%15bk;f7DVBXkIPjmN)P(^SM1|_74Dz5OhAZME29+m z%#R|$#$>om>!c-Cd<9gK5(F|%shCr3S4X|HD7R6m7q*Y4D_@jFsJpeSP%7);_1-5Coxr%iqP>(`(Wn}eYrYEd} zB_siVbHyn)9^(e}$@$R~-!+>Wo7xUqk|nT)X?4LB`QW#IN_hotOC)AjfFaLk4LLC{ z>Bkx5KzI!*J06UX5BbGA)SXP?jy4-BR^4Mnt?qC*573$WU@TYXYBiKoy|@*TWUhIa zSn>(l=r~d4=hyo^zn;D^Gr6MG}uQd4l1nS9<0lb%h++3dapGL^LJn&9m*q(7dTu;)+9TG=vYe>Ak$U4 zgwuBnrktkCC*8*=OvwYAhR>5O^{8tjj-?*s5KwoWw{ZoN~>w(m6K1onWjkr}2qd zaINFhJzGrmK?l3_%_=k~BhY4irAu`qI)mv}(qg)RuhDF+tAu^0Yy0IGZ7uHTvun5c zUvFNpSL!70~0k3nj$i@B;UglJbM zj$fm--iUk4+yO8`sQTnq1(FDYQlO|c;j>POBN7Wb)Nds*!_jc{9-`Z?=5!q^#cR=T ziN+xOgUb;-1s0@`dAOns8L3(tyPzP*@pw)m33-`6-nD>1|FP-UZ!$>G0Ze4O6JD>+ zCZ9$kFzV`CINn8w6`@TOD18h=f7^xwIqYJ51??J64BBat7{1{EeAgv^T)7A7xCoQJ z#GETKXfQAWo@|!|LPD;R+TrA~SyM{Ab6`pq$cOR37Qu8x9>Rqm6oU9x~n**`LlX`<G^F`dM!7-PH!3Obl zD8-zgL%NposmF4h5psMFlMlKnxY77Z+jiL{Z@BE4B3~1bUOCKNo{PW9s`m=Zy0W7( zi0LZ51jaK*j?WG24l~ zGVMP+5~EgMb-5jdfGI;y$VUrDR1&>|AOoYz4c4Rhux%!hwC6lf2wgCn74+=(alpiBCU*i3UgFNX zE*0nSA&v%`KB(5X*%ri{1qq}H_{iW9IGYW1O%UB`iyc81R(IJCdA!;Q2+4Q5Hl`u= zucMf$p#y|T`xER?3w*Ztf)Xfd+>Y(XpWJVv2LifQvzItuct2Fhu35o_tc`ou`!LkF zR=<6<7LSl`@DlNReS)Z> zya?R!uU(PE(@Nu_CWKk%k=iCy`66$Jg*X`o9r&wL1OO(T-EAb@ZTh!{ev7loHML9N z7f}3KZO~tF9oqVSc^5fmvpnS>!j0QZI{HrdAyj(>(xZjv<OGw;;+LHuQ0B58 zMMJXa-@FkT4cB$b)tfeOxH{3VuEXgCw!ETEyns1j zk(h8tX_V%sffR^|VgI^y$QD~P#FnH0NI1ABs}tLmy*K03qmiME6JyV^gf1dGah*hh zgjZk*z(uk_ly^?9H9W3kAJ$v7j^`ksq~#b>;z0CoL>5K|mrd!pp)Y>5-6tRwpR>+Uw>cluSNSOS6Yy(ySjZk=GE`fXimJwxtnjGq|VX5*?N+v+HxvoHj+t;>gt;LqL2Lly;Fj*rz8R)>4 zh!Z=y$2k=R>qM+dzk&!wBm#y*`BjZ3()_O21GR-mYyx&lnZ7N*fyVpHy95ql<3U-@ z*a?&s+|5qtRbslxs3%S5>ZvYK%(Ms)n7XabA5|TTB2UxZos0&AQR}?oYcQ|E`!Zsg;oENF9y*#1U-6aU|KIZtq@mCaYMm$DiwPi`==Q$*~_=9W9i!U3*WPXLrFISu^Ubv&=%EBpT(~@4~Amf#2Fx}&C z%&GILO1HbKsv8c|Yr$T-d;Tcc61iv6$Bs)V_A&ICr>l=m+@)Ol=>3qM2 zGj*L1hRr)m@l@Gx9l--l()q!nsDi`Ow9!3r*Or{1Yo)1k0X&b1#aXi1iHj=>jot3`8kAkt_JPKPDVWfi<-ZztwjUXHn&qOMsrKa8W-^HYiR^!>2$zy_}p{ zAm@_u>N|(1NktS@x(C&1;=H+Z=}z(ZR_VpIR;qvKrdRnxRm=$3v~hXN;B0xbw)t8D zr#jY3B}}UX%vzcJ2$`EaW(h$Q?!4>&7}4-ZQ5gZ1yPS5!!=8VIE1V7ul)GJnJg zj=H_Ea?By5&60udv(ZusKccgB+YgbB8zVikBS^`^p(@9 z)cm-9u#tLsjP|s#-F07SFC8>s_f&tL916(L98^` z4cKDmh1nC(Sx@He)8Nagz>MQp?kA3ra654YkdhMc`PCC6_|QySCX3vSC%=9EzOgJh z`DXd+`ARX?Y$mg@vd#I6E`brw_f&hUe`pRvnKV_Mu}Y($otQ4Fl=fYrIheJU_t8k0 zK2exh|E2mK-Gn%&~|@Vg>sSQX%{2kVCRh|CrqLtuF5!;^+&5%Y6vCjFa@ z@6?tOYXHk7tw3X(eNiWq<*Vwve~wt#J*E$M`)tVU)>q<}IuSW^p>L}(z2QrAe91In zw?T<3611b4nbZEB6&dLAJmJ-%x-s_WhZCd#yorYfv~wCZ2jLgun&82kF2xZD+DPSw zV6c&O1Svqc*F~c|#&1;g#vVW>O!~WhZt6|D$lmNm!_|7J{s>K?gF(u!06Wm4<^mwx zcMmVfCLqGoNl3&BxRp}ud?QqDa_-{}eD(?lhBkZ6Mi4#=zxWf*O8kQd=538fLn~hN zcRYB5ppbrXJlmxMfRYYLSZ{N!$m!kkPut-h;8pZ(F$kIYeC3{Jdep#)giQb;{2(1d zMRj<>`Z$&Md{6R4!BeRd^ff6j$!p)l>!;%w76X{iZco?Qs5QbX_&gZiy+WeaO3 z(p;h~nj0KD`hH>Vq=T{`hbtkjX560bsmy&1=JbKX)W(b$MRaxWlgMWOzL&j1qgw2S z{qU(XUSuijO?3t3TLrRp3XrX@QhgDhI%~#$?;0Gv6_L(QTg98`TJsu1u5Q0TCj&2gDpm+pB3>WSgx zZpMizBHTK`M1WXleF%SsD;s7RA2;*uKAFoyve;b7!m3SVGd$X?`raWeYt0W29S1#G z-m%DZ2X(CUXJ@;#EMf}iAo_G6v|jYKO(#(3QzO>x88-8^Hl+6`RNyF~`lmP~no> z^D6OwjJsw9K+=FIO;aT$+|n4~VRm(>v{d)Y$A1jR0l1v(jxR#a35UJLqk}?eepxM9jvDh>QUQ z>RU@Jt5y0oJfzv(Aq@#kqZWj&h6h$)72F)aYphHHd&4 zZDK_*Qjo^1EAzX#92tW}+kgcjM_lq67hc&{m^6+W#5Z7YZN)0jQ^QQ<)RcS<7?)L` z96X!HFrQ8v@aa6eNoJ2-Hp8$##(oPLK;&qu((`wuh=p8%di(-dt5P+4R_-ZB@q-&{ zuL~8-`n8zfOx2wGbzJXDq{o@X(xN&~sKNT)@e4eK@LQ%H4TrTpEm*_TXd&7W!CciZR($ z-J&*=xCDp@p19Yhc>uF>U5{)^9{aac`=6MBsq1C>rKMJhhC9xc9LJN65ZKMX5t9Kr zJ?KCKvG)-0^-?2L0vAA2M!-6KcJ7@5S$?iN*&*aUw`jq&`J(IdhSDq|~LK zMM^bv!THvt3n6IlgSx{>anu`enMMQ}9gXt;UE6e2Y3nf1mJ?JQ-{`4R?=C^eV8{4z zp}hTEYg;#!7tR+#zQtr+ELrUfd-Vz~^R7CO9AIg(?eB)*z;^s#MpRtA`c#a410spC zGegHvn1#@HB^5aORXWI z%Eh%o>=GQtZv>6ROk5#>|1HzQCzj9y0SOB_ToOfW>%-_>0MXwb-7Pu>+UJk^ayW1O=Ig}VKU8o{JHd)-ymCWpYWse>bA@^2dX8vO* z;!^%K)El;7CyE>?DULg-xt<4j!GKxB;ih=ZVMX>*iqW}?{UJV}Zo#6GFCF!f5>iyb z9*xul(Zk#JSe4N&xw)X38dyBSj|IB|kn2jE3 zKjPD}OH>HVW9^y8FZ(tH(Mw}XX$EgjrIch;Oju^vr9nU@M!qY&Ex) zvSx{`X>XFThdO+2x`Nhn{?s0O?qavYy&wu-geM|#2My&HPa*Qvg2Jr*{4)_sAr_fy zPQ-sUf(T$C!6ohoVC z!LgIInR76Ds6FAWWlKzMe)jI=>?QNC0^T?-YJI$3QX!$LTeXc$QrS3b4pqz;dQVm2 z1p8MB?2-V9=s<*0d&R*@sM}LBKDIE{4MJ+CZbJ8cwl6w1)%w zh`=lhy6IyhLe|HBKqErx$BYQ$s<2zLD*J?0@wsSKoG_`*uqY~a1Xe_FSd#Tn*OP65 zlh)JB?#GXLx5{u05%+N6kAnQ~#sO+GX! zWm*R_eaa)r^!Cq6)4LvCYo5C{8}^)2miyv*2*YfQ$D{Ea{B4gZ0+k$C#cKTSWA}3K z9PC19A_^iSJ?s9xf}Kix#5X;MPbhVAE8cfuE~iCE^Gh~U3U)SHKRk8rI45~K-9qi5 z2mLuIU@9dH7J|wkk2tgPiq*R*H$vjaBP%g*m(tr7 z3S@yR@8E+~Yu?h(;g$SaglR2=4=ZJFZEHzDbVgWH0uu#JH%mrMEM0MXn7ju-UKYcwhMDYh+#CqHX*IC3A zKhic}B|IH$*TV``J_q@Hi@=OUHlG9gjYhU<$wzWy3tI%|7uxafyZh8U)iPs`JXY;N zlPjTu)DN<%tclRsW_d1}ZKq^~T_?&yIcSJig-oY9qbRC8RTzUFAZQ7q3^6aBFKr$1 z)=2>FwX4zil}wEV)C*A;>TWY2X~1H<>T`IBng$(MPF80hvrm)G_;g6O^1yV&0b#{Z zE$V1FNpia$gtVYlcZyT0VpS5m7SoYY2XKrqSSu{KIl%{luB-`R`Cte8v*hp#`C7YBe%kgTSPa<&xA}R=5}n z@eqTzB6qkNmYNr|vyGJ2&jo^!9;g~?{6xTpbV&MK^iU&|nQWAC$&qQWzU1PzcB=d+4 z?U5Wkuq-?G!f+~D2r*NI|65p<&DH1(Oc|twT050hp^WT$Q~?Bf)R!!j9yV7l0trVA zm3?Lvt)+nX+D2cD_pPSqVla1dOnmqtkDHVfTv$aik}O1+g69deyH?zyA{Xi_sp2A) z^DUWg0SJt@Dg}oPO+e(-jfG1D(unl3e8zP%Y7CG6S-(dqjk#)dZdtpmP~q6Wh3A&@ zKfwJ-7gSgmIqm=N?&^KxsDk(*EfPX0LYKnD6)DbAymBHJhp{YMT%1d=FtROlg(a`y z9NXBrvvRS5CCZd3C@CpYQczH)prqsvp`fIo;P;!aw|jTKv%y$`Ch_j=&b~Kq-h9uz zOi~8t9~(y_^|h^XDRCFtVK*lgR(5+?4xOrNtXn#)mvA0Za;VGRgrh{ama>9QcK z*KNdTdBhM_khn1Ae%w6r+H0o`$M4oY3)qls77^yEW8z)095xyq_)AOF(Lpv|7k&K1 z={<+6my@m&iJ>V`2zAp{M2XNLu>JyP3V0%ZXjX%q^t}O9l_@}Q4Xeu;uuI1h*Z?M; zVFZSUo&aFW*=_#YB|94@ZkAWRMVMQITIBM!vy9Jr6iz55LZY-u_YTmJ;ef>Ca|r7c zAzC+3QR8OAD8P8wd*8~4poufnVZRGqf&O^Xv(`NqkR_{HA=1+P$1%}X@(ro<_ZCG3 zCkgIwLlh=wt;r{=CvTakbR<^k=Qm|6uvpkQ7-49JSO~<)-4;^mNl=e2kvT92o z!qb7OBP6DU0yNB`bj1-9!sMOcH0#Pum1V!`wg)164K_9xz800Ibl# zJAI(-bbs!&e~Mxn>Xdtf#o9u>D2iU6)<5#Q-hjEEJY8IjQ4Ja~`q}*KW$*dkX=66W z7jN@D^ja`Fe&R%83p|CCo1BfFX?8g>ev22v1(Tw!kgN9)d`)pylXa5_yQ%gelvE+b zEKzlH(@9XMxph);!io#kmn5(KS>iJxz@T9V!!eem>!{MJ;#a*P8iZfwAJJecy-U1V)X&!N#Q>iGk zF&IwRe1V1WZ0(x34n8DGx+*?z+%}DEYX#9}(;;n4{({2u2Z=#1)ELr7hD{-RpYsJ5 z(U}2}d55p#u31vl)^SzUTg>Z>t(ku_Y3=ZPB}bsil`>Tb3c|Dn!?!C&<^0d}kL5t* zGG@Ty27Q!*klTrugKdAyV&*@-9wOa=iPCx)23ZSQ8xst;^0G8!1JO(wOj(jUV$2Mh zuG6f^OY=XZ?ZX=tt5f&T|7uA-5Pqwuuw~H;mC;q159ivKD47rk)H769;Rp_))9YEf z7E@|r%_bG@RuXm>al$)#aKdF;#oP^LWhdl+#ox8O{?_{xR9K}f`#61HRKI^^PyRHW zM}iEktx{f-WV9mPxdgKeWRPWQejC%4O?6YO8bSCTRh17bq^@AnMg_{*DciM)Cg;ws zWF~zLbF0GBs>&yd{K2aOoP9a2N6`Tppu(UuZIl|alUQM+FL}tGxWe}cp5@*|N63(} zN2dk_y4x&LZ1CaRee)P#j&WU_`?nq6TN ztUqLaDht^zFk$JhC|j<>Ubg|7Rvn7aN=7XF65&4Cv~o^InDsv_xk~s2xpYc`iwRb( z0H&IcpCK8$EZ_Lz9Qt6f#ZMw3@pJU>MISwF+GCnan9>4+E`GO;rOhwWBDH&<_=YWo z{1r@(p0-RpV{s#Mg!q%|*iby+xVgfKJ^|fKQF*V;ZWl9Wn%(}+%sn3))YdG86EmLO&|~!;vy~y$iCGy)yyu>k44sVZ=W+ z6^cutm*&lYDXeq?G@ck*9j4)wah){CG&_l2Wa;`bJrCIqz{Jx!TShscbF^_7AC5UV z-wL1VAS+Nq*604l&ZqOyxUt5k))>pkw%I!ue=*?6uDp`>F7c~RL2jeJlL*n^;vo+T z&>=0rp5&>I#_|PwXnXHD0%pKI M`Ji&H@?-D+1#d8cSpWb4 diff --git a/integration_tests/data/extrinsics/kusama/spec1042_block106284/EXTRINSIC_spec_1042_block_106284_index_0.bin b/integration_tests/data/extrinsics/kusama/spec1042_block106284/EXTRINSIC_spec_1042_block_106284_index_0.bin deleted file mode 100644 index 3f3365afbfd18aed2ce1e5fab6f8afcbc8721206..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 TcmdO3VPfDeI1_a%kC6)i5ZnVJ diff --git a/integration_tests/data/extrinsics/kusama/spec1042_block106284/EXTRINSIC_spec_1042_block_106284_index_1.bin b/integration_tests/data/extrinsics/kusama/spec1042_block106284/EXTRINSIC_spec_1042_block_106284_index_1.bin deleted file mode 100644 index 144b09de88678f20f9d0c053312e98055b32da9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9 Qcmb1P;bd4tZ*iqg1S^1*!nD5JaI$1r$k* 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 diff --git a/integration_tests/data/extrinsics/kusama/spec1042_block899638/EXTRINSIC_spec_1042_block_899638_index_0.bin b/integration_tests/data/extrinsics/kusama/spec1042_block899638/EXTRINSIC_spec_1042_block_899638_index_0.bin deleted file mode 100644 index 26b66228f3202a83426e4da7da0989b8b1614118..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 TcmdO3VPfFEaD|7ffRPIT4(tMN diff --git a/integration_tests/data/extrinsics/kusama/spec1042_block899638/EXTRINSIC_spec_1042_block_899638_index_1.bin b/integration_tests/data/extrinsics/kusama/spec1042_block899638/EXTRINSIC_spec_1042_block_899638_index_1.bin deleted file mode 100644 index 45bbdf173872fadf4288106221001fd92a048061..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9 Qcmb1P;bb`V!i<3n012W38~^|S diff --git a/integration_tests/data/extrinsics/kusama/spec1042_block899638/EXTRINSIC_spec_1042_block_899638_index_2.bin b/integration_tests/data/extrinsics/kusama/spec1042_block899638/EXTRINSIC_spec_1042_block_899638_index_2.bin deleted file mode 100644 index bf51eab782a4c1cb186ebc426ce5c163aff84280..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6 NcmWe&5n*890ssKi05bpp diff --git a/integration_tests/data/extrinsics/kusama/spec1042_block899638/EXTRINSIC_spec_1042_block_899638_index_3.bin b/integration_tests/data/extrinsics/kusama/spec1042_block899638/EXTRINSIC_spec_1042_block_899638_index_3.bin deleted file mode 100644 index 0881622216ef3a7a984e4cac45c609bebf524431..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 151 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

V#)iCY&lznu8~(wVk)JYD4u~BmweG@J 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

YN#GH;-qYSFfjjb6v@QABis$JUD&_}j$FajHl+ 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 Vec { f.read_to_end(&mut buffer).expect("Reading file failed"); buffer } - diff --git a/integration_tests/tests/storage.rs b/integration_tests/tests/storage.rs index b9183b9f..3cb60852 100644 --- a/integration_tests/tests/storage.rs +++ b/integration_tests/tests/storage.rs @@ -1,12 +1,11 @@ -use crate::test_suite; +use crate::runtime_metadata::*; +use anyhow::Result; use codec::Encode; use desub_core::{ decoder::{Chain, Decoder, Metadata}, SubstrateType, }; use primitives::twox_128; -use anyhow::Result; - /// T::BlockNumber in meta V11 Block 1768321 fn get_plain_value() -> (Vec, Option>) { @@ -23,7 +22,7 @@ fn should_decode_plain() { let types = extras::TypeResolver::default(); let mut decoder = Decoder::new(types, Chain::Kusama); - let meta = test_suite::runtime_v11(); + let meta = runtime_v11(); let meta = Metadata::new(meta.as_slice()); decoder.register_version(2023, &meta); @@ -38,7 +37,7 @@ fn should_decode_map() -> Result<()> { let types = extras::TypeResolver::default(); let mut decoder = Decoder::new(types, Chain::Kusama); - let meta = test_suite::runtime_v11(); + let meta = runtime_v11(); let meta = Metadata::new(meta.as_slice()); decoder.register_version(2023, &meta); // AccountInfo from block 3944196 @@ -57,11 +56,13 @@ fn should_decode_map_ksm_3944195() -> Result<()> { let types = extras::TypeResolver::default(); let mut decoder = Decoder::new(types, Chain::Kusama); - let meta = test_suite::runtime_v11(); + let meta = runtime_v11(); let meta = Metadata::new(meta.as_slice()); decoder.register_version(2023, &meta); // BlockHash from block 3944196 - let storage_key = hex::decode("26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c1187465eb805861b659fd1022f3c00").unwrap(); + let storage_key = + hex::decode("26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c1187465eb805861b659fd1022f3c00") + .unwrap(); let encoded_hash = hex::decode("38f14d3d028e2f5b9ce889a444b49e774b88bcb3fe205fa4f5a10c2e66290c59").unwrap(); let res = decoder.decode_storage(2023, (storage_key, Some(encoded_hash)))?; @@ -69,14 +70,13 @@ fn should_decode_map_ksm_3944195() -> Result<()> { Ok(()) } - #[test] fn should_decode_double_map() { let _ = pretty_env_logger::try_init(); let types = extras::TypeResolver::default(); let mut decoder = Decoder::new(types, Chain::Kusama); - let meta = test_suite::runtime_v11(); + let meta = runtime_v11(); let meta = Metadata::new(meta.as_slice()); decoder.register_version(2023, &meta); // THIS STORAGE KEY IS WRONG for "ImOnline AuthoredBlocks" type diff --git a/integration_tests/tests/test_suite.rs b/integration_tests/tests/test_suite.rs deleted file mode 100644 index afb5685c..00000000 --- a/integration_tests/tests/test_suite.rs +++ /dev/null @@ -1,87 +0,0 @@ -mod runtime_metadata; - -const EXT_PATH: &'static str = "./data/extrinsics/"; -use desub_core::decoder::Chain; -use std::{fs::File, io::prelude::*}; - -use paste::paste; - -pub use runtime_metadata::*; - -// NOTE: it is only usable in the current file. -macro_rules! decl_extrinsic_test { - ( - $( - [$spec:expr, $chain: expr, $block:expr] - )* - ) => { - $( - paste! { - pub fn []() -> (Vec, Vec>) { - let mut exts: Vec> = Vec::new(); - if std::path::Path::new("./integration_tests").exists() { - std::env::set_current_dir("./integration_tests").unwrap(); - } - let path = format!("{}{}/", EXT_PATH, $chain); - let path = &format!("{}spec{}_block{}/", path, $spec, $block); - println!( - "{}/{}", - path, - std::env::current_dir().unwrap().to_str().unwrap() - ); - - // get the number of files with prefix ${path}_EXTRINSIC in the directory. - let num_ext = std::fs::read_dir(&path) - .unwrap() - .map(|d| d.unwrap().file_name().into_string().unwrap()) - .filter(|ext| ext.starts_with("EXTRINSIC")) - .count(); - for i in 0..num_ext { - let ext_path = &format!( - "{}EXTRINSIC_spec_{}_block_{}_index_{}.bin", - &path, $spec, $block, i - ); - let mut f = File::open(ext_path).expect("Opening extrinsic failed"); - let mut ext = Vec::new(); - f.read_to_end(&mut ext).expect("Reading file failed"); - exts.push(ext) - } - - let mut f = File::open(&format!( - "{}spec_{}_block_{}_METADATA.bin", - &path, $spec, $block - )).expect("Opening Metadata file failed"); - - let mut meta = Vec::new(); - f.read_to_end(&mut meta).expect("Reading file failed"); - - (meta, exts) - } - } - )* - }; -} - -decl_extrinsic_test! { - ["1031", Chain::Kusama, "342962"] - ["1031", Chain::Kusama, "422871"] - ["1031", Chain::Kusama, "50970"] - ["1042", Chain::Kusama, "106284"] - ["1055", Chain::Kusama, "1674683"] - ["1055", Chain::Kusama, "1677621"] - ["1055", Chain::Kusama, "1702023"] - ["1055", Chain::Kusama, "1714495"] - ["1055", Chain::Kusama, "1717926"] - ["1055", Chain::Kusama, "1718223"] - ["1055", Chain::Kusama, "1732321"] - ["1055", Chain::Kusama, "1731904"] - ["1055", Chain::Kusama, "1768321"] - ["1020", Chain::Kusama, "6144"] - ["1042", Chain::Kusama, "779410"] - ["1042", Chain::Kusama, "899638"] - ["1030", Chain::Kusama, "233816"] - ["1039", Chain::Kusama, "607421"] - ["0", Chain::Polkadot, "892"] - ["1", Chain::Westend, "1191"] -} - diff --git a/substrate-metadata-versions/metadatav10/Cargo.toml b/substrate-metadata-versions/metadatav10/Cargo.toml index 0537de40..349d2409 100644 --- a/substrate-metadata-versions/metadatav10/Cargo.toml +++ b/substrate-metadata-versions/metadatav10/Cargo.toml @@ -6,16 +6,15 @@ edition = "2018" license = "GPL-3.0" [dependencies] -codec = { package = "parity-scale-codec", version = "1", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "2", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-std = { version = "2.0.0-rc6", default-features = false, git = "https://github.com/paritytech/substrate" , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } -sp-core = { path = "../sp_core_versions/core-7314a/" } +frame-metadata = { version = "14.0.0", features = ["v13"] } [features] default = ["std"] std = [ "codec/std", "sp-std/std", - "sp-core/std", "serde", ] diff --git a/substrate-metadata-versions/metadatav10/src/lib.rs b/substrate-metadata-versions/metadatav10/src/lib.rs index f6e280be..9b6d4bfa 100644 --- a/substrate-metadata-versions/metadatav10/src/lib.rs +++ b/substrate-metadata-versions/metadatav10/src/lib.rs @@ -19,7 +19,7 @@ //! This really doesn't belong here, but is necessary for the moment. In the future //! it should be removed entirely to an external module for shimming on to the //! codec-encoded metadata. - +#![allow(clippy::all)] #![cfg_attr(not(feature = "std"), no_std)] #[cfg(feature = "std")] @@ -28,10 +28,7 @@ use serde::Serialize; use codec::{Decode, Input, Error}; use codec::{Encode, Output}; use sp_std::vec::Vec; -use sp_core::RuntimeDebug; - -#[cfg(feature = "std")] -type StringBuf = String; +use frame_metadata::decode_different::*; /// Curent prefix of metadata pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness @@ -40,84 +37,8 @@ pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness /// So, if someone tries to decode this stuff on `no_std`, they will get a compilation error. #[cfg(not(feature = "std"))] type StringBuf = &'static str; - -/// A type that decodes to a different type than it encodes. -/// The user needs to make sure that both types use the same encoding. -/// -/// For example a `&'static [ &'static str ]` can be decoded to a `Vec`. -#[derive(Clone)] -pub enum DecodeDifferent where B: 'static, O: 'static { - Encode(B), - Decoded(O), -} - -impl Encode for DecodeDifferent where B: Encode + 'static, O: Encode + 'static { - fn encode_to(&self, dest: &mut W) { - match self { - DecodeDifferent::Encode(b) => b.encode_to(dest), - DecodeDifferent::Decoded(o) => o.encode_to(dest), - } - } -} - -impl codec::EncodeLike for DecodeDifferent where B: Encode + 'static, O: Encode + 'static {} - -#[cfg(feature = "std")] -impl Decode for DecodeDifferent where B: 'static, O: Decode + 'static { - fn decode(input: &mut I) -> Result { - ::decode(input).map(|val| { - DecodeDifferent::Decoded(val) - }) - } -} - -impl PartialEq for DecodeDifferent -where - B: Encode + Eq + PartialEq + 'static, - O: Encode + Eq + PartialEq + 'static, -{ - fn eq(&self, other: &Self) -> bool { - self.encode() == other.encode() - } -} - -impl Eq for DecodeDifferent - where B: Encode + Eq + PartialEq + 'static, O: Encode + Eq + PartialEq + 'static -{} - -impl sp_std::fmt::Debug for DecodeDifferent - where - B: sp_std::fmt::Debug + Eq + 'static, - O: sp_std::fmt::Debug + Eq + 'static, -{ - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - match self { - DecodeDifferent::Encode(b) => b.fmt(f), - DecodeDifferent::Decoded(o) => o.fmt(f), - } - } -} - -#[cfg(feature = "std")] -impl serde::Serialize for DecodeDifferent - where - B: serde::Serialize + 'static, - O: serde::Serialize + 'static, -{ - fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - match self { - DecodeDifferent::Encode(b) => b.serialize(serializer), - DecodeDifferent::Decoded(o) => o.serialize(serializer), - } - } -} - -pub type DecodeDifferentArray = DecodeDifferent<&'static [B], Vec>; - -type DecodeDifferentStr = DecodeDifferent<&'static str, StringBuf>; - /// All the metadata about a function. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct FunctionMetadata { pub name: DecodeDifferentStr, @@ -126,7 +47,7 @@ pub struct FunctionMetadata { } /// All the metadata about a function argument. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct FunctionArgumentMetadata { pub name: DecodeDifferentStr, @@ -138,7 +59,7 @@ pub struct FunctionArgumentMetadata { pub struct FnEncode(pub fn() -> E) where E: Encode + 'static; impl Encode for FnEncode { - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { self.0().encode_to(dest); } } @@ -165,7 +86,7 @@ impl serde::Serialize for FnEncode { } /// All the metadata about an outer event. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct OuterEventMetadata { pub name: DecodeDifferentStr, @@ -176,7 +97,7 @@ pub struct OuterEventMetadata { } /// All the metadata about an event. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct EventMetadata { pub name: DecodeDifferentStr, @@ -185,7 +106,7 @@ pub struct EventMetadata { } /// All the metadata about one storage entry. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct StorageEntryMetadata { pub name: DecodeDifferentStr, @@ -196,7 +117,7 @@ pub struct StorageEntryMetadata { } /// All the metadata about one module constant. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct ModuleConstantMetadata { pub name: DecodeDifferentStr, @@ -206,7 +127,7 @@ pub struct ModuleConstantMetadata { } /// All the metadata about a module error. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct ErrorMetadata { pub name: DecodeDifferentStr, @@ -237,7 +158,7 @@ pub struct DefaultByteGetter(pub &'static dyn DefaultByte); pub type ByteGetter = DecodeDifferent>; impl Encode for DefaultByteGetter { - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { self.0.default_byte().encode_to(dest) } } @@ -268,7 +189,7 @@ impl sp_std::fmt::Debug for DefaultByteGetter { } /// Hasher used by storage maps -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum StorageHasher { Blake2_128, @@ -280,7 +201,7 @@ pub enum StorageHasher { } /// A storage entry type. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum StorageEntryType { Plain(DecodeDifferentStr), @@ -300,7 +221,7 @@ pub enum StorageEntryType { } /// A storage entry modifier. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum StorageEntryModifier { Optional, @@ -308,7 +229,7 @@ pub enum StorageEntryModifier { } /// All metadata of the storage. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct StorageMetadata { /// The common prefix used by all storage entries. @@ -316,7 +237,7 @@ pub struct StorageMetadata { pub entries: DecodeDifferent<&'static [StorageEntryMetadata], Vec>, } -#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[derive(Eq, Encode, PartialEq)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] /// Metadata prefixed by a u32 for reserved usage pub struct RuntimeMetadataPrefixed(pub u32, pub RuntimeMetadata); @@ -324,7 +245,7 @@ pub struct RuntimeMetadataPrefixed(pub u32, pub RuntimeMetadata); /// The metadata of a runtime. /// The version ID encoded/decoded through /// the enum nature of `RuntimeMetadata`. -#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[derive(Eq, Encode, PartialEq)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum RuntimeMetadata { /// Unused; enum filler. @@ -352,12 +273,12 @@ pub enum RuntimeMetadata { } /// Enum that should fail. -#[derive(Eq, PartialEq, RuntimeDebug)] +#[derive(Eq, PartialEq)] #[cfg_attr(feature = "std", derive(Serialize))] pub enum RuntimeMetadataDeprecated { } impl Encode for RuntimeMetadataDeprecated { - fn encode_to(&self, _dest: &mut W) {} + fn encode_to(&self, _dest: &mut W) {} } impl codec::EncodeLike for RuntimeMetadataDeprecated {} @@ -370,7 +291,7 @@ impl Decode for RuntimeMetadataDeprecated { } /// The metadata of a runtime. -#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[derive(Eq, Encode, PartialEq)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct RuntimeMetadataV10 { pub modules: DecodeDifferentArray, @@ -380,7 +301,7 @@ pub struct RuntimeMetadataV10 { pub type RuntimeMetadataLastVersion = RuntimeMetadataV10; /// All metadata about an runtime module. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct ModuleMetadata { pub name: DecodeDifferentStr, @@ -394,9 +315,9 @@ pub struct ModuleMetadata { type ODFnA = Option>; type DFnA = DecodeDifferent, Vec>; -impl Into for RuntimeMetadataPrefixed { - fn into(self) -> sp_core::OpaqueMetadata { - sp_core::OpaqueMetadata::new(self.encode()) +impl Into for RuntimeMetadataPrefixed { + fn into(self) -> frame_metadata::OpaqueMetadata { + frame_metadata::OpaqueMetadata(self.encode()) } } diff --git a/substrate-metadata-versions/metadatav11/Cargo.lock b/substrate-metadata-versions/metadatav11/Cargo.lock deleted file mode 100644 index 979ced02..00000000 --- a/substrate-metadata-versions/metadatav11/Cargo.lock +++ /dev/null @@ -1,1791 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "Inflector" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -dependencies = [ - "lazy_static", - "regex", -] - -[[package]] -name = "addr2line" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" - -[[package]] -name = "aho-corasick" -version = "0.7.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b476ce7103678b0c6d3d395dbbae31d48ff910bd28be979ba5d48c6351131d0d" -dependencies = [ - "memchr", -] - -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - -[[package]] -name = "arrayref" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" - -[[package]] -name = "arrayvec" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" -dependencies = [ - "nodrop", -] - -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "backtrace" -version = "0.3.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707b586e0e2f247cbde68cdd2c3ce69ea7b7be43e1c5b426e37c9319c4b9838e" -dependencies = [ - "addr2line", - "cfg-if 1.0.0", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base58" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" - -[[package]] -name = "bitflags" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" - -[[package]] -name = "bitvec" -version = "0.17.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" -dependencies = [ - "either", - "radium", -] - -[[package]] -name = "blake2-rfc" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" -dependencies = [ - "arrayvec 0.4.12", - "constant_time_eq", -] - -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -dependencies = [ - "block-padding", - "byte-tools", - "byteorder", - "generic-array 0.12.3", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", -] - -[[package]] -name = "byte-slice-cast" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" - -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - -[[package]] -name = "byteorder" -version = "1.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" - -[[package]] -name = "cc" -version = "1.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed67cbde08356238e75fc4656be4749481eeffb09e19f320a25237d5221c985d" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" -dependencies = [ - "libc", - "num-integer", - "num-traits", - "time", - "winapi", -] - -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags", -] - -[[package]] -name = "cloudabi" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467" -dependencies = [ - "bitflags", -] - -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - -[[package]] -name = "cpuid-bool" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-mac" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" -dependencies = [ - "generic-array 0.12.3", - "subtle 1.0.0", -] - -[[package]] -name = "curve25519-dalek" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d85653f070353a16313d0046f173f70d1aadd5b42600a14de626f0dfb3473a5" -dependencies = [ - "byteorder", - "digest 0.8.1", - "rand_core", - "subtle 2.3.0", - "zeroize", -] - -[[package]] -name = "curve25519-dalek" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8492de420e9e60bc9a1d66e2dbb91825390b738a388606600663fc529b4b307" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core", - "subtle 2.3.0", - "zeroize", -] - -[[package]] -name = "derive_more" -version = "0.99.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.3", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "dyn-clonable" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4" -dependencies = [ - "dyn-clonable-impl", - "dyn-clone", -] - -[[package]] -name = "dyn-clonable-impl" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dyn-clone" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d55796afa1b20c2945ca8eabfc421839f2b766619209f1ede813cf2484f31804" - -[[package]] -name = "ed25519" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c66a534cbb46ab4ea03477eae19d5c22c01da8258030280b7bd9d8433fb6ef" -dependencies = [ - "signature", -] - -[[package]] -name = "ed25519-dalek" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" -dependencies = [ - "curve25519-dalek 3.0.0", - "ed25519", - "rand", - "serde", - "sha2 0.9.1", - "zeroize", -] - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "environmental" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6576a1755ddffd988788025e75bce9e74b018f7cc226198fe931d077911c6d7e" - -[[package]] -name = "failure" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" -dependencies = [ - "backtrace", - "failure_derive", -] - -[[package]] -name = "failure_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - -[[package]] -name = "fixed-hash" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11498d382790b7a8f2fd211780bec78619bba81cdad3a283997c0c41f836759c" -dependencies = [ - "byteorder", - "rand", - "rustc-hex", - "static_assertions", -] - -[[package]] -name = "frame-metadatav11" -version = "11.0.0-rc6" -dependencies = [ - "parity-scale-codec", - "serde", - "sp-core", - "sp-std", -] - -[[package]] -name = "futures" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95314d38584ffbfda215621d723e0a3906f032e03ae5551e650058dac83d4797" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0448174b01148032eed37ac4aed28963aaaa8cfa93569a08e5b479bbc6c2c151" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18eaa56102984bed2c88ea39026cff3ce3b4c7f508ca970cedf2450ea10d4e46" - -[[package]] -name = "futures-executor" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5f8e0c9258abaea85e78ebdda17ef9666d390e987f006be6080dfe354b708cb" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", - "num_cpus", -] - -[[package]] -name = "futures-io" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1798854a4727ff944a7b12aa999f58ce7aa81db80d2dfaaf2ba06f065ddd2b" - -[[package]] -name = "futures-macro" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36fccf3fc58563b4a14d265027c627c3b665d7fed489427e88e7cc929559efe" -dependencies = [ - "proc-macro-hack", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e3ca3f17d6e8804ae5d3df7a7d35b2b3a6fe89dac84b31872720fc3060a0b11" - -[[package]] -name = "futures-task" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d502af37186c4fef99453df03e374683f8a1eec9dcc1e66b3b82dc8278ce3c" -dependencies = [ - "once_cell", -] - -[[package]] -name = "futures-util" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abcb44342f62e6f3e8ac427b8aa815f724fd705dfad060b18ac7866c15bb8e34" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project", - "pin-utils", - "proc-macro-hack", - "proc-macro-nested", - "slab", -] - -[[package]] -name = "generator" -version = "0.6.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cdc09201b2e8ca1b19290cf7e65de2246b8e91fb6874279722189c4de7b94dc" -dependencies = [ - "cc", - "libc", - "log", - "rustc_version", - "winapi", -] - -[[package]] -name = "generic-array" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" -dependencies = [ - "typenum", -] - -[[package]] -name = "generic-array" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "gimli" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724" - -[[package]] -name = "hash-db" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" - -[[package]] -name = "hash256-std-hasher" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" -dependencies = [ - "crunchy", -] - -[[package]] -name = "hermit-abi" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" -dependencies = [ - "libc", -] - -[[package]] -name = "hex" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" - -[[package]] -name = "hmac" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" -dependencies = [ - "crypto-mac", - "digest 0.8.1", -] - -[[package]] -name = "hmac-drbg" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" -dependencies = [ - "digest 0.8.1", - "generic-array 0.12.3", - "hmac", -] - -[[package]] -name = "impl-codec" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" -dependencies = [ - "parity-scale-codec", -] - -[[package]] -name = "impl-serde" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b47ca4d2b6931707a55fce5cf66aff80e2178c8b63bbb4ecb5695cbc870ddf6f" -dependencies = [ - "serde", -] - -[[package]] -name = "impl-trait-for-tuples" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "instant" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb1fc4429a33e1f80d41dc9fea4d108a88bec1de8053878898ae448a0b52f613" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "itoa" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" - -[[package]] -name = "keccak" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" - -[[package]] -name = "libsecp256k1" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" -dependencies = [ - "arrayref", - "crunchy", - "digest 0.8.1", - "hmac-drbg", - "rand", - "sha2 0.8.2", - "subtle 2.3.0", - "typenum", -] - -[[package]] -name = "lock_api" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "lock_api" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" -dependencies = [ - "cfg-if 0.1.10", -] - -[[package]] -name = "loom" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0e8460f2f2121162705187214720353c517b97bdfb3494c0b1e33d83ebe4bed" -dependencies = [ - "cfg-if 0.1.10", - "generator", - "scoped-tls", - "serde", - "serde_json", -] - -[[package]] -name = "matchers" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" -dependencies = [ - "regex-automata", -] - -[[package]] -name = "memchr" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" - -[[package]] -name = "memory_units" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" - -[[package]] -name = "merlin" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6feca46f4fa3443a01769d768727f10c10a20fdb65e52dc16a81f0c8269bb78" -dependencies = [ - "byteorder", - "keccak", - "rand_core", - "zeroize", -] - -[[package]] -name = "miniz_oxide" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" -dependencies = [ - "adler", - "autocfg", -] - -[[package]] -name = "nodrop" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" - -[[package]] -name = "num-bigint" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" -dependencies = [ - "autocfg", - "num-bigint", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37fd5004feb2ce328a52b0b3d01dbf4ffff72583493900ed15f22d4111c51693" - -[[package]] -name = "once_cell" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad" -dependencies = [ - "parking_lot 0.11.0", -] - -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "parity-scale-codec" -version = "1.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c740e5fbcb6847058b40ac7e5574766c6388f585e184d769910fe0d3a2ca861" -dependencies = [ - "arrayvec 0.5.2", - "bitvec", - "byte-slice-cast", - "parity-scale-codec-derive", - "serde", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "198db82bb1c18fc00176004462dd809b2a6d851669550aa17af6dacd21ae0c14" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "parity-util-mem" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "297ff91fa36aec49ce183484b102f6b75b46776822bd81525bfc4cc9b0dd0f5c" -dependencies = [ - "cfg-if 0.1.10", - "impl-trait-for-tuples", - "parity-util-mem-derive", - "primitive-types", - "winapi", -] - -[[package]] -name = "parity-util-mem-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" -dependencies = [ - "proc-macro2", - "syn", - "synstructure", -] - -[[package]] -name = "parity-wasm" -version = "0.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" - -[[package]] -name = "parking_lot" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" -dependencies = [ - "lock_api 0.3.4", - "parking_lot_core 0.7.2", -] - -[[package]] -name = "parking_lot" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733" -dependencies = [ - "instant", - "lock_api 0.4.1", - "parking_lot_core 0.8.0", -] - -[[package]] -name = "parking_lot_core" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" -dependencies = [ - "cfg-if 0.1.10", - "cloudabi 0.0.3", - "libc", - "redox_syscall", - "smallvec", - "winapi", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" -dependencies = [ - "cfg-if 0.1.10", - "cloudabi 0.1.0", - "instant", - "libc", - "redox_syscall", - "smallvec", - "winapi", -] - -[[package]] -name = "pbkdf2" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" -dependencies = [ - "byteorder", - "crypto-mac", -] - -[[package]] -name = "pin-project" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee41d838744f60d959d7074e3afb6b35c7456d0f61cad38a24e35e6553f73841" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81a4ffa594b66bff340084d4081df649a7dc049ac8d7fc458d8e628bfbbb2f86" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-lite" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "ppv-lite86" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20" - -[[package]] -name = "primitive-types" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55c21c64d0eaa4d7ed885d959ef2d62d9e488c27c0e02d9aa5ce6c877b7d5f8" -dependencies = [ - "fixed-hash", - "impl-codec", - "impl-serde", - "uint", -] - -[[package]] -name = "proc-macro-crate" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" -dependencies = [ - "toml", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598" - -[[package]] -name = "proc-macro-nested" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a" - -[[package]] -name = "proc-macro2" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radium" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom", - "libc", - "rand_chacha", - "rand_core", - "rand_hc", - "rand_pcg", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core", -] - -[[package]] -name = "rand_pcg" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -dependencies = [ - "rand_core", -] - -[[package]] -name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - -[[package]] -name = "ref-cast" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "745c1787167ddae5569661d5ffb8b25ae5fedbf46717eaa92d652221cec72623" -dependencies = [ - "ref-cast-impl", -] - -[[package]] -name = "ref-cast-impl" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d21b475ab879ef0e315ad99067fa25778c3b0377f57f1b00207448dac1a3144" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "regex" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8963b85b8ce3074fecffde43b4b0dded83ce2f367dc8d363afc56679f3ee820b" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", - "thread_local", -] - -[[package]] -name = "regex-automata" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" -dependencies = [ - "byteorder", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cab7a364d15cde1e505267766a2d3c4e22a843e1a601f0fa7564c0f82ced11c" - -[[package]] -name = "rustc-demangle" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc-hex" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", -] - -[[package]] -name = "ryu" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" - -[[package]] -name = "schnorrkel" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862" -dependencies = [ - "arrayref", - "arrayvec 0.5.2", - "curve25519-dalek 2.1.0", - "getrandom", - "merlin", - "rand", - "rand_core", - "sha2 0.8.2", - "subtle 2.3.0", - "zeroize", -] - -[[package]] -name = "scoped-tls" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "secrecy" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9182278ed645df3477a9c27bfee0621c621aa16f6972635f7f795dae3d81070f" -dependencies = [ - "zeroize", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - -[[package]] -name = "serde" -version = "1.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.59" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha2" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" -dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "fake-simd", - "opaque-debug 0.2.3", -] - -[[package]] -name = "sha2" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 0.1.10", - "cpuid-bool", - "digest 0.9.0", - "opaque-debug 0.3.0", -] - -[[package]] -name = "sharded-slab" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4921be914e16899a80adefb821f8ddb7974e3f1250223575a44ed994882127" -dependencies = [ - "lazy_static", - "loom", -] - -[[package]] -name = "signature" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29f060a7d147e33490ec10da418795238fd7545bba241504d6b31a409f2e6210" - -[[package]] -name = "slab" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" - -[[package]] -name = "smallvec" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252" - -[[package]] -name = "sp-core" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "base58", - "blake2-rfc", - "byteorder", - "derive_more", - "dyn-clonable", - "ed25519-dalek", - "futures", - "hash-db", - "hash256-std-hasher", - "hex", - "impl-serde", - "lazy_static", - "libsecp256k1", - "log", - "merlin", - "num-traits", - "parity-scale-codec", - "parity-util-mem", - "parking_lot 0.10.2", - "primitive-types", - "rand", - "regex", - "schnorrkel", - "secrecy", - "serde", - "sha2 0.8.2", - "sp-debug-derive", - "sp-externalities", - "sp-runtime-interface", - "sp-std", - "sp-storage", - "substrate-bip39", - "tiny-bip39", - "tiny-keccak", - "twox-hash", - "wasmi", - "zeroize", -] - -[[package]] -name = "sp-debug-derive" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "sp-externalities" -version = "0.8.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "environmental", - "parity-scale-codec", - "sp-std", - "sp-storage", -] - -[[package]] -name = "sp-runtime-interface" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "parity-scale-codec", - "primitive-types", - "sp-externalities", - "sp-runtime-interface-proc-macro", - "sp-std", - "sp-storage", - "sp-tracing", - "sp-wasm-interface", - "static_assertions", -] - -[[package]] -name = "sp-runtime-interface-proc-macro" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "Inflector", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "sp-std" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" - -[[package]] -name = "sp-storage" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "impl-serde", - "parity-scale-codec", - "ref-cast", - "serde", - "sp-debug-derive", - "sp-std", -] - -[[package]] -name = "sp-tracing" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "log", - "parity-scale-codec", - "sp-std", - "tracing", - "tracing-core", - "tracing-subscriber", -] - -[[package]] -name = "sp-wasm-interface" -version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?rev=7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2#7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" -dependencies = [ - "impl-trait-for-tuples", - "parity-scale-codec", - "sp-std", - "wasmi", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "substrate-bip39" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bed6646a0159b9935b5d045611560eeef842b78d7adc3ba36f5ca325a13a0236" -dependencies = [ - "hmac", - "pbkdf2", - "schnorrkel", - "sha2 0.8.2", - "zeroize", -] - -[[package]] -name = "subtle" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" - -[[package]] -name = "subtle" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd" - -[[package]] -name = "syn" -version = "1.0.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "synstructure" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", -] - -[[package]] -name = "thread_local" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "time" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "tiny-bip39" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0165e045cc2ae1660270ca65e1676dbaab60feb0f91b10f7d0665e9b47e31f2" -dependencies = [ - "failure", - "hmac", - "once_cell", - "pbkdf2", - "rand", - "rustc-hash", - "sha2 0.8.2", - "unicode-normalization", -] - -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tinyvec" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117" - -[[package]] -name = "toml" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645" -dependencies = [ - "serde", -] - -[[package]] -name = "tracing" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0987850db3733619253fe60e17cb59b82d37c7e6c0236bb81e4d6b87c879f27" -dependencies = [ - "cfg-if 0.1.10", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e0ccfc3378da0cce270c946b676a376943f5cd16aeba64568e7939806f4ada" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "tracing-log" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e0f8c7178e13481ff6765bd169b33e8d554c5d2bbede5e32c356194be02b9b9" -dependencies = [ - "lazy_static", - "log", - "tracing-core", -] - -[[package]] -name = "tracing-serde" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b" -dependencies = [ - "serde", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2810660b9d5b18895d140caba6401765749a6a162e5d0736cfc44ea50db9d79d" -dependencies = [ - "ansi_term", - "chrono", - "lazy_static", - "matchers", - "regex", - "serde", - "serde_json", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", - "tracing-serde", -] - -[[package]] -name = "twox-hash" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59" -dependencies = [ - "cfg-if 0.1.10", - "rand", - "static_assertions", -] - -[[package]] -name = "typenum" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" - -[[package]] -name = "uint" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9db035e67dfaf7edd9aebfe8676afcd63eed53c8a4044fed514c8cccf1835177" -dependencies = [ - "byteorder", - "crunchy", - "rustc-hex", - "static_assertions", -] - -[[package]] -name = "unicode-normalization" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-xid" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" - -[[package]] -name = "version_check" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - -[[package]] -name = "wasmi" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf617d864d25af3587aa745529f7aaa541066c876d57e050c0d0c85c61c92aff" -dependencies = [ - "libc", - "memory_units", - "num-rational", - "num-traits", - "parity-wasm", - "wasmi-validation", -] - -[[package]] -name = "wasmi-validation" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea78c597064ba73596099281e2f4cfc019075122a65cdda3205af94f0b264d93" -dependencies = [ - "parity-wasm", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "zeroize" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f33972566adbd2d3588b0491eb94b98b43695c4ef897903470ede4f3f5a28a" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3f369ddb18862aba61aa49bf31e74d29f0f162dec753063200e1dc084345d16" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] diff --git a/substrate-metadata-versions/metadatav11/Cargo.toml b/substrate-metadata-versions/metadatav11/Cargo.toml index 469f3dd4..00212b52 100644 --- a/substrate-metadata-versions/metadatav11/Cargo.toml +++ b/substrate-metadata-versions/metadatav11/Cargo.toml @@ -13,16 +13,15 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "2", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-std = { default-features = false, git = "https://github.com/paritytech/substrate" , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } -sp-core = { path = "../sp_core_versions/core-7314a/" } +frame-metadata = { version = "14.0.0", features = ["v13"] } [features] default = ["std"] std = [ "codec/std", "sp-std/std", - "sp-core/std", "serde", ] diff --git a/substrate-metadata-versions/metadatav11/src/lib.rs b/substrate-metadata-versions/metadatav11/src/lib.rs index b9f82202..cedac3dd 100644 --- a/substrate-metadata-versions/metadatav11/src/lib.rs +++ b/substrate-metadata-versions/metadatav11/src/lib.rs @@ -21,6 +21,7 @@ //! it should be removed entirely to an external module for shimming on to the //! codec-encoded metadata. +#![allow(clippy::all)] #![cfg_attr(not(feature = "std"), no_std)] #[cfg(feature = "std")] @@ -29,7 +30,7 @@ use serde::Serialize; use codec::{Decode, Input, Error}; use codec::{Encode, Output}; use sp_std::vec::Vec; -use sp_core::RuntimeDebug; +use frame_metadata::decode_different::*; #[cfg(feature = "std")] type StringBuf = String; @@ -37,88 +38,8 @@ type StringBuf = String; /// Current prefix of metadata pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness -/// On `no_std` we do not support `Decode` and thus `StringBuf` is just `&'static str`. -/// So, if someone tries to decode this stuff on `no_std`, they will get a compilation error. -#[cfg(not(feature = "std"))] -type StringBuf = &'static str; - -/// A type that decodes to a different type than it encodes. -/// The user needs to make sure that both types use the same encoding. -/// -/// For example a `&'static [ &'static str ]` can be decoded to a `Vec`. -#[derive(Clone)] -pub enum DecodeDifferent where B: 'static, O: 'static { - Encode(B), - Decoded(O), -} - -impl Encode for DecodeDifferent where B: Encode + 'static, O: Encode + 'static { - fn encode_to(&self, dest: &mut W) { - match self { - DecodeDifferent::Encode(b) => b.encode_to(dest), - DecodeDifferent::Decoded(o) => o.encode_to(dest), - } - } -} - -impl codec::EncodeLike for DecodeDifferent where B: Encode + 'static, O: Encode + 'static {} - -#[cfg(feature = "std")] -impl Decode for DecodeDifferent where B: 'static, O: Decode + 'static { - fn decode(input: &mut I) -> Result { - ::decode(input).map(|val| { - DecodeDifferent::Decoded(val) - }) - } -} - -impl PartialEq for DecodeDifferent -where - B: Encode + Eq + PartialEq + 'static, - O: Encode + Eq + PartialEq + 'static, -{ - fn eq(&self, other: &Self) -> bool { - self.encode() == other.encode() - } -} - -impl Eq for DecodeDifferent - where B: Encode + Eq + PartialEq + 'static, O: Encode + Eq + PartialEq + 'static -{} - -impl sp_std::fmt::Debug for DecodeDifferent - where - B: sp_std::fmt::Debug + Eq + 'static, - O: sp_std::fmt::Debug + Eq + 'static, -{ - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - match self { - DecodeDifferent::Encode(b) => b.fmt(f), - DecodeDifferent::Decoded(o) => o.fmt(f), - } - } -} - -#[cfg(feature = "std")] -impl serde::Serialize for DecodeDifferent - where - B: serde::Serialize + 'static, - O: serde::Serialize + 'static, -{ - fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - match self { - DecodeDifferent::Encode(b) => b.serialize(serializer), - DecodeDifferent::Decoded(o) => o.serialize(serializer), - } - } -} - -pub type DecodeDifferentArray = DecodeDifferent<&'static [B], Vec>; - -type DecodeDifferentStr = DecodeDifferent<&'static str, StringBuf>; - /// All the metadata about a function. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct FunctionMetadata { pub name: DecodeDifferentStr, @@ -127,7 +48,7 @@ pub struct FunctionMetadata { } /// All the metadata about a function argument. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct FunctionArgumentMetadata { pub name: DecodeDifferentStr, @@ -139,7 +60,7 @@ pub struct FunctionArgumentMetadata { pub struct FnEncode(pub fn() -> E) where E: Encode + 'static; impl Encode for FnEncode { - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { self.0().encode_to(dest); } } @@ -166,7 +87,7 @@ impl serde::Serialize for FnEncode { } /// All the metadata about an outer event. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct OuterEventMetadata { pub name: DecodeDifferentStr, @@ -177,7 +98,7 @@ pub struct OuterEventMetadata { } /// All the metadata about an event. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct EventMetadata { pub name: DecodeDifferentStr, @@ -186,7 +107,7 @@ pub struct EventMetadata { } /// All the metadata about one storage entry. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct StorageEntryMetadata { pub name: DecodeDifferentStr, @@ -197,7 +118,7 @@ pub struct StorageEntryMetadata { } /// All the metadata about one module constant. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct ModuleConstantMetadata { pub name: DecodeDifferentStr, @@ -207,7 +128,7 @@ pub struct ModuleConstantMetadata { } /// All the metadata about a module error. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct ErrorMetadata { pub name: DecodeDifferentStr, @@ -238,7 +159,7 @@ pub struct DefaultByteGetter(pub &'static dyn DefaultByte); pub type ByteGetter = DecodeDifferent>; impl Encode for DefaultByteGetter { - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { self.0.default_byte().encode_to(dest) } } @@ -269,7 +190,7 @@ impl sp_std::fmt::Debug for DefaultByteGetter { } /// Hasher used by storage maps -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum StorageHasher { Blake2_128, @@ -282,7 +203,7 @@ pub enum StorageHasher { } /// A storage entry type. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum StorageEntryType { Plain(DecodeDifferentStr), @@ -303,7 +224,7 @@ pub enum StorageEntryType { } /// A storage entry modifier. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum StorageEntryModifier { Optional, @@ -311,7 +232,7 @@ pub enum StorageEntryModifier { } /// All metadata of the storage. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct StorageMetadata { /// The common prefix used by all storage entries. @@ -320,12 +241,12 @@ pub struct StorageMetadata { } /// Metadata prefixed by a u32 for reserved usage -#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[derive(Eq, Encode, PartialEq)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct RuntimeMetadataPrefixed(pub u32, pub RuntimeMetadata); /// Metadata of the extrinsic used by the runtime. -#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[derive(Eq, Encode, PartialEq)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct ExtrinsicMetadata { /// Extrinsic version. @@ -337,7 +258,7 @@ pub struct ExtrinsicMetadata { /// The metadata of a runtime. /// The version ID encoded/decoded through /// the enum nature of `RuntimeMetadata`. -#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[derive(Eq, Encode, PartialEq)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum RuntimeMetadata { /// Unused; enum filler. @@ -367,12 +288,12 @@ pub enum RuntimeMetadata { } /// Enum that should fail. -#[derive(Eq, PartialEq, RuntimeDebug)] +#[derive(Eq, PartialEq)] #[cfg_attr(feature = "std", derive(Serialize))] pub enum RuntimeMetadataDeprecated { } impl Encode for RuntimeMetadataDeprecated { - fn encode_to(&self, _dest: &mut W) {} + fn encode_to(&self, _dest: &mut W) {} } impl codec::EncodeLike for RuntimeMetadataDeprecated {} @@ -385,7 +306,7 @@ impl Decode for RuntimeMetadataDeprecated { } /// The metadata of a runtime. -#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[derive(Eq, Encode, PartialEq)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct RuntimeMetadataV11 { /// Metadata of all the modules. @@ -395,7 +316,7 @@ pub struct RuntimeMetadataV11 { } /// All metadata about an runtime module. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct ModuleMetadata { pub name: DecodeDifferentStr, @@ -409,9 +330,9 @@ pub struct ModuleMetadata { type ODFnA = Option>; type DFnA = DecodeDifferent, Vec>; -impl Into for RuntimeMetadataPrefixed { - fn into(self) -> sp_core::OpaqueMetadata { - sp_core::OpaqueMetadata::new(self.encode()) +impl Into for RuntimeMetadataPrefixed { + fn into(self) -> frame_metadata::OpaqueMetadata { + frame_metadata::OpaqueMetadata(self.encode()) } } diff --git a/substrate-metadata-versions/metadatav8/Cargo.toml b/substrate-metadata-versions/metadatav8/Cargo.toml index 8bb24b03..04c98499 100644 --- a/substrate-metadata-versions/metadatav8/Cargo.toml +++ b/substrate-metadata-versions/metadatav8/Cargo.toml @@ -5,11 +5,10 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -codec = { package = "parity-scale-codec", version = "1", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "2", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } rstd = { package = "sp-std", git = "https://github.com/paritytech/substrate", default-features = false , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } -primitives = { path = "../sp_core_versions/core-7314a/", package = "sp-core" } - +frame-metadata = { version = "14.0.0", features = ["v13"] } [features] @@ -17,7 +16,6 @@ default = ["std"] std = [ "codec/std", "rstd/std", - "primitives/std", "serde", ] diff --git a/substrate-metadata-versions/metadatav8/src/lib.rs b/substrate-metadata-versions/metadatav8/src/lib.rs index 244d1175..28453faa 100644 --- a/substrate-metadata-versions/metadatav8/src/lib.rs +++ b/substrate-metadata-versions/metadatav8/src/lib.rs @@ -19,7 +19,7 @@ //! This really doesn't belong here, but is necessary for the moment. In the future //! it should be removed entirely to an external module for shimming on to the //! codec-encoded metadata. - +#![allow(clippy::all)] #![cfg_attr(not(feature = "std"), no_std)] #[cfg(feature = "std")] @@ -28,96 +28,11 @@ use serde::Serialize; use codec::{Decode, Input, Error}; use codec::{Encode, Output}; use rstd::vec::Vec; - -#[cfg(feature = "std")] -type StringBuf = String; +use frame_metadata::decode_different::*; /// Curent prefix of metadata pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness -/// On `no_std` we do not support `Decode` and thus `StringBuf` is just `&'static str`. -/// So, if someone tries to decode this stuff on `no_std`, they will get a compilation error. -#[cfg(not(feature = "std"))] -type StringBuf = &'static str; - -/// A type that decodes to a different type than it encodes. -/// The user needs to make sure that both types use the same encoding. -/// -/// For example a `&'static [ &'static str ]` can be decoded to a `Vec`. -#[derive(Clone)] -pub enum DecodeDifferent where B: 'static, O: 'static { - Encode(B), - Decoded(O), -} - -impl Encode for DecodeDifferent where B: Encode + 'static, O: Encode + 'static { - fn encode_to(&self, dest: &mut W) { - match self { - DecodeDifferent::Encode(b) => b.encode_to(dest), - DecodeDifferent::Decoded(o) => o.encode_to(dest), - } - } -} - -impl codec::EncodeLike for DecodeDifferent where B: Encode + 'static, O: Encode + 'static {} - -#[cfg(feature = "std")] -impl Decode for DecodeDifferent where B: 'static, O: Decode + 'static { - fn decode(input: &mut I) -> Result { - ::decode(input).map(|val| { - DecodeDifferent::Decoded(val) - }) - } -} - -impl PartialEq for DecodeDifferent -where - B: Encode + Eq + PartialEq + 'static, - O: Encode + Eq + PartialEq + 'static, -{ - fn eq(&self, other: &Self) -> bool { - self.encode() == other.encode() - } -} - -impl Eq for DecodeDifferent - where B: Encode + Eq + PartialEq + 'static, O: Encode + Eq + PartialEq + 'static -{} - -#[cfg(feature = "std")] -impl std::fmt::Debug for DecodeDifferent - where - B: std::fmt::Debug + Eq + 'static, - O: std::fmt::Debug + Eq + 'static, -{ - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - match self { - DecodeDifferent::Encode(b) => b.fmt(f), - DecodeDifferent::Decoded(o) => o.fmt(f), - } - } -} - -#[cfg(feature = "std")] -impl serde::Serialize for DecodeDifferent - where - B: serde::Serialize + 'static, - O: serde::Serialize + 'static, -{ - fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - match self { - DecodeDifferent::Encode(b) => b.serialize(serializer), - DecodeDifferent::Decoded(o) => o.serialize(serializer), - } - } -} - -pub type DecodeDifferentArray = DecodeDifferent<&'static [B], Vec>; - -#[cfg(feature = "std")] -type DecodeDifferentStr = DecodeDifferent<&'static str, StringBuf>; -#[cfg(not(feature = "std"))] -type DecodeDifferentStr = DecodeDifferent<&'static str, StringBuf>; /// All the metadata about a function. #[derive(Clone, PartialEq, Eq, Encode)] @@ -141,7 +56,7 @@ pub struct FunctionArgumentMetadata { pub struct FnEncode(pub fn() -> E) where E: Encode + 'static; impl Encode for FnEncode { - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { self.0().encode_to(dest); } } @@ -241,7 +156,7 @@ pub struct DefaultByteGetter(pub &'static dyn DefaultByte); pub type ByteGetter = DecodeDifferent>; impl Encode for DefaultByteGetter { - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { self.0.default_byte().encode_to(dest) } } @@ -357,7 +272,7 @@ pub enum RuntimeMetadata { pub enum RuntimeMetadataDeprecated { } impl Encode for RuntimeMetadataDeprecated { - fn encode_to(&self, _dest: &mut W) {} + fn encode_to(&self, _dest: &mut W) {} } impl codec::EncodeLike for RuntimeMetadataDeprecated {} @@ -394,9 +309,9 @@ pub struct ModuleMetadata { type ODFnA = Option>; type DFnA = DecodeDifferent, Vec>; -impl Into for RuntimeMetadataPrefixed { - fn into(self) -> primitives::OpaqueMetadata { - primitives::OpaqueMetadata::new(self.encode()) +impl Into for RuntimeMetadataPrefixed { + fn into(self) -> frame_metadata::OpaqueMetadata { + frame_metadata::OpaqueMetadata(self.encode()) } } diff --git a/substrate-metadata-versions/metadatav9/Cargo.toml b/substrate-metadata-versions/metadatav9/Cargo.toml index d9d2745e..12727f77 100644 --- a/substrate-metadata-versions/metadatav9/Cargo.toml +++ b/substrate-metadata-versions/metadatav9/Cargo.toml @@ -5,16 +5,15 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -codec = { package = "parity-scale-codec", version = "1", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "2", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } rstd = { package = "sp-std", git = "https://github.com/paritytech/substrate", default-features = false , rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } -primitives = { path = "../sp_core_versions/core-7314a/", package = "sp-core" } +frame-metadata = { version = "14.0.0", features = ["v13"] } [features] default = ["std"] std = [ "codec/std", "rstd/std", - "primitives/std", "serde", ] diff --git a/substrate-metadata-versions/metadatav9/src/lib.rs b/substrate-metadata-versions/metadatav9/src/lib.rs index b89079fa..813c8aac 100644 --- a/substrate-metadata-versions/metadatav9/src/lib.rs +++ b/substrate-metadata-versions/metadatav9/src/lib.rs @@ -19,7 +19,7 @@ //! This really doesn't belong here, but is necessary for the moment. In the future //! it should be removed entirely to an external module for shimming on to the //! codec-encoded metadata. - +#![allow(clippy::all)] #![cfg_attr(not(feature = "std"), no_std)] #[cfg(feature = "std")] @@ -28,96 +28,13 @@ use serde::Serialize; use codec::{Decode, Input, Error}; use codec::{Encode, Output}; use rstd::vec::Vec; -use primitives::RuntimeDebug; - -#[cfg(feature = "std")] -type StringBuf = String; +use frame_metadata::decode_different::*; /// Curent prefix of metadata pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness -/// On `no_std` we do not support `Decode` and thus `StringBuf` is just `&'static str`. -/// So, if someone tries to decode this stuff on `no_std`, they will get a compilation error. -#[cfg(not(feature = "std"))] -type StringBuf = &'static str; - -/// A type that decodes to a different type than it encodes. -/// The user needs to make sure that both types use the same encoding. -/// -/// For example a `&'static [ &'static str ]` can be decoded to a `Vec`. -#[derive(Clone)] -pub enum DecodeDifferent where B: 'static, O: 'static { - Encode(B), - Decoded(O), -} - -impl Encode for DecodeDifferent where B: Encode + 'static, O: Encode + 'static { - fn encode_to(&self, dest: &mut W) { - match self { - DecodeDifferent::Encode(b) => b.encode_to(dest), - DecodeDifferent::Decoded(o) => o.encode_to(dest), - } - } -} - -impl codec::EncodeLike for DecodeDifferent where B: Encode + 'static, O: Encode + 'static {} - -#[cfg(feature = "std")] -impl Decode for DecodeDifferent where B: 'static, O: Decode + 'static { - fn decode(input: &mut I) -> Result { - ::decode(input).map(|val| { - DecodeDifferent::Decoded(val) - }) - } -} - -impl PartialEq for DecodeDifferent -where - B: Encode + Eq + PartialEq + 'static, - O: Encode + Eq + PartialEq + 'static, -{ - fn eq(&self, other: &Self) -> bool { - self.encode() == other.encode() - } -} - -impl Eq for DecodeDifferent - where B: Encode + Eq + PartialEq + 'static, O: Encode + Eq + PartialEq + 'static -{} - -impl rstd::fmt::Debug for DecodeDifferent - where - B: rstd::fmt::Debug + Eq + 'static, - O: rstd::fmt::Debug + Eq + 'static, -{ - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { - match self { - DecodeDifferent::Encode(b) => b.fmt(f), - DecodeDifferent::Decoded(o) => o.fmt(f), - } - } -} - -#[cfg(feature = "std")] -impl serde::Serialize for DecodeDifferent - where - B: serde::Serialize + 'static, - O: serde::Serialize + 'static, -{ - fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - match self { - DecodeDifferent::Encode(b) => b.serialize(serializer), - DecodeDifferent::Decoded(o) => o.serialize(serializer), - } - } -} - -pub type DecodeDifferentArray = DecodeDifferent<&'static [B], Vec>; - -type DecodeDifferentStr = DecodeDifferent<&'static str, StringBuf>; - /// All the metadata about a function. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct FunctionMetadata { pub name: DecodeDifferentStr, @@ -126,7 +43,7 @@ pub struct FunctionMetadata { } /// All the metadata about a function argument. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct FunctionArgumentMetadata { pub name: DecodeDifferentStr, @@ -138,7 +55,7 @@ pub struct FunctionArgumentMetadata { pub struct FnEncode(pub fn() -> E) where E: Encode + 'static; impl Encode for FnEncode { - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { self.0().encode_to(dest); } } @@ -165,7 +82,7 @@ impl serde::Serialize for FnEncode { } /// All the metadata about an outer event. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct OuterEventMetadata { pub name: DecodeDifferentStr, @@ -176,7 +93,7 @@ pub struct OuterEventMetadata { } /// All the metadata about an event. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct EventMetadata { pub name: DecodeDifferentStr, @@ -185,7 +102,7 @@ pub struct EventMetadata { } /// All the metadata about one storage entry. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct StorageEntryMetadata { pub name: DecodeDifferentStr, @@ -196,7 +113,7 @@ pub struct StorageEntryMetadata { } /// All the metadata about one module constant. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct ModuleConstantMetadata { pub name: DecodeDifferentStr, @@ -206,7 +123,7 @@ pub struct ModuleConstantMetadata { } /// All the metadata about a module error. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct ErrorMetadata { pub name: DecodeDifferentStr, @@ -237,7 +154,7 @@ pub struct DefaultByteGetter(pub &'static dyn DefaultByte); pub type ByteGetter = DecodeDifferent>; impl Encode for DefaultByteGetter { - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { self.0.default_byte().encode_to(dest) } } @@ -268,7 +185,7 @@ impl rstd::fmt::Debug for DefaultByteGetter { } /// Hasher used by storage maps -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum StorageHasher { Blake2_128, @@ -280,7 +197,7 @@ pub enum StorageHasher { } /// A storage entry type. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum StorageEntryType { Plain(DecodeDifferentStr), @@ -300,7 +217,7 @@ pub enum StorageEntryType { } /// A storage entry modifier. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum StorageEntryModifier { Optional, @@ -308,7 +225,7 @@ pub enum StorageEntryModifier { } /// All metadata of the storage. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct StorageMetadata { /// The common prefix used by all storage entries. @@ -316,7 +233,7 @@ pub struct StorageMetadata { pub entries: DecodeDifferent<&'static [StorageEntryMetadata], Vec>, } -#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[derive(Eq, Encode, PartialEq)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] /// Metadata prefixed by a u32 for reserved usage pub struct RuntimeMetadataPrefixed(pub u32, pub RuntimeMetadata); @@ -324,7 +241,7 @@ pub struct RuntimeMetadataPrefixed(pub u32, pub RuntimeMetadata); /// The metadata of a runtime. /// The version ID encoded/decoded through /// the enum nature of `RuntimeMetadata`. -#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[derive(Eq, Encode, PartialEq)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum RuntimeMetadata { /// Unused; enum filler. @@ -350,12 +267,12 @@ pub enum RuntimeMetadata { } /// Enum that should fail. -#[derive(Eq, PartialEq, RuntimeDebug)] +#[derive(Eq, PartialEq)] #[cfg_attr(feature = "std", derive(Serialize))] pub enum RuntimeMetadataDeprecated { } impl Encode for RuntimeMetadataDeprecated { - fn encode_to(&self, _dest: &mut W) {} + fn encode_to(&self, _dest: &mut W) {} } impl codec::EncodeLike for RuntimeMetadataDeprecated {} @@ -368,7 +285,7 @@ impl Decode for RuntimeMetadataDeprecated { } /// The metadata of a runtime. -#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[derive(Eq, Encode, PartialEq)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct RuntimeMetadataV9 { pub modules: DecodeDifferentArray, @@ -378,7 +295,7 @@ pub struct RuntimeMetadataV9 { pub type RuntimeMetadataLastVersion = RuntimeMetadataV9; /// All metadata about an runtime module. -#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct ModuleMetadata { pub name: DecodeDifferentStr, @@ -392,9 +309,9 @@ pub struct ModuleMetadata { type ODFnA = Option>; type DFnA = DecodeDifferent, Vec>; -impl Into for RuntimeMetadataPrefixed { - fn into(self) -> primitives::OpaqueMetadata { - primitives::OpaqueMetadata::new(self.encode()) +impl Into for RuntimeMetadataPrefixed { + fn into(self) -> frame_metadata::OpaqueMetadata { + frame_metadata::OpaqueMetadata(self.encode()) } } diff --git a/substrate-metadata-versions/sp_core_versions/README.md b/substrate-metadata-versions/sp_core_versions/README.md deleted file mode 100644 index 9a94786a..00000000 --- a/substrate-metadata-versions/sp_core_versions/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Locally-Patched `sp-core` packages. - -Usually, a dependency needs to be updated (generally parity-util mem). Dependencies which diverge -from the original package are topped with a comment of the format: -`# PATCHED.insipx.2021Aug20 from `version = "0.7.0"` - - this is mostly to easily & quickly rg patched dependencies - diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/Cargo.toml b/substrate-metadata-versions/sp_core_versions/core-7314a/Cargo.toml deleted file mode 100644 index 1ef45795..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/Cargo.toml +++ /dev/null @@ -1,126 +0,0 @@ -[package] -name = "sp-core" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" -license = "Apache-2.0" -homepage = "https://substrate.dev" -repository = "https://github.com/paritytech/substrate/" -description = "Shareable Substrate types." -documentation = "https://docs.rs/sp-core" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -derive_more = "0.99.2" -sp-std = { version = "2.0.0", default-features = false, git = "https://github.com/paritytech/substrate", rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } -codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } -log = { version = "0.4.8", default-features = false } -serde = { version = "1.0.101", optional = true, features = ["derive"] } -byteorder = { version = "1.3.2", default-features = false } -primitive-types = { version = "0.7.0", default-features = false, features = ["codec"] } -impl-serde = { version = "0.3.0", optional = true } -wasmi = { version = "0.6.2", optional = true } -hash-db = { version = "0.15.2", default-features = false } -hash256-std-hasher = { version = "0.15.2", default-features = false } -base58 = { version = "0.1.0", optional = true } -rand = { version = "0.7.3", optional = true, features = ["small_rng"] } -substrate-bip39 = { version = "0.4.2", optional = true } -tiny-bip39 = { version = "0.7", optional = true } -regex = { version = "1.3.1", optional = true } -num-traits = { version = "0.2.8", default-features = false } -zeroize = { version = "1.0.0", default-features = false } -secrecy = { version = "0.6.0", default-features = false } -lazy_static = { version = "1.4.0", default-features = false, optional = true } -parking_lot = { version = "0.10.0", optional = true } -sp-debug-derive = { version = "2.0.0", git = "https://github.com/paritytech/substrate", rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } -sp-externalities = { version = "0.8.0", optional = true, git = "https://github.com/paritytech/substrate", rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } -sp-storage = { version = "2.0.0", default-features = false, git = "https://github.com/paritytech/substrate", rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } -# PATCHED.insipx.2021Aug20 from `version = "0.7.0"` -parity-util-mem = { version = "0.10.0", default-features = false, features = ["primitive-types"] } -futures = { version = "0.3.1", optional = true } -dyn-clonable = { version = "0.9.0", optional = true } - -# full crypto -ed25519-dalek = { version = "1.0.0-pre.4", default-features = false, features = ["u64_backend", "alloc"], optional = true } -blake2-rfc = { version = "0.2.18", default-features = false, optional = true } -tiny-keccak = { version = "2.0.1", features = ["keccak"], optional = true } -schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated", "u64_backend"], default-features = false, optional = true } -sha2 = { version = "0.8.0", default-features = false, optional = true } -hex = { version = "0.4", default-features = false, optional = true } -twox-hash = { version = "1.5.0", default-features = false, optional = true } -libsecp256k1 = { version = "0.3.2", default-features = false, features = ["hmac"], optional = true } -merlin = { version = "2.0", default-features = false, optional = true } - -sp-runtime-interface = { version = "2.0.0", default-features = false, git = "https://github.com/paritytech/substrate", rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } - -[dev-dependencies] -sp-serializer = { version = "2.0.0", git = "https://github.com/paritytech/substrate", rev = "7314a78d49d0dc3862c6ef7c8115cb1b3d0c0fd2" } -pretty_assertions = "0.6.1" -hex-literal = "0.3.1" -rand = "0.7.2" -criterion = "0.3.3" -serde_json = "1.0" -rand_chacha = "0.2.2" - -[features] -default = ["std"] -std = [ - "full_crypto", - "log/std", - "wasmi", - "lazy_static", - "parking_lot", - "primitive-types/std", - "primitive-types/serde", - "primitive-types/byteorder", - "primitive-types/rustc-hex", - "impl-serde", - "codec/std", - "hash256-std-hasher/std", - "hash-db/std", - "sp-std/std", - "serde", - "twox-hash/std", - "blake2-rfc/std", - "ed25519-dalek/std", - "hex/std", - "base58", - "substrate-bip39", - "tiny-bip39", - "serde", - "byteorder/std", - "rand", - "sha2/std", - "schnorrkel/std", - "regex", - "num-traits/std", - "tiny-keccak", - "sp-debug-derive/std", - "sp-externalities", - "sp-storage/std", - "sp-runtime-interface/std", - "zeroize/alloc", - "secrecy/alloc", - "futures", - "futures/thread-pool", - "libsecp256k1/std", - "dyn-clonable", -] - -# This feature enables all crypto primitives for `no_std` builds like microcontrollers -# or Intel SGX. -# For the regular wasm runtime builds this should not be used. -full_crypto = [ - "ed25519-dalek", - "blake2-rfc", - "tiny-keccak", - "schnorrkel", - "hex", - "sha2", - "twox-hash", - "libsecp256k1", - "sp-runtime-interface/disable_target_static_assertions", - "merlin", -] diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/changes_trie.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/changes_trie.rs deleted file mode 100644 index 1d88242e..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/changes_trie.rs +++ /dev/null @@ -1,306 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Substrate changes trie configuration. - -#[cfg(any(feature = "std", test))] -use serde::{Serialize, Deserialize}; -use codec::{Encode, Decode}; -use num_traits::Zero; - -/// Substrate changes trie configuration. -#[cfg_attr(any(feature = "std", test), derive(Serialize, Deserialize, parity_util_mem::MallocSizeOf))] -#[derive(Debug, Clone, PartialEq, Eq, Default, Encode, Decode)] -pub struct ChangesTrieConfiguration { - /// Interval (in blocks) at which level1-digests are created. Digests are not - /// created when this is less or equal to 1. - pub digest_interval: u32, - /// Maximal number of digest levels in hierarchy. 0 means that digests are not - /// created at all (even level1 digests). 1 means only level1-digests are created. - /// 2 means that every digest_interval^2 there will be a level2-digest, and so on. - /// Please ensure that maximum digest interval (i.e. digest_interval^digest_levels) - /// is within `u32` limits. Otherwise you'll never see digests covering such intervals - /// && maximal digests interval will be truncated to the last interval that fits - /// `u32` limits. - pub digest_levels: u32, -} - -/// Substrate changes trie configuration range. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ChangesTrieConfigurationRange { - /// Zero block of configuration. - pub zero: (Number, Hash), - /// Last block of configuration (if configuration has been deactivated at some point). - pub end: Option<(Number, Hash)>, - /// The configuration itself. None if changes tries were disabled in this range. - pub config: Option, -} - -impl ChangesTrieConfiguration { - /// Create new configuration given digest interval and levels. - pub fn new(digest_interval: u32, digest_levels: u32) -> Self { - Self { digest_interval, digest_levels } - } - - /// Is digest build enabled? - pub fn is_digest_build_enabled(&self) -> bool { - self.digest_interval > 1 && self.digest_levels > 0 - } - - /// Do we need to build digest at given block? - pub fn is_digest_build_required_at_block( - &self, - zero: Number, - block: Number, - ) -> bool - where - Number: From + PartialEq + - ::sp_std::ops::Rem + ::sp_std::ops::Sub + - ::sp_std::cmp::PartialOrd + Zero, - { - block > zero - && self.is_digest_build_enabled() - && ((block - zero) % self.digest_interval.into()).is_zero() - } - - /// Returns max digest interval. One if digests are not created at all. - pub fn max_digest_interval(&self) -> u32 { - if !self.is_digest_build_enabled() { - return 1; - } - - // we'll get >1 loop iteration only when bad configuration parameters are selected - let mut current_level = self.digest_levels; - loop { - if let Some(max_digest_interval) = self.digest_interval.checked_pow(current_level) { - return max_digest_interval; - } - - current_level = current_level - 1; - } - } - - /// Returns max level digest block number that has been created at block <= passed block number. - /// - /// Returns None if digests are not created at all. - pub fn prev_max_level_digest_block( - &self, - zero: Number, - block: Number, - ) -> Option - where - Number: Clone + From + PartialOrd + PartialEq + - ::sp_std::ops::Add + ::sp_std::ops::Sub + - ::sp_std::ops::Div + ::sp_std::ops::Mul + Zero, - { - if block <= zero { - return None; - } - - let (next_begin, next_end) = self.next_max_level_digest_range(zero.clone(), block.clone())?; - - // if 'next' digest includes our block, then it is a also a previous digest - if next_end == block { - return Some(block); - } - - // if previous digest ends at zero block, then there are no previous digest - let prev_end = next_begin - 1.into(); - if prev_end == zero { - None - } else { - Some(prev_end) - } - } - - /// Returns max level digest blocks range (inclusive) which includes passed block. - /// - /// Returns None if digests are not created at all. - /// It will return the first max-level digest if block is <= zero. - pub fn next_max_level_digest_range( - &self, - zero: Number, - mut block: Number, - ) -> Option<(Number, Number)> - where - Number: Clone + From + PartialOrd + PartialEq + - ::sp_std::ops::Add + ::sp_std::ops::Sub + - ::sp_std::ops::Div + ::sp_std::ops::Mul, - { - if !self.is_digest_build_enabled() { - return None; - } - - if block <= zero { - block = zero.clone() + 1.into(); - } - - let max_digest_interval: Number = self.max_digest_interval().into(); - let max_digests_since_zero = (block.clone() - zero.clone()) / max_digest_interval.clone(); - if max_digests_since_zero == 0.into() { - return Some((zero.clone() + 1.into(), zero + max_digest_interval)); - } - let last_max_digest_block = zero + max_digests_since_zero * max_digest_interval.clone(); - Some(if block == last_max_digest_block { - (block.clone() - max_digest_interval + 1.into(), block) - } else { - (last_max_digest_block.clone() + 1.into(), last_max_digest_block + max_digest_interval) - }) - } - - /// Returns Some if digest must be built at given block number. - /// The tuple is: - /// ( - /// digest level - /// digest interval (in blocks) - /// step between blocks we're interested in when digest is built - /// ) - pub fn digest_level_at_block(&self, zero: Number, block: Number) -> Option<(u32, u32, u32)> - where - Number: Clone + From + PartialEq + - ::sp_std::ops::Rem + ::sp_std::ops::Sub + - ::sp_std::cmp::PartialOrd + Zero, - { - if !self.is_digest_build_required_at_block(zero.clone(), block.clone()) { - return None; - } - - let relative_block = block - zero; - let mut digest_interval = self.digest_interval; - let mut current_level = 1u32; - let mut digest_step = 1u32; - while current_level < self.digest_levels { - let new_digest_interval = match digest_interval.checked_mul(self.digest_interval) { - Some(new_digest_interval) if (relative_block.clone() % new_digest_interval.into()).is_zero() - => new_digest_interval, - _ => break, - }; - - digest_step = digest_interval; - digest_interval = new_digest_interval; - current_level = current_level + 1; - } - - Some(( - current_level, - digest_interval, - digest_step, - )) - } -} - -#[cfg(test)] -mod tests { - use super::ChangesTrieConfiguration; - - fn config(interval: u32, levels: u32) -> ChangesTrieConfiguration { - ChangesTrieConfiguration { - digest_interval: interval, - digest_levels: levels, - } - } - - #[test] - fn is_digest_build_enabled_works() { - assert!(!config(0, 100).is_digest_build_enabled()); - assert!(!config(1, 100).is_digest_build_enabled()); - assert!(config(2, 100).is_digest_build_enabled()); - assert!(!config(100, 0).is_digest_build_enabled()); - assert!(config(100, 1).is_digest_build_enabled()); - } - - #[test] - fn is_digest_build_required_at_block_works() { - fn test_with_zero(zero: u64) { - assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 0u64)); - assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 1u64)); - assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 2u64)); - assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 4u64)); - assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 8u64)); - assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 9u64)); - assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 64u64)); - assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 64u64)); - assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 512u64)); - assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 4096u64)); - assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 4103u64)); - assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 4104u64)); - assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 4108u64)); - } - - test_with_zero(0); - test_with_zero(8); - test_with_zero(17); - } - - #[test] - fn digest_level_at_block_works() { - fn test_with_zero(zero: u64) { - assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 0u64), None); - assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 7u64), None); - assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 63u64), None); - assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 8u64), Some((1, 8, 1))); - assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 64u64), Some((2, 64, 8))); - assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 512u64), Some((3, 512, 64))); - assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 4096u64), Some((4, 4096, 512))); - assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 4112u64), Some((1, 8, 1))); - } - - test_with_zero(0); - test_with_zero(8); - test_with_zero(17); - } - - #[test] - fn max_digest_interval_works() { - assert_eq!(config(0, 0).max_digest_interval(), 1); - assert_eq!(config(2, 2).max_digest_interval(), 4); - assert_eq!(config(8, 4).max_digest_interval(), 4096); - assert_eq!(config(::std::u32::MAX, 1024).max_digest_interval(), ::std::u32::MAX); - } - - #[test] - fn next_max_level_digest_range_works() { - assert_eq!(config(0, 0).next_max_level_digest_range(0u64, 16), None); - assert_eq!(config(1, 1).next_max_level_digest_range(0u64, 16), None); - assert_eq!(config(2, 1).next_max_level_digest_range(0u64, 16), Some((15, 16))); - assert_eq!(config(4, 1).next_max_level_digest_range(0u64, 16), Some((13, 16))); - assert_eq!(config(32, 1).next_max_level_digest_range(0u64, 16), Some((1, 32))); - assert_eq!(config(2, 3).next_max_level_digest_range(0u64, 10), Some((9, 16))); - assert_eq!(config(2, 3).next_max_level_digest_range(0u64, 8), Some((1, 8))); - assert_eq!(config(2, 1).next_max_level_digest_range(1u64, 1), Some((2, 3))); - assert_eq!(config(2, 2).next_max_level_digest_range(7u64, 9), Some((8, 11))); - - assert_eq!(config(2, 2).next_max_level_digest_range(7u64, 5), Some((8, 11))); - } - - #[test] - fn prev_max_level_digest_block_works() { - assert_eq!(config(0, 0).prev_max_level_digest_block(0u64, 16), None); - assert_eq!(config(1, 1).prev_max_level_digest_block(0u64, 16), None); - assert_eq!(config(2, 1).prev_max_level_digest_block(0u64, 16), Some(16)); - assert_eq!(config(4, 1).prev_max_level_digest_block(0u64, 16), Some(16)); - assert_eq!(config(4, 2).prev_max_level_digest_block(0u64, 16), Some(16)); - assert_eq!(config(4, 2).prev_max_level_digest_block(0u64, 17), Some(16)); - assert_eq!(config(4, 2).prev_max_level_digest_block(0u64, 33), Some(32)); - assert_eq!(config(32, 1).prev_max_level_digest_block(0u64, 16), None); - assert_eq!(config(2, 3).prev_max_level_digest_block(0u64, 10), Some(8)); - assert_eq!(config(2, 3).prev_max_level_digest_block(0u64, 8), Some(8)); - assert_eq!(config(2, 2).prev_max_level_digest_block(7u64, 8), None); - - assert_eq!(config(2, 2).prev_max_level_digest_block(7u64, 5), None); - } -} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/crypto.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/crypto.rs deleted file mode 100644 index c0a85cb2..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/crypto.rs +++ /dev/null @@ -1,1263 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// tag::description[] -//! Cryptographic utilities. -// end::description[] - -use crate::{sr25519, ed25519}; -use sp_std::hash::Hash; -use sp_std::vec::Vec; -use sp_std::str; -#[cfg(feature = "std")] -use sp_std::convert::TryInto; -use sp_std::convert::TryFrom; -#[cfg(feature = "std")] -use parking_lot::Mutex; -#[cfg(feature = "std")] -use rand::{RngCore, rngs::OsRng}; -use codec::{Encode, Decode}; -#[cfg(feature = "std")] -use regex::Regex; -#[cfg(feature = "std")] -use base58::{FromBase58, ToBase58}; -#[cfg(feature = "std")] -use crate::hexdisplay::HexDisplay; -#[doc(hidden)] -pub use sp_std::ops::Deref; -use sp_runtime_interface::pass_by::PassByInner; -/// Trait to zeroize a memory buffer. -pub use zeroize::Zeroize; -/// Trait for accessing reference to `SecretString`. -pub use secrecy::ExposeSecret; -/// A store for sensitive data. -#[cfg(feature = "std")] -pub use secrecy::SecretString; - -/// The root phrase for our publicly known keys. -pub const DEV_PHRASE: &str = "bottom drive obey lake curtain smoke basket hold race lonely fit walk"; - -/// The address of the associated root phrase for our publicly known keys. -pub const DEV_ADDRESS: &str = "5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqRzV"; - -/// The infallible type. -#[derive(crate::RuntimeDebug)] -pub enum Infallible {} - -/// The length of the junction identifier. Note that this is also referred to as the -/// `CHAIN_CODE_LENGTH` in the context of Schnorrkel. -#[cfg(feature = "full_crypto")] -pub const JUNCTION_ID_LEN: usize = 32; - -/// Similar to `From`, except that the onus is on the part of the caller to ensure -/// that data passed in makes sense. Basically, you're not guaranteed to get anything -/// sensible out. -pub trait UncheckedFrom { - /// Convert from an instance of `T` to Self. This is not guaranteed to be - /// whatever counts as a valid instance of `T` and it's up to the caller to - /// ensure that it makes sense. - fn unchecked_from(t: T) -> Self; -} - -/// The counterpart to `UncheckedFrom`. -pub trait UncheckedInto { - /// The counterpart to `unchecked_from`. - fn unchecked_into(self) -> T; -} - -impl> UncheckedInto for S { - fn unchecked_into(self) -> T { - T::unchecked_from(self) - } -} - -/// An error with the interpretation of a secret. -#[derive(Debug, Clone, PartialEq, Eq)] -#[cfg(feature = "full_crypto")] -pub enum SecretStringError { - /// The overall format was invalid (e.g. the seed phrase contained symbols). - InvalidFormat, - /// The seed phrase provided is not a valid BIP39 phrase. - InvalidPhrase, - /// The supplied password was invalid. - InvalidPassword, - /// The seed is invalid (bad content). - InvalidSeed, - /// The seed has an invalid length. - InvalidSeedLength, - /// The derivation path was invalid (e.g. contains soft junctions when they are not supported). - InvalidPath, -} - -/// A since derivation junction description. It is the single parameter used when creating -/// a new secret key from an existing secret key and, in the case of `SoftRaw` and `SoftIndex` -/// a new public key from an existing public key. -#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Encode, Decode)] -#[cfg(feature = "full_crypto")] -pub enum DeriveJunction { - /// Soft (vanilla) derivation. Public keys have a correspondent derivation. - Soft([u8; JUNCTION_ID_LEN]), - /// Hard ("hardened") derivation. Public keys do not have a correspondent derivation. - Hard([u8; JUNCTION_ID_LEN]), -} - -#[cfg(feature = "full_crypto")] -impl DeriveJunction { - /// Consume self to return a soft derive junction with the same chain code. - pub fn soften(self) -> Self { DeriveJunction::Soft(self.unwrap_inner()) } - - /// Consume self to return a hard derive junction with the same chain code. - pub fn harden(self) -> Self { DeriveJunction::Hard(self.unwrap_inner()) } - - /// Create a new soft (vanilla) DeriveJunction from a given, encodable, value. - /// - /// If you need a hard junction, use `hard()`. - pub fn soft(index: T) -> Self { - let mut cc: [u8; JUNCTION_ID_LEN] = Default::default(); - index.using_encoded(|data| if data.len() > JUNCTION_ID_LEN { - let hash_result = blake2_rfc::blake2b::blake2b(JUNCTION_ID_LEN, &[], data); - let hash = hash_result.as_bytes(); - cc.copy_from_slice(hash); - } else { - cc[0..data.len()].copy_from_slice(data); - }); - DeriveJunction::Soft(cc) - } - - /// Create a new hard (hardened) DeriveJunction from a given, encodable, value. - /// - /// If you need a soft junction, use `soft()`. - pub fn hard(index: T) -> Self { - Self::soft(index).harden() - } - - /// Consume self to return the chain code. - pub fn unwrap_inner(self) -> [u8; JUNCTION_ID_LEN] { - match self { - DeriveJunction::Hard(c) | DeriveJunction::Soft(c) => c, - } - } - - /// Get a reference to the inner junction id. - pub fn inner(&self) -> &[u8; JUNCTION_ID_LEN] { - match self { - DeriveJunction::Hard(ref c) | DeriveJunction::Soft(ref c) => c, - } - } - - /// Return `true` if the junction is soft. - pub fn is_soft(&self) -> bool { - match *self { - DeriveJunction::Soft(_) => true, - _ => false, - } - } - - /// Return `true` if the junction is hard. - pub fn is_hard(&self) -> bool { - match *self { - DeriveJunction::Hard(_) => true, - _ => false, - } - } -} - -#[cfg(feature = "full_crypto")] -impl> From for DeriveJunction { - fn from(j: T) -> DeriveJunction { - let j = j.as_ref(); - let (code, hard) = if j.starts_with('/') { - (&j[1..], true) - } else { - (j, false) - }; - - let res = if let Ok(n) = str::parse::(code) { - // number - DeriveJunction::soft(n) - } else { - // something else - DeriveJunction::soft(code) - }; - - if hard { - res.harden() - } else { - res - } - } -} - -/// An error type for SS58 decoding. -#[cfg(feature = "full_crypto")] -#[derive(Clone, Copy, Eq, PartialEq, Debug)] -pub enum PublicError { - /// Bad alphabet. - BadBase58, - /// Bad length. - BadLength, - /// Unknown version. - UnknownVersion, - /// Invalid checksum. - InvalidChecksum, - /// Invalid format. - InvalidFormat, - /// Invalid derivation path. - InvalidPath, -} - -/// Key that can be encoded to/from SS58. -#[cfg(feature = "full_crypto")] -pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default { - /// Some if the string is a properly encoded SS58Check address. - #[cfg(feature = "std")] - fn from_ss58check(s: &str) -> Result { - Self::from_ss58check_with_version(s) - .and_then(|(r, v)| match v { - v if !v.is_custom() => Ok(r), - v if v == *DEFAULT_VERSION.lock() => Ok(r), - _ => Err(PublicError::UnknownVersion), - }) - } - /// Some if the string is a properly encoded SS58Check address. - #[cfg(feature = "std")] - fn from_ss58check_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> { - let mut res = Self::default(); - let len = res.as_mut().len(); - let d = s.from_base58().map_err(|_| PublicError::BadBase58)?; // failure here would be invalid encoding. - if d.len() != len + 3 { - // Invalid length. - return Err(PublicError::BadLength); - } - let ver = d[0].try_into().map_err(|_: ()| PublicError::UnknownVersion)?; - - if d[len + 1..len + 3] != ss58hash(&d[0..len + 1]).as_bytes()[0..2] { - // Invalid checksum. - return Err(PublicError::InvalidChecksum); - } - res.as_mut().copy_from_slice(&d[1..len + 1]); - Ok((res, ver)) - } - /// Some if the string is a properly encoded SS58Check address, optionally with - /// a derivation path following. - #[cfg(feature = "std")] - fn from_string(s: &str) -> Result { - Self::from_string_with_version(s) - .and_then(|(r, v)| match v { - v if !v.is_custom() => Ok(r), - v if v == *DEFAULT_VERSION.lock() => Ok(r), - _ => Err(PublicError::UnknownVersion), - }) - } - - /// Return the ss58-check string for this key. - #[cfg(feature = "std")] - fn to_ss58check_with_version(&self, version: Ss58AddressFormat) -> String { - let mut v = vec![version.into()]; - v.extend(self.as_ref()); - let r = ss58hash(&v); - v.extend(&r.as_bytes()[0..2]); - v.to_base58() - } - - /// Return the ss58-check string for this key. - #[cfg(feature = "std")] - fn to_ss58check(&self) -> String { self.to_ss58check_with_version(*DEFAULT_VERSION.lock()) } - - /// Some if the string is a properly encoded SS58Check address, optionally with - /// a derivation path following. - #[cfg(feature = "std")] - fn from_string_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> { - Self::from_ss58check_with_version(s) - } -} - -/// Derivable key trait. -pub trait Derive: Sized { - /// Derive a child key from a series of given junctions. - /// - /// Will be `None` for public keys if there are any hard junctions in there. - #[cfg(feature = "std")] - fn derive>(&self, _path: Iter) -> Option { - None - } -} - -#[cfg(feature = "std")] -const PREFIX: &[u8] = b"SS58PRE"; - -#[cfg(feature = "std")] -fn ss58hash(data: &[u8]) -> blake2_rfc::blake2b::Blake2bResult { - let mut context = blake2_rfc::blake2b::Blake2b::new(64); - context.update(PREFIX); - context.update(data); - context.finalize() -} - -#[cfg(feature = "std")] -lazy_static::lazy_static! { - static ref DEFAULT_VERSION: Mutex - = Mutex::new(Ss58AddressFormat::SubstrateAccount); -} - -#[cfg(feature = "full_crypto")] -macro_rules! ss58_address_format { - ( $( $identifier:tt => ($number:expr, $name:expr, $desc:tt) )* ) => ( - /// A known address (sub)format/network ID for SS58. - #[derive(Copy, Clone, PartialEq, Eq, crate::RuntimeDebug)] - pub enum Ss58AddressFormat { - $(#[doc = $desc] $identifier),*, - /// Use a manually provided numeric value. - Custom(u8), - } - - #[cfg(feature = "std")] - impl std::fmt::Display for Ss58AddressFormat { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - match self { - $( - Ss58AddressFormat::$identifier => write!(f, "{}", $name), - )* - Ss58AddressFormat::Custom(x) => write!(f, "{}", x), - } - - } - } - - static ALL_SS58_ADDRESS_FORMATS: [Ss58AddressFormat; 0 $(+ { let _ = $number; 1})*] = [ - $(Ss58AddressFormat::$identifier),*, - ]; - - impl Ss58AddressFormat { - /// names of all address formats - pub fn all_names() -> &'static [&'static str] { - &[ - $($name),*, - ] - } - /// All known address formats. - pub fn all() -> &'static [Ss58AddressFormat] { - &ALL_SS58_ADDRESS_FORMATS - } - - /// Whether the address is custom. - pub fn is_custom(&self) -> bool { - match self { - Self::Custom(_) => true, - _ => false, - } - } - } - - impl From for u8 { - fn from(x: Ss58AddressFormat) -> u8 { - match x { - $(Ss58AddressFormat::$identifier => $number),*, - Ss58AddressFormat::Custom(n) => n, - } - } - } - - impl TryFrom for Ss58AddressFormat { - type Error = (); - - fn try_from(x: u8) -> Result { - match x { - $($number => Ok(Ss58AddressFormat::$identifier)),*, - _ => { - #[cfg(feature = "std")] - match Ss58AddressFormat::default() { - Ss58AddressFormat::Custom(n) if n == x => Ok(Ss58AddressFormat::Custom(x)), - _ => Err(()), - } - - #[cfg(not(feature = "std"))] - Err(()) - }, - } - } - } - - /// Error encountered while parsing `Ss58AddressFormat` from &'_ str - /// unit struct for now. - #[derive(Copy, Clone, PartialEq, Eq, crate::RuntimeDebug)] - pub struct ParseError; - - impl<'a> TryFrom<&'a str> for Ss58AddressFormat { - type Error = ParseError; - - fn try_from(x: &'a str) -> Result { - match x { - $($name => Ok(Ss58AddressFormat::$identifier)),*, - a => a.parse::().map(Ss58AddressFormat::Custom).map_err(|_| ParseError), - } - } - } - - #[cfg(feature = "std")] - impl std::str::FromStr for Ss58AddressFormat { - type Err = ParseError; - - fn from_str(data: &str) -> Result { - Self::try_from(data) - } - } - - #[cfg(feature = "std")] - impl std::fmt::Display for ParseError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "failed to parse network value as u8") - } - } - - #[cfg(feature = "std")] - impl Default for Ss58AddressFormat { - fn default() -> Self { - *DEFAULT_VERSION.lock() - } - } - - #[cfg(feature = "std")] - impl From for String { - fn from(x: Ss58AddressFormat) -> String { - x.to_string() - } - } - ) -} - -#[cfg(feature = "full_crypto")] -ss58_address_format!( - PolkadotAccount => - (0, "polkadot", "Polkadot Relay-chain, standard account (*25519).") - Reserved1 => - (1, "reserved1", "Reserved for future use (1).") - KusamaAccount => - (2, "kusama", "Kusama Relay-chain, standard account (*25519).") - Reserved3 => - (3, "reserved3", "Reserved for future use (3).") - KatalChainAccount => - (4, "katalchain", "Katal Chain, standard account (*25519).") - PlasmAccount => - (5, "plasm", "Plasm Network, standard account (*25519).") - BifrostAccount => - (6, "bifrost", "Bifrost mainnet, direct checksum, standard account (*25519).") - EdgewareAccount => - (7, "edgeware", "Edgeware mainnet, standard account (*25519).") - KaruraAccount => - (8, "karura", "Acala Karura canary network, standard account (*25519).") - ReynoldsAccount => - (9, "reynolds", "Laminar Reynolds canary network, standard account (*25519).") - AcalaAccount => - (10, "acala", "Acala mainnet, standard account (*25519).") - LaminarAccount => - (11, "laminar", "Laminar mainnet, standard account (*25519).") - PolymathAccount => - (12, "polymath", "Polymath network, standard account (*25519).") - SubstraTeeAccount => - (13, "substratee", "Any SubstraTEE off-chain network private account (*25519).") - KulupuAccount => - (16, "kulupu", "Kulupu mainnet, standard account (*25519).") - DarkAccount => - (17, "dark", "Dark mainnet, standard account (*25519).") - DarwiniaAccount => - (18, "darwinia", "Darwinia Chain mainnet, standard account (*25519).") - GeekAccount => - (19, "geek", "GeekCash mainnet, standard account (*25519).") - StafiAccount => - (20, "stafi", "Stafi mainnet, standard account (*25519).") - DockTestAccount => - (21, "dock-testnet", "Dock testnet, standard account (*25519).") - DockMainAccount => - (22, "dock-mainnet", "Dock mainnet, standard account (*25519).") - ShiftNrg => - (23, "shift", "ShiftNrg mainnet, standard account (*25519).") - SubsocialAccount => - (28, "subsocial", "Subsocial network, standard account (*25519).") - PhalaAccount => - (30, "phala", "Phala Network, standard account (*25519).") - RobonomicsAccount => - (32, "robonomics", "Any Robonomics network standard account (*25519).") - DataHighwayAccount => - (33, "datahighway", "DataHighway mainnet, standard account (*25519).") - CentrifugeAccount => - (36, "centrifuge", "Centrifuge Chain mainnet, standard account (*25519).") - SubstrateAccount => - (42, "substrate", "Any Substrate network, standard account (*25519).") - Reserved43 => - (43, "reserved43", "Reserved for future use (43).") - ChainXAccount => - (44, "chainx", "ChainX mainnet, standard account (*25519).") - Reserved46 => - (46, "reserved46", "Reserved for future use (46).") - Reserved47 => - (47, "reserved47", "Reserved for future use (47).") - // Note: 48 and above are reserved. -); - -/// Set the default "version" (actually, this is a bit of a misnomer and the version byte is -/// typically used not just to encode format/version but also network identity) that is used for -/// encoding and decoding SS58 addresses. If an unknown version is provided then it fails. -/// -/// See `ss58_address_format!` for all current known "versions". -#[cfg(feature = "std")] -pub fn set_default_ss58_version(version: Ss58AddressFormat) { - *DEFAULT_VERSION.lock() = version -} - -#[cfg(feature = "std")] -impl + AsRef<[u8]> + Default + Derive> Ss58Codec for T { - fn from_string(s: &str) -> Result { - let re = Regex::new(r"^(?P[\w\d ]+)?(?P(//?[^/]+)*)$") - .expect("constructed from known-good static value; qed"); - let cap = re.captures(s).ok_or(PublicError::InvalidFormat)?; - let re_junction = Regex::new(r"/(/?[^/]+)") - .expect("constructed from known-good static value; qed"); - let s = cap.name("ss58") - .map(|r| r.as_str()) - .unwrap_or(DEV_ADDRESS); - let addr = if s.starts_with("0x") { - let d = hex::decode(&s[2..]).map_err(|_| PublicError::InvalidFormat)?; - let mut r = Self::default(); - if d.len() == r.as_ref().len() { - r.as_mut().copy_from_slice(&d); - r - } else { - Err(PublicError::BadLength)? - } - } else { - Self::from_ss58check(s)? - }; - if cap["path"].is_empty() { - Ok(addr) - } else { - let path = re_junction.captures_iter(&cap["path"]) - .map(|f| DeriveJunction::from(&f[1])); - addr.derive(path) - .ok_or(PublicError::InvalidPath) - } - } - - fn from_string_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> { - let re = Regex::new(r"^(?P[\w\d ]+)?(?P(//?[^/]+)*)$") - .expect("constructed from known-good static value; qed"); - let cap = re.captures(s).ok_or(PublicError::InvalidFormat)?; - let re_junction = Regex::new(r"/(/?[^/]+)") - .expect("constructed from known-good static value; qed"); - let (addr, v) = Self::from_ss58check_with_version( - cap.name("ss58") - .map(|r| r.as_str()) - .unwrap_or(DEV_ADDRESS) - )?; - if cap["path"].is_empty() { - Ok((addr, v)) - } else { - let path = re_junction.captures_iter(&cap["path"]) - .map(|f| DeriveJunction::from(&f[1])); - addr.derive(path) - .ok_or(PublicError::InvalidPath) - .map(|a| (a, v)) - } - } -} - -/// Trait suitable for typical cryptographic PKI key public type. -pub trait Public: - AsRef<[u8]> + AsMut<[u8]> + Default + Derive + CryptoType + PartialEq + Eq + Clone + Send + Sync -{ - /// A new instance from the given slice. - /// - /// NOTE: No checking goes on to ensure this is a real public key. Only use it if - /// you are certain that the array actually is a pubkey. GIGO! - fn from_slice(data: &[u8]) -> Self; - - /// Return a `Vec` filled with raw data. - fn to_raw_vec(&self) -> Vec { self.as_slice().to_vec() } - - /// Return a slice filled with raw data. - fn as_slice(&self) -> &[u8] { self.as_ref() } - /// Return `CryptoTypePublicPair` from public key. - fn to_public_crypto_pair(&self) -> CryptoTypePublicPair; -} - -/// An opaque 32-byte cryptographic identifier. -#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Default, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Hash))] -pub struct AccountId32([u8; 32]); - -impl UncheckedFrom for AccountId32 { - fn unchecked_from(h: crate::hash::H256) -> Self { - AccountId32(h.into()) - } -} - -#[cfg(feature = "std")] -impl Ss58Codec for AccountId32 {} - -impl AsRef<[u8]> for AccountId32 { - fn as_ref(&self) -> &[u8] { - &self.0[..] - } -} - -impl AsMut<[u8]> for AccountId32 { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0[..] - } -} - -impl AsRef<[u8; 32]> for AccountId32 { - fn as_ref(&self) -> &[u8; 32] { - &self.0 - } -} - -impl AsMut<[u8; 32]> for AccountId32 { - fn as_mut(&mut self) -> &mut [u8; 32] { - &mut self.0 - } -} - -impl From<[u8; 32]> for AccountId32 { - fn from(x: [u8; 32]) -> AccountId32 { - AccountId32(x) - } -} - -impl<'a> sp_std::convert::TryFrom<&'a [u8]> for AccountId32 { - type Error = (); - fn try_from(x: &'a [u8]) -> Result { - if x.len() == 32 { - let mut r = AccountId32::default(); - r.0.copy_from_slice(x); - Ok(r) - } else { - Err(()) - } - } -} - -impl From for [u8; 32] { - fn from(x: AccountId32) -> [u8; 32] { - x.0 - } -} - -impl From for AccountId32 { - fn from(k: sr25519::Public) -> Self { - k.0.into() - } -} - -impl From for AccountId32 { - fn from(k: ed25519::Public) -> Self { - k.0.into() - } -} - -#[cfg(feature = "std")] -impl std::fmt::Display for AccountId32 { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{}", self.to_ss58check()) - } -} - -impl sp_std::fmt::Debug for AccountId32 { - #[cfg(feature = "std")] - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - let s = self.to_ss58check(); - write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) - } - - #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - Ok(()) - } -} - -#[cfg(feature = "std")] -impl serde::Serialize for AccountId32 { - fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - serializer.serialize_str(&self.to_ss58check()) - } -} - -#[cfg(feature = "std")] -impl<'de> serde::Deserialize<'de> for AccountId32 { - fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { - Ss58Codec::from_ss58check(&String::deserialize(deserializer)?) - .map_err(|e| serde::de::Error::custom(format!("{:?}", e))) - } -} - -#[cfg(feature = "std")] -impl sp_std::str::FromStr for AccountId32 { - type Err = &'static str; - - fn from_str(s: &str) -> Result { - let hex_or_ss58_without_prefix = s.trim_start_matches("0x"); - if hex_or_ss58_without_prefix.len() == 64 { - let mut bytes = [0u8; 32]; - hex::decode_to_slice(hex_or_ss58_without_prefix, &mut bytes) - .map_err(|_| "invalid hex address.") - .map(|_| Self::from(bytes)) - } else { - Self::from_ss58check(s).map_err(|_| "invalid ss58 address.") - } - } -} - -#[cfg(feature = "std")] -pub use self::dummy::*; - -#[cfg(feature = "std")] -mod dummy { - use super::*; - - /// Dummy cryptography. Doesn't do anything. - #[derive(Clone, Hash, Default, Eq, PartialEq)] - pub struct Dummy; - - impl AsRef<[u8]> for Dummy { - fn as_ref(&self) -> &[u8] { &b""[..] } - } - - impl AsMut<[u8]> for Dummy { - fn as_mut(&mut self) -> &mut[u8] { - unsafe { - #[allow(mutable_transmutes)] - sp_std::mem::transmute::<_, &'static mut [u8]>(&b""[..]) - } - } - } - - impl CryptoType for Dummy { - type Pair = Dummy; - } - - impl Derive for Dummy {} - - impl Public for Dummy { - fn from_slice(_: &[u8]) -> Self { Self } - #[cfg(feature = "std")] - fn to_raw_vec(&self) -> Vec { vec![] } - fn as_slice(&self) -> &[u8] { b"" } - fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { - CryptoTypePublicPair( - CryptoTypeId(*b"dumm"), Public::to_raw_vec(self) - ) - } - } - - impl Pair for Dummy { - type Public = Dummy; - type Seed = Dummy; - type Signature = Dummy; - type DeriveError = (); - #[cfg(feature = "std")] - fn generate_with_phrase(_: Option<&str>) -> (Self, String, Self::Seed) { Default::default() } - #[cfg(feature = "std")] - fn from_phrase(_: &str, _: Option<&str>) - -> Result<(Self, Self::Seed), SecretStringError> - { - Ok(Default::default()) - } - fn derive< - Iter: Iterator, - >(&self, _: Iter, _: Option) -> Result<(Self, Option), Self::DeriveError> { Ok((Self, None)) } - fn from_seed(_: &Self::Seed) -> Self { Self } - fn from_seed_slice(_: &[u8]) -> Result { Ok(Self) } - fn sign(&self, _: &[u8]) -> Self::Signature { Self } - fn verify>(_: &Self::Signature, _: M, _: &Self::Public) -> bool { true } - fn verify_weak, M: AsRef<[u8]>>(_: &[u8], _: M, _: P) -> bool { true } - fn public(&self) -> Self::Public { Self } - fn to_raw_vec(&self) -> Vec { vec![] } - } -} - -/// Trait suitable for typical cryptographic PKI key pair type. -/// -/// For now it just specifies how to create a key from a phrase and derivation path. -#[cfg(feature = "full_crypto")] -pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static { - /// The type which is used to encode a public key. - type Public: Public + Hash; - - /// The type used to (minimally) encode the data required to securely create - /// a new key pair. - type Seed: Default + AsRef<[u8]> + AsMut<[u8]> + Clone; - - /// The type used to represent a signature. Can be created from a key pair and a message - /// and verified with the message and a public key. - type Signature: AsRef<[u8]>; - - /// Error returned from the `derive` function. - type DeriveError; - - /// Generate new secure (random) key pair. - /// - /// This is only for ephemeral keys really, since you won't have access to the secret key - /// for storage. If you want a persistent key pair, use `generate_with_phrase` instead. - #[cfg(feature = "std")] - fn generate() -> (Self, Self::Seed) { - let mut seed = Self::Seed::default(); - OsRng.fill_bytes(seed.as_mut()); - (Self::from_seed(&seed), seed) - } - - /// Generate new secure (random) key pair and provide the recovery phrase. - /// - /// You can recover the same key later with `from_phrase`. - /// - /// This is generally slower than `generate()`, so prefer that unless you need to persist - /// the key from the current session. - #[cfg(feature = "std")] - fn generate_with_phrase(password: Option<&str>) -> (Self, String, Self::Seed); - - /// Returns the KeyPair from the English BIP39 seed `phrase`, or `None` if it's invalid. - #[cfg(feature = "std")] - fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Self, Self::Seed), SecretStringError>; - - /// Derive a child key from a series of given junctions. - fn derive>(&self, - path: Iter, - seed: Option, - ) -> Result<(Self, Option), Self::DeriveError>; - - /// Generate new key pair from the provided `seed`. - /// - /// @WARNING: THIS WILL ONLY BE SECURE IF THE `seed` IS SECURE. If it can be guessed - /// by an attacker then they can also derive your key. - fn from_seed(seed: &Self::Seed) -> Self; - - /// Make a new key pair from secret seed material. The slice must be the correct size or - /// it will return `None`. - /// - /// @WARNING: THIS WILL ONLY BE SECURE IF THE `seed` IS SECURE. If it can be guessed - /// by an attacker then they can also derive your key. - fn from_seed_slice(seed: &[u8]) -> Result; - - /// Sign a message. - fn sign(&self, message: &[u8]) -> Self::Signature; - - /// Verify a signature on a message. Returns true if the signature is good. - fn verify>(sig: &Self::Signature, message: M, pubkey: &Self::Public) -> bool; - - /// Verify a signature on a message. Returns true if the signature is good. - fn verify_weak, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool; - - /// Get the public key. - fn public(&self) -> Self::Public; - - /// Interprets the string `s` in order to generate a key Pair. Returns both the pair and an optional seed, in the - /// case that the pair can be expressed as a direct derivation from a seed (some cases, such as Sr25519 derivations - /// with path components, cannot). - /// - /// This takes a helper function to do the key generation from a phrase, password and - /// junction iterator. - /// - /// - If `s` is a possibly `0x` prefixed 64-digit hex string, then it will be interpreted - /// directly as a `MiniSecretKey` (aka "seed" in `subkey`). - /// - If `s` is a valid BIP-39 key phrase of 12, 15, 18, 21 or 24 words, then the key will - /// be derived from it. In this case: - /// - the phrase may be followed by one or more items delimited by `/` characters. - /// - the path may be followed by `///`, in which case everything after the `///` is treated - /// as a password. - /// - If `s` begins with a `/` character it is prefixed with the Substrate public `DEV_PHRASE` and - /// interpreted as above. - /// - /// In this case they are interpreted as HDKD junctions; purely numeric items are interpreted as - /// integers, non-numeric items as strings. Junctions prefixed with `/` are interpreted as soft - /// junctions, and with `//` as hard junctions. - /// - /// There is no correspondence mapping between SURI strings and the keys they represent. - /// Two different non-identical strings can actually lead to the same secret being derived. - /// Notably, integer junction indices may be legally prefixed with arbitrary number of zeros. - /// Similarly an empty password (ending the SURI with `///`) is perfectly valid and will generally - /// be equivalent to no password at all. - /// - /// `None` is returned if no matches are found. - #[cfg(feature = "std")] - fn from_string_with_seed(s: &str, password_override: Option<&str>) - -> Result<(Self, Option), SecretStringError> - { - let re = Regex::new(r"^(?P[\d\w ]+)?(?P(//?[^/]+)*)(///(?P.*))?$") - .expect("constructed from known-good static value; qed"); - let cap = re.captures(s).ok_or(SecretStringError::InvalidFormat)?; - - let re_junction = Regex::new(r"/(/?[^/]+)") - .expect("constructed from known-good static value; qed"); - let path = re_junction.captures_iter(&cap["path"]) - .map(|f| DeriveJunction::from(&f[1])); - - let phrase = cap.name("phrase").map(|r| r.as_str()).unwrap_or(DEV_PHRASE); - let password = password_override.or_else(|| cap.name("password").map(|m| m.as_str())); - - let (root, seed) = if phrase.starts_with("0x") { - hex::decode(&phrase[2..]).ok() - .and_then(|seed_vec| { - let mut seed = Self::Seed::default(); - if seed.as_ref().len() == seed_vec.len() { - seed.as_mut().copy_from_slice(&seed_vec); - Some((Self::from_seed(&seed), seed)) - } else { - None - } - }) - .ok_or(SecretStringError::InvalidSeed)? - } else { - Self::from_phrase(phrase, password) - .map_err(|_| SecretStringError::InvalidPhrase)? - }; - root.derive(path, Some(seed)).map_err(|_| SecretStringError::InvalidPath) - } - - /// Interprets the string `s` in order to generate a key pair. - /// - /// See [`from_string_with_seed`](Pair::from_string_with_seed) for more extensive documentation. - #[cfg(feature = "std")] - fn from_string(s: &str, password_override: Option<&str>) -> Result { - Self::from_string_with_seed(s, password_override).map(|x| x.0) - } - - /// Return a vec filled with raw data. - fn to_raw_vec(&self) -> Vec; -} - -/// One type is wrapped by another. -pub trait IsWrappedBy: From + Into { - /// Get a reference to the inner from the outer. - fn from_ref(outer: &Outer) -> &Self; - /// Get a mutable reference to the inner from the outer. - fn from_mut(outer: &mut Outer) -> &mut Self; -} - -/// Opposite of `IsWrappedBy` - denotes a type which is a simple wrapper around another type. -pub trait Wraps: Sized { - /// The inner type it is wrapping. - type Inner: IsWrappedBy; -} - -impl IsWrappedBy for T where - Outer: AsRef + AsMut + From, - T: From, -{ - /// Get a reference to the inner from the outer. - fn from_ref(outer: &Outer) -> &Self { outer.as_ref() } - - /// Get a mutable reference to the inner from the outer. - fn from_mut(outer: &mut Outer) -> &mut Self { outer.as_mut() } -} - -impl UncheckedFrom for Outer where - Outer: Wraps, - Inner: IsWrappedBy + UncheckedFrom, -{ - fn unchecked_from(t: T) -> Self { - let inner: Inner = t.unchecked_into(); - inner.into() - } -} - -/// Type which has a particular kind of crypto associated with it. -pub trait CryptoType { - /// The pair key type of this crypto. - #[cfg(feature = "full_crypto")] - type Pair: Pair; -} - -/// An identifier for a type of cryptographic key. -/// -/// To avoid clashes with other modules when distributing your module publicly, register your -/// `KeyTypeId` on the list here by making a PR. -/// -/// Values whose first character is `_` are reserved for private use and won't conflict with any -/// public modules. -#[derive( - Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode, PassByInner, - crate::RuntimeDebug -)] -pub struct KeyTypeId(pub [u8; 4]); - -impl From for KeyTypeId { - fn from(x: u32) -> Self { - Self(x.to_le_bytes()) - } -} - -impl From for u32 { - fn from(x: KeyTypeId) -> Self { - u32::from_le_bytes(x.0) - } -} - -impl<'a> TryFrom<&'a str> for KeyTypeId { - type Error = (); - fn try_from(x: &'a str) -> Result { - let b = x.as_bytes(); - if b.len() != 4 { - return Err(()); - } - let mut res = KeyTypeId::default(); - res.0.copy_from_slice(&b[0..4]); - Ok(res) - } -} - -/// An identifier for a specific cryptographic algorithm used by a key pair -#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode)] -pub struct CryptoTypeId(pub [u8; 4]); - -/// A type alias of CryptoTypeId & a public key -#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode)] -pub struct CryptoTypePublicPair(pub CryptoTypeId, pub Vec); - -#[cfg(feature = "std")] -impl sp_std::fmt::Display for CryptoTypePublicPair { - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - let id = match str::from_utf8(&(self.0).0[..]) { - Ok(id) => id.to_string(), - Err(_) => { - format!("{:#?}", self.0) - } - }; - write!(f, "{}-{}", id, HexDisplay::from(&self.1)) - } -} - -/// Known key types; this also functions as a global registry of key types for projects wishing to -/// avoid collisions with each other. -/// -/// It's not universal in the sense that *all* key types need to be mentioned here, it's just a -/// handy place to put common key types. -pub mod key_types { - use super::KeyTypeId; - - /// Key type for Babe module, built-in. Identified as `babe`. - pub const BABE: KeyTypeId = KeyTypeId(*b"babe"); - /// Key type for Grandpa module, built-in. Identified as `gran`. - pub const GRANDPA: KeyTypeId = KeyTypeId(*b"gran"); - /// Key type for controlling an account in a Substrate runtime, built-in. Identified as `acco`. - pub const ACCOUNT: KeyTypeId = KeyTypeId(*b"acco"); - /// Key type for Aura module, built-in. Identified as `aura`. - pub const AURA: KeyTypeId = KeyTypeId(*b"aura"); - /// Key type for ImOnline module, built-in. Identified as `imon`. - pub const IM_ONLINE: KeyTypeId = KeyTypeId(*b"imon"); - /// Key type for AuthorityDiscovery module, built-in. Identified as `audi`. - pub const AUTHORITY_DISCOVERY: KeyTypeId = KeyTypeId(*b"audi"); - /// Key type for staking, built-in. Identified as `stak`. - pub const STAKING: KeyTypeId = KeyTypeId(*b"stak"); - /// Key type for equivocation reporting, built-in. Identified as `fish`. - pub const REPORTING: KeyTypeId = KeyTypeId(*b"fish"); - /// A key type ID useful for tests. - pub const DUMMY: KeyTypeId = KeyTypeId(*b"dumy"); -} - -#[cfg(test)] -mod tests { - use crate::DeriveJunction; - use hex_literal::hex; - use super::*; - - #[derive(Clone, Eq, PartialEq, Debug)] - enum TestPair { - Generated, - GeneratedWithPhrase, - GeneratedFromPhrase{phrase: String, password: Option}, - Standard{phrase: String, password: Option, path: Vec}, - Seed(Vec), - } - impl Default for TestPair { - fn default() -> Self { - TestPair::Generated - } - } - impl CryptoType for TestPair { - type Pair = Self; - } - - #[derive(Clone, PartialEq, Eq, Hash, Default)] - struct TestPublic; - impl AsRef<[u8]> for TestPublic { - fn as_ref(&self) -> &[u8] { - &[] - } - } - impl AsMut<[u8]> for TestPublic { - fn as_mut(&mut self) -> &mut [u8] { - &mut [] - } - } - impl CryptoType for TestPublic { - type Pair = TestPair; - } - impl Derive for TestPublic {} - impl Public for TestPublic { - fn from_slice(_bytes: &[u8]) -> Self { - Self - } - fn as_slice(&self) -> &[u8] { - &[] - } - fn to_raw_vec(&self) -> Vec { - vec![] - } - fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { - CryptoTypePublicPair( - CryptoTypeId(*b"dumm"), self.to_raw_vec(), - ) - } - } - impl Pair for TestPair { - type Public = TestPublic; - type Seed = [u8; 8]; - type Signature = [u8; 0]; - type DeriveError = (); - - fn generate() -> (Self, ::Seed) { (TestPair::Generated, [0u8; 8]) } - fn generate_with_phrase(_password: Option<&str>) -> (Self, String, ::Seed) { - (TestPair::GeneratedWithPhrase, "".into(), [0u8; 8]) - } - fn from_phrase(phrase: &str, password: Option<&str>) - -> Result<(Self, ::Seed), SecretStringError> - { - Ok((TestPair::GeneratedFromPhrase { - phrase: phrase.to_owned(), - password: password.map(Into::into) - }, [0u8; 8])) - } - fn derive>(&self, path_iter: Iter, _: Option<[u8; 8]>) - -> Result<(Self, Option<[u8; 8]>), Self::DeriveError> - { - Ok((match self.clone() { - TestPair::Standard {phrase, password, path} => - TestPair::Standard { phrase, password, path: path.into_iter().chain(path_iter).collect() }, - TestPair::GeneratedFromPhrase {phrase, password} => - TestPair::Standard { phrase, password, path: path_iter.collect() }, - x => if path_iter.count() == 0 { x } else { return Err(()) }, - }, None)) - } - fn from_seed(_seed: &::Seed) -> Self { TestPair::Seed(_seed.as_ref().to_owned()) } - fn sign(&self, _message: &[u8]) -> Self::Signature { [] } - fn verify>(_: &Self::Signature, _: M, _: &Self::Public) -> bool { true } - fn verify_weak, M: AsRef<[u8]>>( - _sig: &[u8], - _message: M, - _pubkey: P - ) -> bool { true } - fn public(&self) -> Self::Public { TestPublic } - fn from_seed_slice(seed: &[u8]) - -> Result - { - Ok(TestPair::Seed(seed.to_owned())) - } - fn to_raw_vec(&self) -> Vec { - vec![] - } - } - - #[test] - fn interpret_std_seed_should_work() { - assert_eq!( - TestPair::from_string("0x0123456789abcdef", None), - Ok(TestPair::Seed(hex!["0123456789abcdef"][..].to_owned())) - ); - } - - #[test] - fn password_override_should_work() { - assert_eq!( - TestPair::from_string("hello world///password", None), - TestPair::from_string("hello world", Some("password")), - ); - assert_eq!( - TestPair::from_string("hello world///password", None), - TestPair::from_string("hello world///other password", Some("password")), - ); - } - - #[test] - fn interpret_std_secret_string_should_work() { - assert_eq!( - TestPair::from_string("hello world", None), - Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![]}) - ); - assert_eq!( - TestPair::from_string("hello world/1", None), - Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![DeriveJunction::soft(1)]}) - ); - assert_eq!( - TestPair::from_string("hello world/DOT", None), - Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![DeriveJunction::soft("DOT")]}) - ); - assert_eq!( - TestPair::from_string("hello world//1", None), - Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![DeriveJunction::hard(1)]}) - ); - assert_eq!( - TestPair::from_string("hello world//DOT", None), - Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![DeriveJunction::hard("DOT")]}) - ); - assert_eq!( - TestPair::from_string("hello world//1/DOT", None), - Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![DeriveJunction::hard(1), DeriveJunction::soft("DOT")]}) - ); - assert_eq!( - TestPair::from_string("hello world//DOT/1", None), - Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![DeriveJunction::hard("DOT"), DeriveJunction::soft(1)]}) - ); - assert_eq!( - TestPair::from_string("hello world///password", None), - Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: Some("password".to_owned()), path: vec![]}) - ); - assert_eq!( - TestPair::from_string("hello world//1/DOT///password", None), - Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: Some("password".to_owned()), path: vec![DeriveJunction::hard(1), DeriveJunction::soft("DOT")]}) - ); - assert_eq!( - TestPair::from_string("hello world/1//DOT///password", None), - Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: Some("password".to_owned()), path: vec![DeriveJunction::soft(1), DeriveJunction::hard("DOT")]}) - ); - } - - #[test] - fn accountid_32_from_str_works() { - use std::str::FromStr; - assert!(AccountId32::from_str("5G9VdMwXvzza9pS8qE8ZHJk3CheHW9uucBn9ngW4C1gmmzpv").is_ok()); - assert!(AccountId32::from_str("5c55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").is_ok()); - assert!(AccountId32::from_str("0x5c55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").is_ok()); - - assert_eq!( - AccountId32::from_str("99G9VdMwXvzza9pS8qE8ZHJk3CheHW9uucBn9ngW4C1gmmzpv").unwrap_err(), - "invalid ss58 address.", - ); - assert_eq!( - AccountId32::from_str("gc55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").unwrap_err(), - "invalid hex address.", - ); - assert_eq!( - AccountId32::from_str("0xgc55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").unwrap_err(), - "invalid hex address.", - ); - - // valid hex but invalid length will be treated as ss58. - assert_eq!( - AccountId32::from_str("55c55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").unwrap_err(), - "invalid ss58 address.", - ); - } -} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/ecdsa.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/ecdsa.rs deleted file mode 100644 index 73e0a6db..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/ecdsa.rs +++ /dev/null @@ -1,718 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// tag::description[] -//! Simple ECDSA API. -// end::description[] - -#[cfg(feature = "full_crypto")] -use sp_std::vec::Vec; - -use sp_std::cmp::Ordering; -use codec::{Encode, Decode}; - -#[cfg(feature = "full_crypto")] -use core::convert::{TryFrom, TryInto}; -#[cfg(feature = "std")] -use substrate_bip39::seed_from_entropy; -#[cfg(feature = "std")] -use bip39::{Mnemonic, Language, MnemonicType}; -#[cfg(feature = "full_crypto")] -use crate::{hashing::blake2_256, crypto::{Pair as TraitPair, DeriveJunction, SecretStringError}}; -#[cfg(feature = "std")] -use crate::crypto::Ss58Codec; -#[cfg(feature = "std")] -use serde::{de, Serializer, Serialize, Deserializer, Deserialize}; -use crate::crypto::{Public as TraitPublic, CryptoTypePublicPair, UncheckedFrom, CryptoType, Derive, CryptoTypeId}; -use sp_runtime_interface::pass_by::PassByInner; -#[cfg(feature = "full_crypto")] -use secp256k1::{PublicKey, SecretKey}; - -/// An identifier used to match public keys against ecdsa keys -pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"ecds"); - -/// A secret seed (which is bytewise essentially equivalent to a SecretKey). -/// -/// We need it as a different type because `Seed` is expected to be AsRef<[u8]>. -#[cfg(feature = "full_crypto")] -type Seed = [u8; 32]; - -/// The ECDSA compressed public key. -#[derive(Clone, Encode, Decode, PassByInner)] -pub struct Public(pub [u8; 33]); - -impl PartialOrd for Public { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for Public { - fn cmp(&self, other: &Self) -> Ordering { - self.as_ref().cmp(&other.as_ref()) - } -} - -impl PartialEq for Public { - fn eq(&self, other: &Self) -> bool { - self.as_ref() == other.as_ref() - } -} - -impl Eq for Public {} - -/// An error type for SS58 decoding. -#[cfg(feature = "std")] -#[derive(Clone, Copy, Eq, PartialEq, Debug)] -pub enum PublicError { - /// Bad alphabet. - BadBase58, - /// Bad length. - BadLength, - /// Unknown version. - UnknownVersion, - /// Invalid checksum. - InvalidChecksum, -} - -impl Public { - /// A new instance from the given 33-byte `data`. - /// - /// NOTE: No checking goes on to ensure this is a real public key. Only use it if - /// you are certain that the array actually is a pubkey. GIGO! - pub fn from_raw(data: [u8; 33]) -> Self { - Self(data) - } - - /// Create a new instance from the given full public key. - /// - /// This will convert the full public key into the compressed format. - #[cfg(feature = "std")] - pub fn from_full(full: &[u8]) -> Result { - secp256k1::PublicKey::parse_slice(full, None) - .map(|k| k.serialize_compressed()) - .map(Self) - .map_err(|_| ()) - } -} - -impl TraitPublic for Public { - /// A new instance from the given slice that should be 33 bytes long. - /// - /// NOTE: No checking goes on to ensure this is a real public key. Only use it if - /// you are certain that the array actually is a pubkey. GIGO! - fn from_slice(data: &[u8]) -> Self { - let mut r = [0u8; 33]; - r.copy_from_slice(data); - Self(r) - } - - fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { - CryptoTypePublicPair(CRYPTO_ID, self.to_raw_vec()) - } -} - -impl From for CryptoTypePublicPair { - fn from(key: Public) -> Self { - (&key).into() - } -} - -impl From<&Public> for CryptoTypePublicPair { - fn from(key: &Public) -> Self { - CryptoTypePublicPair(CRYPTO_ID, key.to_raw_vec()) - } -} - -impl Derive for Public {} - -impl Default for Public { - fn default() -> Self { - Public([0u8; 33]) - } -} - -impl AsRef<[u8]> for Public { - fn as_ref(&self) -> &[u8] { - &self.0[..] - } -} - -impl AsMut<[u8]> for Public { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0[..] - } -} - -impl sp_std::convert::TryFrom<&[u8]> for Public { - type Error = (); - - fn try_from(data: &[u8]) -> Result { - if data.len() == 33 { - Ok(Self::from_slice(data)) - } else { - - Err(()) - } - } -} - -#[cfg(feature = "full_crypto")] -impl From for Public { - fn from(x: Pair) -> Self { - x.public() - } -} - -impl UncheckedFrom<[u8; 33]> for Public { - fn unchecked_from(x: [u8; 33]) -> Self { - Public(x) - } -} - -#[cfg(feature = "std")] -impl std::fmt::Display for Public { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{}", self.to_ss58check()) - } -} - -impl sp_std::fmt::Debug for Public { - #[cfg(feature = "std")] - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - let s = self.to_ss58check(); - write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.as_ref()), &s[0..8]) - } - - #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - Ok(()) - } -} - -#[cfg(feature = "std")] -impl Serialize for Public { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - serializer.serialize_str(&self.to_ss58check()) - } -} - -#[cfg(feature = "std")] -impl<'de> Deserialize<'de> for Public { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { - Public::from_ss58check(&String::deserialize(deserializer)?) - .map_err(|e| de::Error::custom(format!("{:?}", e))) - } -} - -#[cfg(feature = "full_crypto")] -impl sp_std::hash::Hash for Public { - fn hash(&self, state: &mut H) { - self.as_ref().hash(state); - } -} - -/// A signature (a 512-bit value, plus 8 bits for recovery ID). -#[derive(Encode, Decode, PassByInner)] -pub struct Signature(pub [u8; 65]); - -impl sp_std::convert::TryFrom<&[u8]> for Signature { - type Error = (); - - fn try_from(data: &[u8]) -> Result { - if data.len() == 65 { - let mut inner = [0u8; 65]; - inner.copy_from_slice(data); - Ok(Signature(inner)) - } else { - Err(()) - } - } -} - -#[cfg(feature = "std")] -impl Serialize for Signature { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - serializer.serialize_str(&hex::encode(self)) - } -} - -#[cfg(feature = "std")] -impl<'de> Deserialize<'de> for Signature { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { - let signature_hex = hex::decode(&String::deserialize(deserializer)?) - .map_err(|e| de::Error::custom(format!("{:?}", e)))?; - Ok(Signature::try_from(signature_hex.as_ref()) - .map_err(|e| de::Error::custom(format!("{:?}", e)))?) - } -} - -impl Clone for Signature { - fn clone(&self) -> Self { - let mut r = [0u8; 65]; - r.copy_from_slice(&self.0[..]); - Signature(r) - } -} - -impl Default for Signature { - fn default() -> Self { - Signature([0u8; 65]) - } -} - -impl PartialEq for Signature { - fn eq(&self, b: &Self) -> bool { - self.0[..] == b.0[..] - } -} - -impl Eq for Signature {} - -impl From for [u8; 65] { - fn from(v: Signature) -> [u8; 65] { - v.0 - } -} - -impl AsRef<[u8; 65]> for Signature { - fn as_ref(&self) -> &[u8; 65] { - &self.0 - } -} - -impl AsRef<[u8]> for Signature { - fn as_ref(&self) -> &[u8] { - &self.0[..] - } -} - -impl AsMut<[u8]> for Signature { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0[..] - } -} - -impl sp_std::fmt::Debug for Signature { - #[cfg(feature = "std")] - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0)) - } - - #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - Ok(()) - } -} - -#[cfg(feature = "full_crypto")] -impl sp_std::hash::Hash for Signature { - fn hash(&self, state: &mut H) { - sp_std::hash::Hash::hash(&self.0[..], state); - } -} - -impl Signature { - /// A new instance from the given 65-byte `data`. - /// - /// NOTE: No checking goes on to ensure this is a real signature. Only use it if - /// you are certain that the array actually is a signature. GIGO! - pub fn from_raw(data: [u8; 65]) -> Signature { - Signature(data) - } - - /// A new instance from the given slice that should be 65 bytes long. - /// - /// NOTE: No checking goes on to ensure this is a real signature. Only use it if - /// you are certain that the array actually is a signature. GIGO! - pub fn from_slice(data: &[u8]) -> Self { - let mut r = [0u8; 65]; - r.copy_from_slice(data); - Signature(r) - } - - /// Recover the public key from this signature and a message. - #[cfg(feature = "full_crypto")] - pub fn recover>(&self, message: M) -> Option { - let message = secp256k1::Message::parse(&blake2_256(message.as_ref())); - let sig: (_, _) = self.try_into().ok()?; - secp256k1::recover(&message, &sig.0, &sig.1) - .ok() - .map(|recovered| Public(recovered.serialize_compressed())) - } -} - -#[cfg(feature = "full_crypto")] -impl From<(secp256k1::Signature, secp256k1::RecoveryId)> for Signature { - fn from(x: (secp256k1::Signature, secp256k1::RecoveryId)) -> Signature { - let mut r = Self::default(); - r.0[0..64].copy_from_slice(&x.0.serialize()[..]); - r.0[64] = x.1.serialize(); - r - } -} - -#[cfg(feature = "full_crypto")] -impl<'a> TryFrom<&'a Signature> for (secp256k1::Signature, secp256k1::RecoveryId) { - type Error = (); - fn try_from(x: &'a Signature) -> Result<(secp256k1::Signature, secp256k1::RecoveryId), Self::Error> { - Ok(( - secp256k1::Signature::parse_slice(&x.0[0..64]).expect("hardcoded to 64 bytes; qed"), - secp256k1::RecoveryId::parse(x.0[64]).map_err(|_| ())?, - )) - } -} - -/// Derive a single hard junction. -#[cfg(feature = "full_crypto")] -fn derive_hard_junction(secret_seed: &Seed, cc: &[u8; 32]) -> Seed { - ("Secp256k1HDKD", secret_seed, cc).using_encoded(|data| { - let mut res = [0u8; 32]; - res.copy_from_slice(blake2_rfc::blake2b::blake2b(32, &[], data).as_bytes()); - res - }) -} - -/// An error when deriving a key. -#[cfg(feature = "full_crypto")] -pub enum DeriveError { - /// A soft key was found in the path (and is unsupported). - SoftKeyInPath, -} - -/// A key pair. -#[cfg(feature = "full_crypto")] -#[derive(Clone)] -pub struct Pair { - public: PublicKey, - secret: SecretKey, -} - -#[cfg(feature = "full_crypto")] -impl TraitPair for Pair { - type Public = Public; - type Seed = Seed; - type Signature = Signature; - type DeriveError = DeriveError; - - /// Generate new secure (random) key pair and provide the recovery phrase. - /// - /// You can recover the same key later with `from_phrase`. - #[cfg(feature = "std")] - fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) { - let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English); - let phrase = mnemonic.phrase(); - let (pair, seed) = Self::from_phrase(phrase, password) - .expect("All phrases generated by Mnemonic are valid; qed"); - ( - pair, - phrase.to_owned(), - seed, - ) - } - - /// Generate key pair from given recovery phrase and password. - #[cfg(feature = "std")] - fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> { - let big_seed = seed_from_entropy( - Mnemonic::from_phrase(phrase, Language::English) - .map_err(|_| SecretStringError::InvalidPhrase)?.entropy(), - password.unwrap_or(""), - ).map_err(|_| SecretStringError::InvalidSeed)?; - let mut seed = Seed::default(); - seed.copy_from_slice(&big_seed[0..32]); - Self::from_seed_slice(&big_seed[0..32]).map(|x| (x, seed)) - } - - /// Make a new key pair from secret seed material. - /// - /// You should never need to use this; generate(), generate_with_phrase - fn from_seed(seed: &Seed) -> Pair { - Self::from_seed_slice(&seed[..]).expect("seed has valid length; qed") - } - - /// Make a new key pair from secret seed material. The slice must be 32 bytes long or it - /// will return `None`. - /// - /// You should never need to use this; generate(), generate_with_phrase - fn from_seed_slice(seed_slice: &[u8]) -> Result { - let secret = SecretKey::parse_slice(seed_slice) - .map_err(|_| SecretStringError::InvalidSeedLength)?; - let public = PublicKey::from_secret_key(&secret); - Ok(Pair{ secret, public }) - } - - /// Derive a child key from a series of given junctions. - fn derive>(&self, - path: Iter, - _seed: Option - ) -> Result<(Pair, Option), DeriveError> { - let mut acc = self.secret.serialize(); - for j in path { - match j { - DeriveJunction::Soft(_cc) => return Err(DeriveError::SoftKeyInPath), - DeriveJunction::Hard(cc) => acc = derive_hard_junction(&acc, &cc), - } - } - Ok((Self::from_seed(&acc), Some(acc))) - } - - /// Get the public key. - fn public(&self) -> Public { - Public(self.public.serialize_compressed()) - } - - /// Sign a message. - fn sign(&self, message: &[u8]) -> Signature { - let message = secp256k1::Message::parse(&blake2_256(message)); - secp256k1::sign(&message, &self.secret).into() - } - - /// Verify a signature on a message. Returns true if the signature is good. - fn verify>(sig: &Self::Signature, message: M, pubkey: &Self::Public) -> bool { - let message = secp256k1::Message::parse(&blake2_256(message.as_ref())); - let sig: (_, _) = match sig.try_into() { Ok(x) => x, _ => return false }; - match secp256k1::recover(&message, &sig.0, &sig.1) { - Ok(actual) => &pubkey.0[..] == &actual.serialize_compressed()[..], - _ => false, - } - } - - /// Verify a signature on a message. Returns true if the signature is good. - /// - /// This doesn't use the type system to ensure that `sig` and `pubkey` are the correct - /// size. Use it only if you're coming from byte buffers and need the speed. - fn verify_weak, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool { - let message = secp256k1::Message::parse(&blake2_256(message.as_ref())); - if sig.len() != 65 { return false } - let ri = match secp256k1::RecoveryId::parse(sig[64]) { Ok(x) => x, _ => return false }; - let sig = match secp256k1::Signature::parse_slice(&sig[0..64]) { Ok(x) => x, _ => return false }; - match secp256k1::recover(&message, &sig, &ri) { - Ok(actual) => pubkey.as_ref() == &actual.serialize()[1..], - _ => false, - } - } - - /// Return a vec filled with raw data. - fn to_raw_vec(&self) -> Vec { - self.seed().to_vec() - } -} - -#[cfg(feature = "full_crypto")] -impl Pair { - /// Get the seed for this key. - pub fn seed(&self) -> Seed { - self.secret.serialize() - } - - /// Exactly as `from_string` except that if no matches are found then, the the first 32 - /// characters are taken (padded with spaces as necessary) and used as the MiniSecretKey. - #[cfg(feature = "std")] - pub fn from_legacy_string(s: &str, password_override: Option<&str>) -> Pair { - Self::from_string(s, password_override).unwrap_or_else(|_| { - let mut padded_seed: Seed = [' ' as u8; 32]; - let len = s.len().min(32); - padded_seed[..len].copy_from_slice(&s.as_bytes()[..len]); - Self::from_seed(&padded_seed) - }) - } -} - -impl CryptoType for Public { - #[cfg(feature="full_crypto")] - type Pair = Pair; -} - -impl CryptoType for Signature { - #[cfg(feature="full_crypto")] - type Pair = Pair; -} - -#[cfg(feature="full_crypto")] -impl CryptoType for Pair { - type Pair = Pair; -} - -#[cfg(test)] -mod test { - use super::*; - use hex_literal::hex; - use crate::crypto::{DEV_PHRASE, set_default_ss58_version}; - use serde_json; - - #[test] - fn default_phrase_should_be_used() { - assert_eq!( - Pair::from_string("//Alice///password", None).unwrap().public(), - Pair::from_string(&format!("{}//Alice", DEV_PHRASE), Some("password")).unwrap().public(), - ); - } - - #[test] - fn seed_and_derive_should_work() { - let seed = hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"); - let pair = Pair::from_seed(&seed); - assert_eq!(pair.seed(), seed); - let path = vec![DeriveJunction::Hard([0u8; 32])]; - let derived = pair.derive(path.into_iter(), None).ok().unwrap(); - assert_eq!( - derived.0.seed(), - hex!("b8eefc4937200a8382d00050e050ced2d4ab72cc2ef1b061477afb51564fdd61") - ); - } - - #[test] - fn test_vector_should_work() { - let pair = Pair::from_seed( - &hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60") - ); - let public = pair.public(); - assert_eq!( - public, - Public::from_full( - &hex!("8db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd913ebbe148dd17c56551a52952371071a6c604b3f3abe8f2c8fa742158ea6dd7d4")[..], - ).unwrap(), - ); - let message = b""; - let signature = hex!("3dde91174bd9359027be59a428b8146513df80a2a3c7eda2194f64de04a69ab97b753169e94db6ffd50921a2668a48b94ca11e3d32c1ff19cfe88890aa7e8f3c00"); - let signature = Signature::from_raw(signature); - assert!(&pair.sign(&message[..]) == &signature); - assert!(Pair::verify(&signature, &message[..], &public)); - } - - #[test] - fn test_vector_by_string_should_work() { - let pair = Pair::from_string( - "0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60", - None - ).unwrap(); - let public = pair.public(); - assert_eq!( - public, - Public::from_full( - &hex!("8db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd913ebbe148dd17c56551a52952371071a6c604b3f3abe8f2c8fa742158ea6dd7d4")[..], - ).unwrap(), - ); - let message = b""; - let signature = hex!("3dde91174bd9359027be59a428b8146513df80a2a3c7eda2194f64de04a69ab97b753169e94db6ffd50921a2668a48b94ca11e3d32c1ff19cfe88890aa7e8f3c00"); - let signature = Signature::from_raw(signature); - assert!(&pair.sign(&message[..]) == &signature); - assert!(Pair::verify(&signature, &message[..], &public)); - } - - #[test] - fn generated_pair_should_work() { - let (pair, _) = Pair::generate(); - let public = pair.public(); - let message = b"Something important"; - let signature = pair.sign(&message[..]); - assert!(Pair::verify(&signature, &message[..], &public)); - assert!(!Pair::verify(&signature, b"Something else", &public)); - } - - #[test] - fn seeded_pair_should_work() { - let pair = Pair::from_seed(b"12345678901234567890123456789012"); - let public = pair.public(); - assert_eq!( - public, - Public::from_full( - &hex!("5676109c54b9a16d271abeb4954316a40a32bcce023ac14c8e26e958aa68fba995840f3de562156558efbfdac3f16af0065e5f66795f4dd8262a228ef8c6d813")[..], - ).unwrap(), - ); - let message = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000200d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000"); - let signature = pair.sign(&message[..]); - println!("Correct signature: {:?}", signature); - assert!(Pair::verify(&signature, &message[..], &public)); - assert!(!Pair::verify(&signature, "Other message", &public)); - } - - #[test] - fn generate_with_phrase_recovery_possible() { - let (pair1, phrase, _) = Pair::generate_with_phrase(None); - let (pair2, _) = Pair::from_phrase(&phrase, None).unwrap(); - - assert_eq!(pair1.public(), pair2.public()); - } - - #[test] - fn generate_with_password_phrase_recovery_possible() { - let (pair1, phrase, _) = Pair::generate_with_phrase(Some("password")); - let (pair2, _) = Pair::from_phrase(&phrase, Some("password")).unwrap(); - - assert_eq!(pair1.public(), pair2.public()); - } - - #[test] - fn password_does_something() { - let (pair1, phrase, _) = Pair::generate_with_phrase(Some("password")); - let (pair2, _) = Pair::from_phrase(&phrase, None).unwrap(); - - assert_ne!(pair1.public(), pair2.public()); - } - - #[test] - #[ignore] // we are not using ss58 from this crate because it's only for legacy purposes (decoding) - fn ss58check_roundtrip_works() { - let pair = Pair::from_seed(b"12345678901234567890123456789012"); - let public = pair.public(); - let s = public.to_ss58check(); - println!("Correct: {}", s); - let cmp = Public::from_ss58check(&s).unwrap(); - assert_eq!(cmp, public); - } - - #[test] - fn ss58check_custom_format_works() { - use crate::crypto::Ss58AddressFormat; - // temp save default format version - let default_format = Ss58AddressFormat::default(); - // set current ss58 version is custom "200" `Ss58AddressFormat::Custom(200)` - set_default_ss58_version(Ss58AddressFormat::Custom(200)); - // custom addr encoded by version 200 - let addr = "2X64kMNEWAW5KLZMSKcGKEc96MyuaRsRUku7vomuYxKgqjVCRj"; - Public::from_ss58check(&addr).unwrap(); - set_default_ss58_version(default_format); - // set current ss58 version to default version - let addr = "KWAfgC2aRG5UVD6CpbPQXCx4YZZUhvWqqAJE6qcYc9Rtr6g5C"; - Public::from_ss58check(&addr).unwrap(); - } - - #[test] - fn signature_serialization_works() { - let pair = Pair::from_seed(b"12345678901234567890123456789012"); - let message = b"Something important"; - let signature = pair.sign(&message[..]); - let serialized_signature = serde_json::to_string(&signature).unwrap(); - // Signature is 65 bytes, so 130 chars + 2 quote chars - assert_eq!(serialized_signature.len(), 132); - let signature = serde_json::from_str(&serialized_signature).unwrap(); - assert!(Pair::verify(&signature, &message[..], &pair.public())); - } - - #[test] - fn signature_serialization_doesnt_panic() { - fn deserialize_signature(text: &str) -> Result { - Ok(serde_json::from_str(text)?) - } - assert!(deserialize_signature("Not valid json.").is_err()); - assert!(deserialize_signature("\"Not an actual signature.\"").is_err()); - // Poorly-sized - assert!(deserialize_signature("\"abc123\"").is_err()); - } -} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/ed25519.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/ed25519.rs deleted file mode 100644 index e7fc53b4..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/ed25519.rs +++ /dev/null @@ -1,712 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// tag::description[] -//! Simple Ed25519 API. -// end::description[] - -#[cfg(feature = "full_crypto")] -use sp_std::vec::Vec; - -use crate::{hash::H256, hash::H512}; -use codec::{Encode, Decode}; - -#[cfg(feature = "full_crypto")] -use blake2_rfc; -#[cfg(feature = "full_crypto")] -use core::convert::TryFrom; -#[cfg(feature = "full_crypto")] -use ed25519_dalek::{Signer as _, Verifier as _}; -#[cfg(feature = "std")] -use substrate_bip39::seed_from_entropy; -#[cfg(feature = "std")] -use bip39::{Mnemonic, Language, MnemonicType}; -#[cfg(feature = "full_crypto")] -use crate::crypto::{Pair as TraitPair, DeriveJunction, SecretStringError}; -#[cfg(feature = "std")] -use crate::crypto::Ss58Codec; -#[cfg(feature = "std")] -use serde::{de, Serializer, Serialize, Deserializer, Deserialize}; -use crate::crypto::{Public as TraitPublic, CryptoTypePublicPair, UncheckedFrom, CryptoType, Derive, CryptoTypeId}; -use sp_runtime_interface::pass_by::PassByInner; -use sp_std::ops::Deref; - -/// An identifier used to match public keys against ed25519 keys -pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"ed25"); - -/// A secret seed. It's not called a "secret key" because ring doesn't expose the secret keys -/// of the key pair (yeah, dumb); as such we're forced to remember the seed manually if we -/// will need it later (such as for HDKD). -#[cfg(feature = "full_crypto")] -type Seed = [u8; 32]; - -/// A public key. -#[cfg_attr(feature = "full_crypto", derive(Hash))] -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Encode, Decode, Default, PassByInner)] -pub struct Public(pub [u8; 32]); - -/// A key pair. -#[cfg(feature = "full_crypto")] -pub struct Pair(ed25519_dalek::Keypair); - -#[cfg(feature = "full_crypto")] -impl Clone for Pair { - fn clone(&self) -> Self { - Pair(ed25519_dalek::Keypair { - public: self.0.public.clone(), - secret: ed25519_dalek::SecretKey::from_bytes(self.0.secret.as_bytes()) - .expect("key is always the correct size; qed") - }) - } -} - -impl AsRef<[u8; 32]> for Public { - fn as_ref(&self) -> &[u8; 32] { - &self.0 - } -} - -impl AsRef<[u8]> for Public { - fn as_ref(&self) -> &[u8] { - &self.0[..] - } -} - -impl AsMut<[u8]> for Public { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0[..] - } -} - -impl Deref for Public { - type Target = [u8]; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl sp_std::convert::TryFrom<&[u8]> for Public { - type Error = (); - - fn try_from(data: &[u8]) -> Result { - if data.len() == 32 { - let mut inner = [0u8; 32]; - inner.copy_from_slice(data); - Ok(Public(inner)) - } else { - Err(()) - } - } -} - -impl From for [u8; 32] { - fn from(x: Public) -> Self { - x.0 - } -} - -#[cfg(feature = "full_crypto")] -impl From for Public { - fn from(x: Pair) -> Self { - x.public() - } -} - -impl From for H256 { - fn from(x: Public) -> Self { - x.0.into() - } -} - -#[cfg(feature = "std")] -impl std::str::FromStr for Public { - type Err = crate::crypto::PublicError; - - fn from_str(s: &str) -> Result { - Self::from_ss58check(s) - } -} - -impl UncheckedFrom<[u8; 32]> for Public { - fn unchecked_from(x: [u8; 32]) -> Self { - Public::from_raw(x) - } -} - -impl UncheckedFrom for Public { - fn unchecked_from(x: H256) -> Self { - Public::from_h256(x) - } -} - -#[cfg(feature = "std")] -impl std::fmt::Display for Public { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{}", self.to_ss58check()) - } -} - -impl sp_std::fmt::Debug for Public { - #[cfg(feature = "std")] - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - let s = self.to_ss58check(); - write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) - } - - #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - Ok(()) - } -} - -#[cfg(feature = "std")] -impl Serialize for Public { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - serializer.serialize_str(&self.to_ss58check()) - } -} - -#[cfg(feature = "std")] -impl<'de> Deserialize<'de> for Public { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { - Public::from_ss58check(&String::deserialize(deserializer)?) - .map_err(|e| de::Error::custom(format!("{:?}", e))) - } -} - -/// A signature (a 512-bit value). -#[derive(Encode, Decode, PassByInner)] -pub struct Signature(pub [u8; 64]); - -impl sp_std::convert::TryFrom<&[u8]> for Signature { - type Error = (); - - fn try_from(data: &[u8]) -> Result { - if data.len() == 64 { - let mut inner = [0u8; 64]; - inner.copy_from_slice(data); - Ok(Signature(inner)) - } else { - Err(()) - } - } -} - -#[cfg(feature = "std")] -impl Serialize for Signature { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - serializer.serialize_str(&hex::encode(self)) - } -} - -#[cfg(feature = "std")] -impl<'de> Deserialize<'de> for Signature { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { - let signature_hex = hex::decode(&String::deserialize(deserializer)?) - .map_err(|e| de::Error::custom(format!("{:?}", e)))?; - Ok(Signature::try_from(signature_hex.as_ref()) - .map_err(|e| de::Error::custom(format!("{:?}", e)))?) - } -} - -impl Clone for Signature { - fn clone(&self) -> Self { - let mut r = [0u8; 64]; - r.copy_from_slice(&self.0[..]); - Signature(r) - } -} - -impl Default for Signature { - fn default() -> Self { - Signature([0u8; 64]) - } -} - -impl PartialEq for Signature { - fn eq(&self, b: &Self) -> bool { - self.0[..] == b.0[..] - } -} - -impl Eq for Signature {} - -impl From for H512 { - fn from(v: Signature) -> H512 { - H512::from(v.0) - } -} - -impl From for [u8; 64] { - fn from(v: Signature) -> [u8; 64] { - v.0 - } -} - -impl AsRef<[u8; 64]> for Signature { - fn as_ref(&self) -> &[u8; 64] { - &self.0 - } -} - -impl AsRef<[u8]> for Signature { - fn as_ref(&self) -> &[u8] { - &self.0[..] - } -} - -impl AsMut<[u8]> for Signature { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0[..] - } -} - -impl sp_std::fmt::Debug for Signature { - #[cfg(feature = "std")] - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0)) - } - - #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - Ok(()) - } -} - -#[cfg(feature = "full_crypto")] -impl sp_std::hash::Hash for Signature { - fn hash(&self, state: &mut H) { - sp_std::hash::Hash::hash(&self.0[..], state); - } -} - -impl Signature { - /// A new instance from the given 64-byte `data`. - /// - /// NOTE: No checking goes on to ensure this is a real signature. Only use it if - /// you are certain that the array actually is a signature. GIGO! - pub fn from_raw(data: [u8; 64]) -> Signature { - Signature(data) - } - - /// A new instance from the given slice that should be 64 bytes long. - /// - /// NOTE: No checking goes on to ensure this is a real signature. Only use it if - /// you are certain that the array actually is a signature. GIGO! - pub fn from_slice(data: &[u8]) -> Self { - let mut r = [0u8; 64]; - r.copy_from_slice(data); - Signature(r) - } - - /// A new instance from an H512. - /// - /// NOTE: No checking goes on to ensure this is a real signature. Only use it if - /// you are certain that the array actually is a signature. GIGO! - pub fn from_h512(v: H512) -> Signature { - Signature(v.into()) - } -} - -/// A localized signature also contains sender information. -#[cfg(feature = "std")] -#[derive(PartialEq, Eq, Clone, Debug, Encode, Decode)] -pub struct LocalizedSignature { - /// The signer of the signature. - pub signer: Public, - /// The signature itself. - pub signature: Signature, -} - -/// An error type for SS58 decoding. -#[cfg(feature = "std")] -#[derive(Clone, Copy, Eq, PartialEq, Debug)] -pub enum PublicError { - /// Bad alphabet. - BadBase58, - /// Bad length. - BadLength, - /// Unknown version. - UnknownVersion, - /// Invalid checksum. - InvalidChecksum, -} - -impl Public { - /// A new instance from the given 32-byte `data`. - /// - /// NOTE: No checking goes on to ensure this is a real public key. Only use it if - /// you are certain that the array actually is a pubkey. GIGO! - pub fn from_raw(data: [u8; 32]) -> Self { - Public(data) - } - - /// A new instance from an H256. - /// - /// NOTE: No checking goes on to ensure this is a real public key. Only use it if - /// you are certain that the array actually is a pubkey. GIGO! - pub fn from_h256(x: H256) -> Self { - Public(x.into()) - } - - /// Return a slice filled with raw data. - pub fn as_array_ref(&self) -> &[u8; 32] { - self.as_ref() - } -} - -impl TraitPublic for Public { - /// A new instance from the given slice that should be 32 bytes long. - /// - /// NOTE: No checking goes on to ensure this is a real public key. Only use it if - /// you are certain that the array actually is a pubkey. GIGO! - fn from_slice(data: &[u8]) -> Self { - let mut r = [0u8; 32]; - r.copy_from_slice(data); - Public(r) - } - - fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { - CryptoTypePublicPair(CRYPTO_ID, self.to_raw_vec()) - } -} - -impl Derive for Public {} - -impl From for CryptoTypePublicPair { - fn from(key: Public) -> Self { - (&key).into() - } -} - -impl From<&Public> for CryptoTypePublicPair { - fn from(key: &Public) -> Self { - CryptoTypePublicPair(CRYPTO_ID, key.to_raw_vec()) - } -} - -/// Derive a single hard junction. -#[cfg(feature = "full_crypto")] -fn derive_hard_junction(secret_seed: &Seed, cc: &[u8; 32]) -> Seed { - ("Ed25519HDKD", secret_seed, cc).using_encoded(|data| { - let mut res = [0u8; 32]; - res.copy_from_slice(blake2_rfc::blake2b::blake2b(32, &[], data).as_bytes()); - res - }) -} - -/// An error when deriving a key. -#[cfg(feature = "full_crypto")] -pub enum DeriveError { - /// A soft key was found in the path (and is unsupported). - SoftKeyInPath, -} - -#[cfg(feature = "full_crypto")] -impl TraitPair for Pair { - type Public = Public; - type Seed = Seed; - type Signature = Signature; - type DeriveError = DeriveError; - - /// Generate new secure (random) key pair and provide the recovery phrase. - /// - /// You can recover the same key later with `from_phrase`. - #[cfg(feature = "std")] - fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) { - let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English); - let phrase = mnemonic.phrase(); - let (pair, seed) = Self::from_phrase(phrase, password) - .expect("All phrases generated by Mnemonic are valid; qed"); - ( - pair, - phrase.to_owned(), - seed, - ) - } - - /// Generate key pair from given recovery phrase and password. - #[cfg(feature = "std")] - fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> { - let big_seed = seed_from_entropy( - Mnemonic::from_phrase(phrase, Language::English) - .map_err(|_| SecretStringError::InvalidPhrase)?.entropy(), - password.unwrap_or(""), - ).map_err(|_| SecretStringError::InvalidSeed)?; - let mut seed = Seed::default(); - seed.copy_from_slice(&big_seed[0..32]); - Self::from_seed_slice(&big_seed[0..32]).map(|x| (x, seed)) - } - - /// Make a new key pair from secret seed material. - /// - /// You should never need to use this; generate(), generate_with_phrase - fn from_seed(seed: &Seed) -> Pair { - Self::from_seed_slice(&seed[..]).expect("seed has valid length; qed") - } - - /// Make a new key pair from secret seed material. The slice must be 32 bytes long or it - /// will return `None`. - /// - /// You should never need to use this; generate(), generate_with_phrase - fn from_seed_slice(seed_slice: &[u8]) -> Result { - let secret = ed25519_dalek::SecretKey::from_bytes(seed_slice) - .map_err(|_| SecretStringError::InvalidSeedLength)?; - let public = ed25519_dalek::PublicKey::from(&secret); - Ok(Pair(ed25519_dalek::Keypair { secret, public })) - } - - /// Derive a child key from a series of given junctions. - fn derive>(&self, - path: Iter, - _seed: Option, - ) -> Result<(Pair, Option), DeriveError> { - let mut acc = self.0.secret.to_bytes(); - for j in path { - match j { - DeriveJunction::Soft(_cc) => return Err(DeriveError::SoftKeyInPath), - DeriveJunction::Hard(cc) => acc = derive_hard_junction(&acc, &cc), - } - } - Ok((Self::from_seed(&acc), Some(acc))) - } - - /// Get the public key. - fn public(&self) -> Public { - let mut r = [0u8; 32]; - let pk = self.0.public.as_bytes(); - r.copy_from_slice(pk); - Public(r) - } - - /// Sign a message. - fn sign(&self, message: &[u8]) -> Signature { - let r = self.0.sign(message).to_bytes(); - Signature::from_raw(r) - } - - /// Verify a signature on a message. Returns true if the signature is good. - fn verify>(sig: &Self::Signature, message: M, pubkey: &Self::Public) -> bool { - Self::verify_weak(&sig.0[..], message.as_ref(), pubkey) - } - - /// Verify a signature on a message. Returns true if the signature is good. - /// - /// This doesn't use the type system to ensure that `sig` and `pubkey` are the correct - /// size. Use it only if you're coming from byte buffers and need the speed. - fn verify_weak, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool { - let public_key = match ed25519_dalek::PublicKey::from_bytes(pubkey.as_ref()) { - Ok(pk) => pk, - Err(_) => return false, - }; - - let sig = match ed25519_dalek::Signature::try_from(sig) { - Ok(s) => s, - Err(_) => return false - }; - - match public_key.verify(message.as_ref(), &sig) { - Ok(_) => true, - _ => false, - } - } - - /// Return a vec filled with raw data. - fn to_raw_vec(&self) -> Vec { - self.seed().to_vec() - } -} - -#[cfg(feature = "full_crypto")] -impl Pair { - /// Get the seed for this key. - pub fn seed(&self) -> &Seed { - self.0.secret.as_bytes() - } - - /// Exactly as `from_string` except that if no matches are found then, the the first 32 - /// characters are taken (padded with spaces as necessary) and used as the MiniSecretKey. - #[cfg(feature = "std")] - pub fn from_legacy_string(s: &str, password_override: Option<&str>) -> Pair { - Self::from_string(s, password_override).unwrap_or_else(|_| { - let mut padded_seed: Seed = [' ' as u8; 32]; - let len = s.len().min(32); - padded_seed[..len].copy_from_slice(&s.as_bytes()[..len]); - Self::from_seed(&padded_seed) - }) - } -} - -impl CryptoType for Public { - #[cfg(feature = "full_crypto")] - type Pair = Pair; -} - -impl CryptoType for Signature { - #[cfg(feature = "full_crypto")] - type Pair = Pair; -} - -#[cfg(feature = "full_crypto")] -impl CryptoType for Pair { - type Pair = Pair; -} - -#[cfg(test)] -mod test { - use super::*; - use hex_literal::hex; - use crate::crypto::DEV_PHRASE; - use serde_json; - - #[test] - fn default_phrase_should_be_used() { - assert_eq!( - Pair::from_string("//Alice///password", None).unwrap().public(), - Pair::from_string(&format!("{}//Alice", DEV_PHRASE), Some("password")).unwrap().public(), - ); - } - - #[test] - fn seed_and_derive_should_work() { - let seed = hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"); - let pair = Pair::from_seed(&seed); - assert_eq!(pair.seed(), &seed); - let path = vec![DeriveJunction::Hard([0u8; 32])]; - let derived = pair.derive(path.into_iter(), None).ok().unwrap().0; - assert_eq!( - derived.seed(), - &hex!("ede3354e133f9c8e337ddd6ee5415ed4b4ffe5fc7d21e933f4930a3730e5b21c") - ); - } - - #[test] - fn test_vector_should_work() { - let pair = Pair::from_seed( - &hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60") - ); - let public = pair.public(); - assert_eq!(public, Public::from_raw( - hex!("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a") - )); - let message = b""; - let signature = hex!("e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"); - let signature = Signature::from_raw(signature); - assert!(&pair.sign(&message[..]) == &signature); - assert!(Pair::verify(&signature, &message[..], &public)); - } - - #[test] - fn test_vector_by_string_should_work() { - let pair = Pair::from_string( - "0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60", - None - ).unwrap(); - let public = pair.public(); - assert_eq!(public, Public::from_raw( - hex!("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a") - )); - let message = b""; - let signature = hex!("e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"); - let signature = Signature::from_raw(signature); - assert!(&pair.sign(&message[..]) == &signature); - assert!(Pair::verify(&signature, &message[..], &public)); - } - - #[test] - fn generated_pair_should_work() { - let (pair, _) = Pair::generate(); - let public = pair.public(); - let message = b"Something important"; - let signature = pair.sign(&message[..]); - assert!(Pair::verify(&signature, &message[..], &public)); - assert!(!Pair::verify(&signature, b"Something else", &public)); - } - - #[test] - fn seeded_pair_should_work() { - let pair = Pair::from_seed(b"12345678901234567890123456789012"); - let public = pair.public(); - assert_eq!(public, Public::from_raw( - hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee") - )); - let message = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000200d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000"); - let signature = pair.sign(&message[..]); - println!("Correct signature: {:?}", signature); - assert!(Pair::verify(&signature, &message[..], &public)); - assert!(!Pair::verify(&signature, "Other message", &public)); - } - - #[test] - fn generate_with_phrase_recovery_possible() { - let (pair1, phrase, _) = Pair::generate_with_phrase(None); - let (pair2, _) = Pair::from_phrase(&phrase, None).unwrap(); - - assert_eq!(pair1.public(), pair2.public()); - } - - #[test] - fn generate_with_password_phrase_recovery_possible() { - let (pair1, phrase, _) = Pair::generate_with_phrase(Some("password")); - let (pair2, _) = Pair::from_phrase(&phrase, Some("password")).unwrap(); - - assert_eq!(pair1.public(), pair2.public()); - } - - #[test] - fn password_does_something() { - let (pair1, phrase, _) = Pair::generate_with_phrase(Some("password")); - let (pair2, _) = Pair::from_phrase(&phrase, None).unwrap(); - - assert_ne!(pair1.public(), pair2.public()); - } - - #[test] - #[ignore] // We are not using ss58 from this crate because only for legacy purposes (decoding) - fn ss58check_roundtrip_works() { - let pair = Pair::from_seed(b"12345678901234567890123456789012"); - let public = pair.public(); - let s = public.to_ss58check(); - println!("Correct: {}", s); - let cmp = Public::from_ss58check(&s).unwrap(); - assert_eq!(cmp, public); - } - - #[test] - fn signature_serialization_works() { - let pair = Pair::from_seed(b"12345678901234567890123456789012"); - let message = b"Something important"; - let signature = pair.sign(&message[..]); - let serialized_signature = serde_json::to_string(&signature).unwrap(); - // Signature is 64 bytes, so 128 chars + 2 quote chars - assert_eq!(serialized_signature.len(), 130); - let signature = serde_json::from_str(&serialized_signature).unwrap(); - assert!(Pair::verify(&signature, &message[..], &pair.public())); - } - - #[test] - fn signature_serialization_doesnt_panic() { - fn deserialize_signature(text: &str) -> Result { - Ok(serde_json::from_str(text)?) - } - assert!(deserialize_signature("Not valid json.").is_err()); - assert!(deserialize_signature("\"Not an actual signature.\"").is_err()); - // Poorly-sized - assert!(deserialize_signature("\"abc123\"").is_err()); - } -} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/hash.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/hash.rs deleted file mode 100644 index 20a6788c..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/hash.rs +++ /dev/null @@ -1,82 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! A fixed hash type. - -pub use primitive_types::{H160, H256, H512}; - -/// Hash conversion. Used to convert between unbound associated hash types in traits, -/// implemented by the same hash type. -/// Panics if used to convert between different hash types. -pub fn convert_hash, H2: AsRef<[u8]>>(src: &H2) -> H1 { - let mut dest = H1::default(); - assert_eq!(dest.as_mut().len(), src.as_ref().len()); - dest.as_mut().copy_from_slice(src.as_ref()); - dest -} - -#[cfg(test)] -mod tests { - use super::*; - use sp_serializer as ser; - - #[test] - fn test_h160() { - let tests = vec![ - (Default::default(), "0x0000000000000000000000000000000000000000"), - (H160::from_low_u64_be(2), "0x0000000000000000000000000000000000000002"), - (H160::from_low_u64_be(15), "0x000000000000000000000000000000000000000f"), - (H160::from_low_u64_be(16), "0x0000000000000000000000000000000000000010"), - (H160::from_low_u64_be(1_000), "0x00000000000000000000000000000000000003e8"), - (H160::from_low_u64_be(100_000), "0x00000000000000000000000000000000000186a0"), - (H160::from_low_u64_be(u64::max_value()), "0x000000000000000000000000ffffffffffffffff"), - ]; - - for (number, expected) in tests { - assert_eq!(format!("{:?}", expected), ser::to_string_pretty(&number)); - assert_eq!(number, ser::from_str(&format!("{:?}", expected)).unwrap()); - } - } - - #[test] - fn test_h256() { - let tests = vec![ - (Default::default(), "0x0000000000000000000000000000000000000000000000000000000000000000"), - (H256::from_low_u64_be(2), "0x0000000000000000000000000000000000000000000000000000000000000002"), - (H256::from_low_u64_be(15), "0x000000000000000000000000000000000000000000000000000000000000000f"), - (H256::from_low_u64_be(16), "0x0000000000000000000000000000000000000000000000000000000000000010"), - (H256::from_low_u64_be(1_000), "0x00000000000000000000000000000000000000000000000000000000000003e8"), - (H256::from_low_u64_be(100_000), "0x00000000000000000000000000000000000000000000000000000000000186a0"), - (H256::from_low_u64_be(u64::max_value()), "0x000000000000000000000000000000000000000000000000ffffffffffffffff"), - ]; - - for (number, expected) in tests { - assert_eq!(format!("{:?}", expected), ser::to_string_pretty(&number)); - assert_eq!(number, ser::from_str(&format!("{:?}", expected)).unwrap()); - } - } - - #[test] - fn test_invalid() { - assert!(ser::from_str::("\"0x000000000000000000000000000000000000000000000000000000000000000\"").unwrap_err().is_data()); - assert!(ser::from_str::("\"0x000000000000000000000000000000000000000000000000000000000000000g\"").unwrap_err().is_data()); - assert!(ser::from_str::("\"0x00000000000000000000000000000000000000000000000000000000000000000\"").unwrap_err().is_data()); - assert!(ser::from_str::("\"\"").unwrap_err().is_data()); - assert!(ser::from_str::("\"0\"").unwrap_err().is_data()); - assert!(ser::from_str::("\"10\"").unwrap_err().is_data()); - } -} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/hasher.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/hasher.rs deleted file mode 100644 index 8ccaa4d9..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/hasher.rs +++ /dev/null @@ -1,58 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Substrate Blake2b Hasher implementation - -pub mod blake2 { - use hash_db::Hasher; - use hash256_std_hasher::Hash256StdHasher; - use crate::hash::H256; - - /// Concrete implementation of Hasher using Blake2b 256-bit hashes - #[derive(Debug)] - pub struct Blake2Hasher; - - impl Hasher for Blake2Hasher { - type Out = H256; - type StdHasher = Hash256StdHasher; - const LENGTH: usize = 32; - - fn hash(x: &[u8]) -> Self::Out { - crate::hashing::blake2_256(x).into() - } - } -} - -pub mod keccak { - use hash_db::Hasher; - use hash256_std_hasher::Hash256StdHasher; - use crate::hash::H256; - - /// Concrete implementation of Hasher using Keccak 256-bit hashes - #[derive(Debug)] - pub struct KeccakHasher; - - impl Hasher for KeccakHasher { - type Out = H256; - type StdHasher = Hash256StdHasher; - const LENGTH: usize = 32; - - fn hash(x: &[u8]) -> Self::Out { - crate::hashing::keccak_256(x).into() - } - } -} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/hashing.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/hashing.rs deleted file mode 100644 index f61700a5..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/hashing.rs +++ /dev/null @@ -1,156 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Hashing functions. - -use blake2_rfc; -use sha2::{Digest, Sha256}; -use tiny_keccak::{Hasher, Keccak}; -use twox_hash; - -/// Do a Blake2 512-bit hash and place result in `dest`. -pub fn blake2_512_into(data: &[u8], dest: &mut [u8; 64]) { - dest.copy_from_slice(blake2_rfc::blake2b::blake2b(64, &[], data).as_bytes()); -} - -/// Do a Blake2 512-bit hash and return result. -pub fn blake2_512(data: &[u8]) -> [u8; 64] { - let mut r = [0; 64]; - blake2_512_into(data, &mut r); - r -} - -/// Do a Blake2 256-bit hash and place result in `dest`. -pub fn blake2_256_into(data: &[u8], dest: &mut [u8; 32]) { - dest.copy_from_slice(blake2_rfc::blake2b::blake2b(32, &[], data).as_bytes()); -} - -/// Do a Blake2 256-bit hash and return result. -pub fn blake2_256(data: &[u8]) -> [u8; 32] { - let mut r = [0; 32]; - blake2_256_into(data, &mut r); - r -} - -/// Do a Blake2 128-bit hash and place result in `dest`. -pub fn blake2_128_into(data: &[u8], dest: &mut [u8; 16]) { - dest.copy_from_slice(blake2_rfc::blake2b::blake2b(16, &[], data).as_bytes()); -} - -/// Do a Blake2 128-bit hash and return result. -pub fn blake2_128(data: &[u8]) -> [u8; 16] { - let mut r = [0; 16]; - blake2_128_into(data, &mut r); - r -} - -/// Do a Blake2 64-bit hash and place result in `dest`. -pub fn blake2_64_into(data: &[u8], dest: &mut [u8; 8]) { - dest.copy_from_slice(blake2_rfc::blake2b::blake2b(8, &[], data).as_bytes()); -} - -/// Do a Blake2 64-bit hash and return result. -pub fn blake2_64(data: &[u8]) -> [u8; 8] { - let mut r = [0; 8]; - blake2_64_into(data, &mut r); - r -} - -/// Do a XX 64-bit hash and place result in `dest`. -pub fn twox_64_into(data: &[u8], dest: &mut [u8; 8]) { - use ::core::hash::Hasher; - let mut h0 = twox_hash::XxHash::with_seed(0); - h0.write(data); - let r0 = h0.finish(); - use byteorder::{ByteOrder, LittleEndian}; - LittleEndian::write_u64(&mut dest[0..8], r0); -} - -/// Do a XX 64-bit hash and return result. -pub fn twox_64(data: &[u8]) -> [u8; 8] { - let mut r: [u8; 8] = [0; 8]; - twox_64_into(data, &mut r); - r -} - -/// Do a XX 128-bit hash and place result in `dest`. -pub fn twox_128_into(data: &[u8], dest: &mut [u8; 16]) { - use ::core::hash::Hasher; - let mut h0 = twox_hash::XxHash::with_seed(0); - let mut h1 = twox_hash::XxHash::with_seed(1); - h0.write(data); - h1.write(data); - let r0 = h0.finish(); - let r1 = h1.finish(); - use byteorder::{ByteOrder, LittleEndian}; - LittleEndian::write_u64(&mut dest[0..8], r0); - LittleEndian::write_u64(&mut dest[8..16], r1); -} - -/// Do a XX 128-bit hash and return result. -pub fn twox_128(data: &[u8]) -> [u8; 16] { - let mut r: [u8; 16] = [0; 16]; - twox_128_into(data, &mut r); - r -} - -/// Do a XX 256-bit hash and place result in `dest`. -pub fn twox_256_into(data: &[u8], dest: &mut [u8; 32]) { - use ::core::hash::Hasher; - use byteorder::{ByteOrder, LittleEndian}; - let mut h0 = twox_hash::XxHash::with_seed(0); - let mut h1 = twox_hash::XxHash::with_seed(1); - let mut h2 = twox_hash::XxHash::with_seed(2); - let mut h3 = twox_hash::XxHash::with_seed(3); - h0.write(data); - h1.write(data); - h2.write(data); - h3.write(data); - let r0 = h0.finish(); - let r1 = h1.finish(); - let r2 = h2.finish(); - let r3 = h3.finish(); - LittleEndian::write_u64(&mut dest[0..8], r0); - LittleEndian::write_u64(&mut dest[8..16], r1); - LittleEndian::write_u64(&mut dest[16..24], r2); - LittleEndian::write_u64(&mut dest[24..32], r3); -} - -/// Do a XX 256-bit hash and return result. -pub fn twox_256(data: &[u8]) -> [u8; 32] { - let mut r: [u8; 32] = [0; 32]; - twox_256_into(data, &mut r); - r -} - -/// Do a keccak 256-bit hash and return result. -pub fn keccak_256(data: &[u8]) -> [u8; 32] { - let mut keccak = Keccak::v256(); - keccak.update(data); - let mut output = [0u8; 32]; - keccak.finalize(&mut output); - output -} - -/// Do a sha2 256-bit hash and return result. -pub fn sha2_256(data: &[u8]) -> [u8; 32] { - let mut hasher = Sha256::new(); - hasher.input(data); - let mut output = [0u8; 32]; - output.copy_from_slice(&hasher.result()); - output -} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/hexdisplay.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/hexdisplay.rs deleted file mode 100644 index 9d2b7a12..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/hexdisplay.rs +++ /dev/null @@ -1,104 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Wrapper type for byte collections that outputs hex. - -/// Simple wrapper to display hex representation of bytes. -pub struct HexDisplay<'a>(&'a [u8]); - -impl<'a> HexDisplay<'a> { - /// Create new instance that will display `d` as a hex string when displayed. - pub fn from(d: &'a R) -> Self { HexDisplay(d.as_bytes_ref()) } -} - -impl<'a> sp_std::fmt::Display for HexDisplay<'a> { - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> Result<(), sp_std::fmt::Error> { - if self.0.len() < 1027 { - for byte in self.0 { - f.write_fmt(format_args!("{:02x}", byte))?; - } - } else { - for byte in &self.0[0..512] { - f.write_fmt(format_args!("{:02x}", byte))?; - } - f.write_str("...")?; - for byte in &self.0[self.0.len() - 512..] { - f.write_fmt(format_args!("{:02x}", byte))?; - } - } - Ok(()) - } -} - -impl<'a> sp_std::fmt::Debug for HexDisplay<'a> { - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> Result<(), sp_std::fmt::Error> { - for byte in self.0 { - f.write_fmt(format_args!("{:02x}", byte))?; - } - Ok(()) - } -} - -/// Simple trait to transform various types to `&[u8]` -pub trait AsBytesRef { - /// Transform `self` into `&[u8]`. - fn as_bytes_ref(&self) -> &[u8]; -} - -impl AsBytesRef for &[u8] { - fn as_bytes_ref(&self) -> &[u8] { self } -} - -impl AsBytesRef for [u8] { - fn as_bytes_ref(&self) -> &[u8] { &self } -} - -impl AsBytesRef for sp_std::vec::Vec { - fn as_bytes_ref(&self) -> &[u8] { &self } -} - -macro_rules! impl_non_endians { - ( $( $t:ty ),* ) => { $( - impl AsBytesRef for $t { - fn as_bytes_ref(&self) -> &[u8] { &self[..] } - } - )* } -} - -impl_non_endians!([u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8], - [u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40], - [u8; 48], [u8; 56], [u8; 64], [u8; 65], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); - -/// Format into ASCII + # + hex, suitable for storage key preimages. -#[cfg(feature = "std")] -pub fn ascii_format(asciish: &[u8]) -> String { - let mut r = String::new(); - let mut latch = false; - for c in asciish { - match (latch, *c) { - (false, 32..=127) => r.push(*c as char), - _ => { - if !latch { - r.push('#'); - latch = true; - } - r.push_str(&format!("{:02x}", *c)); - } - } - } - r -} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/lib.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/lib.rs deleted file mode 100644 index 94f6bb29..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/lib.rs +++ /dev/null @@ -1,390 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Shareable Substrate types. - -#![warn(missing_docs)] - -#![cfg_attr(not(feature = "std"), no_std)] - -/// Initialize a key-value collection from array. -/// -/// Creates a vector of given pairs and calls `collect` on the iterator from it. -/// Can be used to create a `HashMap`. -#[macro_export] -macro_rules! map { - ($( $name:expr => $value:expr ),* $(,)? ) => ( - vec![ $( ( $name, $value ) ),* ].into_iter().collect() - ); -} - -use sp_runtime_interface::pass_by::{PassByEnum, PassByInner}; -use sp_std::prelude::*; -use sp_std::ops::Deref; -#[cfg(feature = "std")] -use std::borrow::Cow; -#[cfg(feature = "std")] -use serde::{Serialize, Deserialize}; -#[cfg(feature = "std")] -pub use serde; -#[doc(hidden)] -pub use codec::{Encode, Decode}; - -pub use sp_debug_derive::RuntimeDebug; - -#[cfg(feature = "std")] -pub use impl_serde::serialize as bytes; - -#[cfg(feature = "full_crypto")] -pub mod hashing; - -#[cfg(feature = "full_crypto")] -pub use hashing::{blake2_128, blake2_256, twox_64, twox_128, twox_256, keccak_256}; -pub mod hexdisplay; -pub mod crypto; - -pub mod u32_trait; - -pub mod ed25519; -pub mod sr25519; -pub mod ecdsa; -pub mod hash; -#[cfg(feature = "std")] -mod hasher; -pub mod offchain; -pub mod sandbox; -pub mod uint; -mod changes_trie; -#[cfg(feature = "std")] -pub mod traits; -pub mod testing; -#[cfg(feature = "std")] -pub mod vrf; - -pub use self::hash::{H160, H256, H512, convert_hash}; -pub use self::uint::{U256, U512}; -pub use changes_trie::{ChangesTrieConfiguration, ChangesTrieConfigurationRange}; -#[cfg(feature = "full_crypto")] -pub use crypto::{DeriveJunction, Pair, Public}; - -pub use hash_db::Hasher; -#[cfg(feature = "std")] -pub use self::hasher::blake2::Blake2Hasher; -#[cfg(feature = "std")] -pub use self::hasher::keccak::KeccakHasher; - -pub use sp_storage as storage; - -#[doc(hidden)] -pub use sp_std; - -/// Context for executing a call into the runtime. -pub enum ExecutionContext { - /// Context used for general block import (including locally authored blocks). - Importing, - /// Context used for importing blocks as part of an initial sync of the blockchain. - /// - /// We distinguish between major sync and import so that validators who are running - /// their initial sync (or catching up after some time offline) can use the faster - /// native runtime (since we can reasonably assume the network as a whole has already - /// come to a broad conensus on the block and it probably hasn't been crafted - /// specifically to attack this node), but when importing blocks at the head of the - /// chain in normal operation they can use the safer Wasm version. - Syncing, - /// Context used for block construction. - BlockConstruction, - /// Context used for offchain calls. - /// - /// This allows passing offchain extension and customizing available capabilities. - OffchainCall(Option<(Box, offchain::Capabilities)>), -} - -impl ExecutionContext { - /// Returns the capabilities of particular context. - pub fn capabilities(&self) -> offchain::Capabilities { - use ExecutionContext::*; - - match self { - Importing | Syncing | BlockConstruction => - offchain::Capabilities::none(), - // Enable keystore and transaction pool by default for offchain calls. - OffchainCall(None) => [ - offchain::Capability::Keystore, - offchain::Capability::TransactionPool, - ][..].into(), - OffchainCall(Some((_, capabilities))) => *capabilities, - } - } -} - -/// Hex-serialized shim for `Vec`. -#[derive(PartialEq, Eq, Clone, RuntimeDebug)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash, PartialOrd, Ord))] -pub struct Bytes(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec); - -impl From> for Bytes { - fn from(s: Vec) -> Self { Bytes(s) } -} - -impl From for Bytes { - fn from(s: OpaqueMetadata) -> Self { Bytes(s.0) } -} - -impl Deref for Bytes { - type Target = [u8]; - fn deref(&self) -> &[u8] { &self.0[..] } -} - -#[cfg(feature = "std")] -impl sp_std::str::FromStr for Bytes { - type Err = bytes::FromHexError; - - fn from_str(s: &str) -> Result { - bytes::from_hex(s).map(Bytes) - } -} - -/// Stores the encoded `RuntimeMetadata` for the native side as opaque type. -#[derive(Encode, Decode, PartialEq)] -pub struct OpaqueMetadata(Vec); - -impl OpaqueMetadata { - /// Creates a new instance with the given metadata blob. - pub fn new(metadata: Vec) -> Self { - OpaqueMetadata(metadata) - } -} - -impl sp_std::ops::Deref for OpaqueMetadata { - type Target = Vec; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -/// Simple blob to hold a `PeerId` without committing to its format. -#[derive(Default, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, PassByInner)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct OpaquePeerId(pub Vec); - -impl OpaquePeerId { - /// Create new `OpaquePeerId` - pub fn new(vec: Vec) -> Self { - OpaquePeerId(vec) - } -} - -/// Something that is either a native or an encoded value. -#[cfg(feature = "std")] -pub enum NativeOrEncoded { - /// The native representation. - Native(R), - /// The encoded representation. - Encoded(Vec) -} - -#[cfg(feature = "std")] -impl sp_std::fmt::Debug for NativeOrEncoded { - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - hexdisplay::HexDisplay::from(&self.as_encoded().as_ref()).fmt(f) - } -} - -#[cfg(feature = "std")] -impl NativeOrEncoded { - /// Return the value as the encoded format. - pub fn as_encoded(&self) -> Cow<'_, [u8]> { - match self { - NativeOrEncoded::Encoded(e) => Cow::Borrowed(e.as_slice()), - NativeOrEncoded::Native(n) => Cow::Owned(n.encode()), - } - } - - /// Return the value as the encoded format. - pub fn into_encoded(self) -> Vec { - match self { - NativeOrEncoded::Encoded(e) => e, - NativeOrEncoded::Native(n) => n.encode(), - } - } -} - -#[cfg(feature = "std")] -impl PartialEq for NativeOrEncoded { - fn eq(&self, other: &Self) -> bool { - match (self, other) { - (NativeOrEncoded::Native(l), NativeOrEncoded::Native(r)) => l == r, - (NativeOrEncoded::Native(n), NativeOrEncoded::Encoded(e)) | - (NativeOrEncoded::Encoded(e), NativeOrEncoded::Native(n)) => - Some(n) == codec::Decode::decode(&mut &e[..]).ok().as_ref(), - (NativeOrEncoded::Encoded(l), NativeOrEncoded::Encoded(r)) => l == r, - } - } -} - -/// A value that is never in a native representation. -/// This is type is useful in conjunction with `NativeOrEncoded`. -#[cfg(feature = "std")] -#[derive(PartialEq)] -pub enum NeverNativeValue {} - -#[cfg(feature = "std")] -impl codec::Encode for NeverNativeValue { - fn encode(&self) -> Vec { - // The enum is not constructable, so this function should never be callable! - unreachable!() - } -} - -#[cfg(feature = "std")] -impl codec::EncodeLike for NeverNativeValue {} - -#[cfg(feature = "std")] -impl codec::Decode for NeverNativeValue { - fn decode(_: &mut I) -> Result { - Err("`NeverNativeValue` should never be decoded".into()) - } -} - -/// Provide a simple 4 byte identifier for a type. -pub trait TypeId { - /// Simple 4 byte identifier. - const TYPE_ID: [u8; 4]; -} - -/// A log level matching the one from `log` crate. -/// -/// Used internally by `sp_io::log` method. -#[derive(Encode, Decode, PassByEnum, Copy, Clone)] -pub enum LogLevel { - /// `Error` log level. - Error = 1, - /// `Warn` log level. - Warn = 2, - /// `Info` log level. - Info = 3, - /// `Debug` log level. - Debug = 4, - /// `Trace` log level. - Trace = 5, -} - -impl From for LogLevel { - fn from(val: u32) -> Self { - match val { - x if x == LogLevel::Warn as u32 => LogLevel::Warn, - x if x == LogLevel::Info as u32 => LogLevel::Info, - x if x == LogLevel::Debug as u32 => LogLevel::Debug, - x if x == LogLevel::Trace as u32 => LogLevel::Trace, - _ => LogLevel::Error, - } - } -} - -impl From for LogLevel { - fn from(l: log::Level) -> Self { - use log::Level::*; - match l { - Error => Self::Error, - Warn => Self::Warn, - Info => Self::Info, - Debug => Self::Debug, - Trace => Self::Trace, - } - } -} - -impl From for log::Level { - fn from(l: LogLevel) -> Self { - use self::LogLevel::*; - match l { - Error => Self::Error, - Warn => Self::Warn, - Info => Self::Info, - Debug => Self::Debug, - Trace => Self::Trace, - } - } -} - -/// Encodes the given value into a buffer and returns the pointer and the length as a single `u64`. -/// -/// When Substrate calls into Wasm it expects a fixed signature for functions exported -/// from the Wasm blob. The return value of this signature is always a `u64`. -/// This `u64` stores the pointer to the encoded return value and the length of this encoded value. -/// The low `32bits` are reserved for the pointer, followed by `32bit` for the length. -#[cfg(not(feature = "std"))] -pub fn to_substrate_wasm_fn_return_value(value: &impl Encode) -> u64 { - let encoded = value.encode(); - - let ptr = encoded.as_ptr() as u64; - let length = encoded.len() as u64; - let res = ptr | (length << 32); - - // Leak the output vector to avoid it being freed. - // This is fine in a WASM context since the heap - // will be discarded after the call. - sp_std::mem::forget(encoded); - - res -} - -/// The void type - it cannot exist. -// Oh rust, you crack me up... -#[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebug)] -pub enum Void {} - -/// Macro for creating `Maybe*` marker traits. -/// -/// Such a maybe-marker trait requires the given bound when `feature = std` and doesn't require -/// the bound on `no_std`. This is useful for situations where you require that a type implements -/// a certain trait with `feature = std`, but not on `no_std`. -/// -/// # Example -/// -/// ``` -/// sp_core::impl_maybe_marker! { -/// /// A marker for a type that implements `Debug` when `feature = std`. -/// trait MaybeDebug: std::fmt::Debug; -/// /// A marker for a type that implements `Debug + Display` when `feature = std`. -/// trait MaybeDebugDisplay: std::fmt::Debug, std::fmt::Display; -/// } -/// ``` -#[macro_export] -macro_rules! impl_maybe_marker { - ( - $( - $(#[$doc:meta] )+ - trait $trait_name:ident: $( $trait_bound:path ),+; - )+ - ) => { - $( - $(#[$doc])+ - #[cfg(feature = "std")] - pub trait $trait_name: $( $trait_bound + )+ {} - #[cfg(feature = "std")] - impl $trait_name for T {} - - $(#[$doc])+ - #[cfg(not(feature = "std"))] - pub trait $trait_name {} - #[cfg(not(feature = "std"))] - impl $trait_name for T {} - )+ - } -} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/mod.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/mod.rs deleted file mode 100644 index 4768496c..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/mod.rs +++ /dev/null @@ -1,775 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Offchain workers types - -use codec::{Encode, Decode}; -use sp_std::{prelude::{Vec, Box}, convert::TryFrom}; -use crate::{OpaquePeerId, RuntimeDebug}; -use sp_runtime_interface::pass_by::{PassByCodec, PassByInner, PassByEnum}; - -pub use crate::crypto::KeyTypeId; - -#[cfg(feature = "std")] -pub mod storage; -#[cfg(feature = "std")] -pub mod testing; - -/// Local storage prefix used by the Offchain Worker API to -pub const STORAGE_PREFIX : &'static [u8] = b"storage"; - -/// Offchain workers local storage. -pub trait OffchainStorage: Clone + Send + Sync { - /// Persist a value in storage under given key and prefix. - fn set(&mut self, prefix: &[u8], key: &[u8], value: &[u8]); - - /// Clear a storage entry under given key and prefix. - fn remove(&mut self, prefix: &[u8], key: &[u8]); - - /// Retrieve a value from storage under given key and prefix. - fn get(&self, prefix: &[u8], key: &[u8]) -> Option>; - - /// Replace the value in storage if given old_value matches the current one. - /// - /// Returns `true` if the value has been set and false otherwise. - fn compare_and_set( - &mut self, - prefix: &[u8], - key: &[u8], - old_value: Option<&[u8]>, - new_value: &[u8], - ) -> bool; -} - -/// A type of supported crypto. -#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, RuntimeDebug, PassByEnum)] -#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] -#[repr(C)] -pub enum StorageKind { - /// Persistent storage is non-revertible and not fork-aware. It means that any value - /// set by the offchain worker triggered at block `N(hash1)` is persisted even - /// if that block is reverted as non-canonical and is available for the worker - /// that is re-run at block `N(hash2)`. - /// This storage can be used by offchain workers to handle forks - /// and coordinate offchain workers running on different forks. - PERSISTENT = 1, - /// Local storage is revertible and fork-aware. It means that any value - /// set by the offchain worker triggered at block `N(hash1)` is reverted - /// if that block is reverted as non-canonical and is NOT available for the worker - /// that is re-run at block `N(hash2)`. - LOCAL = 2, -} - -impl TryFrom for StorageKind { - type Error = (); - - fn try_from(kind: u32) -> Result { - match kind { - e if e == u32::from(StorageKind::PERSISTENT as u8) => Ok(StorageKind::PERSISTENT), - e if e == u32::from(StorageKind::LOCAL as u8) => Ok(StorageKind::LOCAL), - _ => Err(()), - } - } -} - -impl From for u32 { - fn from(c: StorageKind) -> Self { - c as u8 as u32 - } -} - -/// Opaque type for offchain http requests. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, Encode, Decode, PassByInner)] -#[cfg_attr(feature = "std", derive(Hash))] -pub struct HttpRequestId(pub u16); - -impl From for u32 { - fn from(c: HttpRequestId) -> Self { - c.0 as u32 - } -} - -/// An error enum returned by some http methods. -#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug, Encode, Decode, PassByEnum)] -#[repr(C)] -pub enum HttpError { - /// The requested action couldn't been completed within a deadline. - DeadlineReached = 1, - /// There was an IO Error while processing the request. - IoError = 2, - /// The ID of the request is invalid in this context. - Invalid = 3, -} - -impl TryFrom for HttpError { - type Error = (); - - fn try_from(error: u32) -> Result { - match error { - e if e == HttpError::DeadlineReached as u8 as u32 => Ok(HttpError::DeadlineReached), - e if e == HttpError::IoError as u8 as u32 => Ok(HttpError::IoError), - e if e == HttpError::Invalid as u8 as u32 => Ok(HttpError::Invalid), - _ => Err(()) - } - } -} - -impl From for u32 { - fn from(c: HttpError) -> Self { - c as u8 as u32 - } -} - -/// Status of the HTTP request -#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug, Encode, Decode, PassByCodec)] -pub enum HttpRequestStatus { - /// Deadline was reached while we waited for this request to finish. - /// - /// Note the deadline is controlled by the calling part, it not necessarily - /// means that the request has timed out. - DeadlineReached, - /// An error has occurred during the request, for example a timeout or the - /// remote has closed our socket. - /// - /// The request is now considered destroyed. To retry the request you need - /// to construct it again. - IoError, - /// The passed ID is invalid in this context. - Invalid, - /// The request has finished with given status code. - Finished(u16), -} - -impl From for u32 { - fn from(status: HttpRequestStatus) -> Self { - match status { - HttpRequestStatus::Invalid => 0, - HttpRequestStatus::DeadlineReached => 10, - HttpRequestStatus::IoError => 20, - HttpRequestStatus::Finished(code) => u32::from(code), - } - } -} - -impl TryFrom for HttpRequestStatus { - type Error = (); - - fn try_from(status: u32) -> Result { - match status { - 0 => Ok(HttpRequestStatus::Invalid), - 10 => Ok(HttpRequestStatus::DeadlineReached), - 20 => Ok(HttpRequestStatus::IoError), - 100..=999 => u16::try_from(status).map(HttpRequestStatus::Finished).map_err(|_| ()), - _ => Err(()), - } - } -} - -/// A blob to hold information about the local node's network state -/// without committing to its format. -#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, PassByCodec)] -#[cfg_attr(feature = "std", derive(Default))] -pub struct OpaqueNetworkState { - /// PeerId of the local node in SCALE encoded. - pub peer_id: OpaquePeerId, - /// List of addresses the node knows it can be reached as. - pub external_addresses: Vec, -} - -/// Simple blob to hold a `Multiaddr` without committing to its format. -#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, PassByInner)] -pub struct OpaqueMultiaddr(pub Vec); - -impl OpaqueMultiaddr { - /// Create new `OpaqueMultiaddr` - pub fn new(vec: Vec) -> Self { - OpaqueMultiaddr(vec) - } -} - -/// Opaque timestamp type -#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default, RuntimeDebug, PassByInner, Encode, Decode)] -pub struct Timestamp(u64); - -/// Duration type -#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default, RuntimeDebug, PassByInner, Encode, Decode)] -pub struct Duration(u64); - -impl Duration { - /// Create new duration representing given number of milliseconds. - pub const fn from_millis(millis: u64) -> Self { - Duration(millis) - } - - /// Returns number of milliseconds this Duration represents. - pub fn millis(&self) -> u64 { - self.0 - } -} - -impl Timestamp { - /// Creates new `Timestamp` given unix timestamp in milliseconds. - pub fn from_unix_millis(millis: u64) -> Self { - Timestamp(millis) - } - - /// Increase the timestamp by given `Duration`. - pub fn add(&self, duration: Duration) -> Timestamp { - Timestamp(self.0.saturating_add(duration.0)) - } - - /// Decrease the timestamp by given `Duration` - pub fn sub(&self, duration: Duration) -> Timestamp { - Timestamp(self.0.saturating_sub(duration.0)) - } - - /// Returns a saturated difference (Duration) between two Timestamps. - pub fn diff(&self, other: &Self) -> Duration { - Duration(self.0.saturating_sub(other.0)) - } - - /// Return number of milliseconds since UNIX epoch. - pub fn unix_millis(&self) -> u64 { - self.0 - } -} - -/// Execution context extra capabilities. -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -#[repr(u8)] -pub enum Capability { - /// Access to transaction pool. - TransactionPool = 1, - /// External http calls. - Http = 2, - /// Keystore access. - Keystore = 4, - /// Randomness source. - Randomness = 8, - /// Access to opaque network state. - NetworkState = 16, - /// Access to offchain worker DB (read only). - OffchainWorkerDbRead = 32, - /// Access to offchain worker DB (writes). - OffchainWorkerDbWrite = 64, - /// Manage the authorized nodes - NodeAuthorization = 128, -} - -/// A set of capabilities -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub struct Capabilities(u8); - -impl Capabilities { - /// Return an object representing an empty set of capabilities. - pub fn none() -> Self { - Self(0) - } - - /// Return an object representing all capabilities enabled. - pub fn all() -> Self { - Self(u8::max_value()) - } - - /// Return capabilities for rich offchain calls. - /// - /// Those calls should be allowed to sign and submit transactions - /// and access offchain workers database (but read only!). - pub fn rich_offchain_call() -> Self { - [ - Capability::TransactionPool, - Capability::Keystore, - Capability::OffchainWorkerDbRead, - ][..].into() - } - - /// Check if particular capability is enabled. - pub fn has(&self, capability: Capability) -> bool { - self.0 & capability as u8 != 0 - } - - /// Check if this capability object represents all capabilities. - pub fn has_all(&self) -> bool { - self == &Capabilities::all() - } -} - -impl<'a> From<&'a [Capability]> for Capabilities { - fn from(list: &'a [Capability]) -> Self { - Capabilities(list.iter().fold(0_u8, |a, b| a | *b as u8)) - } -} - -/// An extended externalities for offchain workers. -pub trait Externalities: Send { - /// Returns if the local node is a potential validator. - /// - /// Even if this function returns `true`, it does not mean that any keys are configured - /// and that the validator is registered in the chain. - fn is_validator(&self) -> bool; - - /// Returns information about the local node's network state. - fn network_state(&self) -> Result; - - /// Returns current UNIX timestamp (in millis) - fn timestamp(&mut self) -> Timestamp; - - /// Pause the execution until `deadline` is reached. - fn sleep_until(&mut self, deadline: Timestamp); - - /// Returns a random seed. - /// - /// This is a truly random non deterministic seed generated by host environment. - /// Obviously fine in the off-chain worker context. - fn random_seed(&mut self) -> [u8; 32]; - - /// Sets a value in the local storage. - /// - /// Note this storage is not part of the consensus, it's only accessible by - /// offchain worker tasks running on the same machine. It _is_ persisted between runs. - fn local_storage_set(&mut self, kind: StorageKind, key: &[u8], value: &[u8]); - - /// Removes a value in the local storage. - /// - /// Note this storage is not part of the consensus, it's only accessible by - /// offchain worker tasks running on the same machine. It _is_ persisted between runs. - fn local_storage_clear(&mut self, kind: StorageKind, key: &[u8]); - - /// Sets a value in the local storage if it matches current value. - /// - /// Since multiple offchain workers may be running concurrently, to prevent - /// data races use CAS to coordinate between them. - /// - /// Returns `true` if the value has been set, `false` otherwise. - /// - /// Note this storage is not part of the consensus, it's only accessible by - /// offchain worker tasks running on the same machine. It _is_ persisted between runs. - fn local_storage_compare_and_set( - &mut self, - kind: StorageKind, - key: &[u8], - old_value: Option<&[u8]>, - new_value: &[u8], - ) -> bool; - - /// Gets a value from the local storage. - /// - /// If the value does not exist in the storage `None` will be returned. - /// Note this storage is not part of the consensus, it's only accessible by - /// offchain worker tasks running on the same machine. It _is_ persisted between runs. - fn local_storage_get(&mut self, kind: StorageKind, key: &[u8]) -> Option>; - - /// Initiates a http request given HTTP verb and the URL. - /// - /// Meta is a future-reserved field containing additional, parity-scale-codec encoded parameters. - /// Returns the id of newly started request. - /// - /// Returns an error if: - /// - No new request identifier could be allocated. - /// - The method or URI contain invalid characters. - /// - fn http_request_start( - &mut self, - method: &str, - uri: &str, - meta: &[u8] - ) -> Result; - - /// Append header to the request. - /// - /// Calling this function multiple times with the same header name continues appending new - /// headers. In other words, headers are never replaced. - /// - /// Returns an error if: - /// - The request identifier is invalid. - /// - You have called `http_request_write_body` on that request. - /// - The name or value contain invalid characters. - /// - /// An error doesn't poison the request, and you can continue as if the call had never been - /// made. - /// - fn http_request_add_header( - &mut self, - request_id: HttpRequestId, - name: &str, - value: &str - ) -> Result<(), ()>; - - /// Write a chunk of request body. - /// - /// Calling this function with a non-empty slice may or may not start the - /// HTTP request. Calling this function with an empty chunks finalizes the - /// request and always starts it. It is no longer valid to write more data - /// afterwards. - /// Passing `None` as deadline blocks forever. - /// - /// Returns an error if: - /// - The request identifier is invalid. - /// - `http_response_wait` has already been called on this request. - /// - The deadline is reached. - /// - An I/O error has happened, for example the remote has closed our - /// request. The request is then considered invalid. - /// - fn http_request_write_body( - &mut self, - request_id: HttpRequestId, - chunk: &[u8], - deadline: Option - ) -> Result<(), HttpError>; - - /// Block and wait for the responses for given requests. - /// - /// Returns a vector of request statuses (the len is the same as ids). - /// Note that if deadline is not provided the method will block indefinitely, - /// otherwise unready responses will produce `DeadlineReached` status. - /// - /// If a response returns an `IoError`, it is then considered destroyed. - /// Its id is then invalid. - /// - /// Passing `None` as deadline blocks forever. - fn http_response_wait( - &mut self, - ids: &[HttpRequestId], - deadline: Option - ) -> Vec; - - /// Read all response headers. - /// - /// Returns a vector of pairs `(HeaderKey, HeaderValue)`. - /// - /// Dispatches the request if it hasn't been done yet. It is no longer - /// valid to modify the headers or write data to the request. - /// - /// Returns an empty list if the identifier is unknown/invalid, hasn't - /// received a response, or has finished. - fn http_response_headers( - &mut self, - request_id: HttpRequestId - ) -> Vec<(Vec, Vec)>; - - /// Read a chunk of body response to given buffer. - /// - /// Dispatches the request if it hasn't been done yet. It is no longer - /// valid to modify the headers or write data to the request. - /// - /// Returns the number of bytes written or an error in case a deadline - /// is reached or server closed the connection. - /// Passing `None` as a deadline blocks forever. - /// - /// If `Ok(0)` or `Err(IoError)` is returned, the request is considered - /// destroyed. Doing another read or getting the response's headers, for - /// example, is then invalid. - /// - /// Returns an error if: - /// - The request identifier is invalid. - /// - The deadline is reached. - /// - An I/O error has happened, for example the remote has closed our - /// request. The request is then considered invalid. - /// - fn http_response_read_body( - &mut self, - request_id: HttpRequestId, - buffer: &mut [u8], - deadline: Option - ) -> Result; - - /// Set the authorized nodes from runtime. - /// - /// In a permissioned network, the connections between nodes need to reach a - /// consensus between participants. - /// - /// - `nodes`: a set of nodes which are allowed to connect for the local node. - /// each one is identified with an `OpaquePeerId`, here it just use plain bytes - /// without any encoding. Invalid `OpaquePeerId`s are silently ignored. - /// - `authorized_only`: if true, only the authorized nodes are allowed to connect, - /// otherwise unauthorized nodes can also be connected through other mechanism. - fn set_authorized_nodes(&mut self, nodes: Vec, authorized_only: bool); -} - -impl Externalities for Box { - fn is_validator(&self) -> bool { - (& **self).is_validator() - } - - fn network_state(&self) -> Result { - (& **self).network_state() - } - - fn timestamp(&mut self) -> Timestamp { - (&mut **self).timestamp() - } - - fn sleep_until(&mut self, deadline: Timestamp) { - (&mut **self).sleep_until(deadline) - } - - fn random_seed(&mut self) -> [u8; 32] { - (&mut **self).random_seed() - } - - fn local_storage_set(&mut self, kind: StorageKind, key: &[u8], value: &[u8]) { - (&mut **self).local_storage_set(kind, key, value) - } - - fn local_storage_clear(&mut self, kind: StorageKind, key: &[u8]) { - (&mut **self).local_storage_clear(kind, key) - } - - fn local_storage_compare_and_set( - &mut self, - kind: StorageKind, - key: &[u8], - old_value: Option<&[u8]>, - new_value: &[u8], - ) -> bool { - (&mut **self).local_storage_compare_and_set(kind, key, old_value, new_value) - } - - fn local_storage_get(&mut self, kind: StorageKind, key: &[u8]) -> Option> { - (&mut **self).local_storage_get(kind, key) - } - - fn http_request_start(&mut self, method: &str, uri: &str, meta: &[u8]) -> Result { - (&mut **self).http_request_start(method, uri, meta) - } - - fn http_request_add_header(&mut self, request_id: HttpRequestId, name: &str, value: &str) -> Result<(), ()> { - (&mut **self).http_request_add_header(request_id, name, value) - } - - fn http_request_write_body( - &mut self, - request_id: HttpRequestId, - chunk: &[u8], - deadline: Option - ) -> Result<(), HttpError> { - (&mut **self).http_request_write_body(request_id, chunk, deadline) - } - - fn http_response_wait(&mut self, ids: &[HttpRequestId], deadline: Option) -> Vec { - (&mut **self).http_response_wait(ids, deadline) - } - - fn http_response_headers(&mut self, request_id: HttpRequestId) -> Vec<(Vec, Vec)> { - (&mut **self).http_response_headers(request_id) - } - - fn http_response_read_body( - &mut self, - request_id: HttpRequestId, - buffer: &mut [u8], - deadline: Option - ) -> Result { - (&mut **self).http_response_read_body(request_id, buffer, deadline) - } - - fn set_authorized_nodes(&mut self, nodes: Vec, authorized_only: bool) { - (&mut **self).set_authorized_nodes(nodes, authorized_only) - } -} - -/// An `OffchainExternalities` implementation with limited capabilities. -pub struct LimitedExternalities { - capabilities: Capabilities, - externalities: T, -} - -impl LimitedExternalities { - /// Create new externalities limited to given `capabilities`. - pub fn new(capabilities: Capabilities, externalities: T) -> Self { - Self { - capabilities, - externalities, - } - } - - /// Check if given capability is allowed. - /// - /// Panics in case it is not. - fn check(&self, capability: Capability, name: &'static str) { - if !self.capabilities.has(capability) { - panic!("Accessing a forbidden API: {}. No: {:?} capability.", name, capability); - } - } -} - -impl Externalities for LimitedExternalities { - fn is_validator(&self) -> bool { - self.check(Capability::Keystore, "is_validator"); - self.externalities.is_validator() - } - - fn network_state(&self) -> Result { - self.check(Capability::NetworkState, "network_state"); - self.externalities.network_state() - } - - fn timestamp(&mut self) -> Timestamp { - self.check(Capability::Http, "timestamp"); - self.externalities.timestamp() - } - - fn sleep_until(&mut self, deadline: Timestamp) { - self.check(Capability::Http, "sleep_until"); - self.externalities.sleep_until(deadline) - } - - fn random_seed(&mut self) -> [u8; 32] { - self.check(Capability::Randomness, "random_seed"); - self.externalities.random_seed() - } - - fn local_storage_set(&mut self, kind: StorageKind, key: &[u8], value: &[u8]) { - self.check(Capability::OffchainWorkerDbWrite, "local_storage_set"); - self.externalities.local_storage_set(kind, key, value) - } - - fn local_storage_clear(&mut self, kind: StorageKind, key: &[u8]) { - self.check(Capability::OffchainWorkerDbWrite, "local_storage_clear"); - self.externalities.local_storage_clear(kind, key) - } - - fn local_storage_compare_and_set( - &mut self, - kind: StorageKind, - key: &[u8], - old_value: Option<&[u8]>, - new_value: &[u8], - ) -> bool { - self.check(Capability::OffchainWorkerDbWrite, "local_storage_compare_and_set"); - self.externalities.local_storage_compare_and_set(kind, key, old_value, new_value) - } - - fn local_storage_get(&mut self, kind: StorageKind, key: &[u8]) -> Option> { - self.check(Capability::OffchainWorkerDbRead, "local_storage_get"); - self.externalities.local_storage_get(kind, key) - } - - fn http_request_start(&mut self, method: &str, uri: &str, meta: &[u8]) -> Result { - self.check(Capability::Http, "http_request_start"); - self.externalities.http_request_start(method, uri, meta) - } - - fn http_request_add_header(&mut self, request_id: HttpRequestId, name: &str, value: &str) -> Result<(), ()> { - self.check(Capability::Http, "http_request_add_header"); - self.externalities.http_request_add_header(request_id, name, value) - } - - fn http_request_write_body( - &mut self, - request_id: HttpRequestId, - chunk: &[u8], - deadline: Option - ) -> Result<(), HttpError> { - self.check(Capability::Http, "http_request_write_body"); - self.externalities.http_request_write_body(request_id, chunk, deadline) - } - - fn http_response_wait(&mut self, ids: &[HttpRequestId], deadline: Option) -> Vec { - self.check(Capability::Http, "http_response_wait"); - self.externalities.http_response_wait(ids, deadline) - } - - fn http_response_headers(&mut self, request_id: HttpRequestId) -> Vec<(Vec, Vec)> { - self.check(Capability::Http, "http_response_headers"); - self.externalities.http_response_headers(request_id) - } - - fn http_response_read_body( - &mut self, - request_id: HttpRequestId, - buffer: &mut [u8], - deadline: Option - ) -> Result { - self.check(Capability::Http, "http_response_read_body"); - self.externalities.http_response_read_body(request_id, buffer, deadline) - } - - fn set_authorized_nodes(&mut self, nodes: Vec, authorized_only: bool) { - self.check(Capability::NodeAuthorization, "set_authorized_nodes"); - self.externalities.set_authorized_nodes(nodes, authorized_only) - } -} - -#[cfg(feature = "std")] -sp_externalities::decl_extension! { - /// The offchain extension that will be registered at the Substrate externalities. - pub struct OffchainExt(Box); -} - -#[cfg(feature = "std")] -impl OffchainExt { - /// Create a new instance of `Self`. - pub fn new(offchain: O) -> Self { - Self(Box::new(offchain)) - } -} - -/// Abstraction over transaction pool. -/// -/// This trait is currently used within the `ExternalitiesExtension` -/// to provide offchain calls with access to the transaction pool without -/// tight coupling with any pool implementation. -#[cfg(feature = "std")] -pub trait TransactionPool { - /// Submit transaction. - /// - /// The transaction will end up in the pool and be propagated to others. - fn submit_transaction(&mut self, extrinsic: Vec) -> Result<(), ()>; -} - -#[cfg(feature = "std")] -sp_externalities::decl_extension! { - /// An externalities extension to submit transactions to the pool. - pub struct TransactionPoolExt(Box); -} - -#[cfg(feature = "std")] -impl TransactionPoolExt { - /// Create a new instance of `TransactionPoolExt`. - pub fn new(pool: O) -> Self { - Self(Box::new(pool)) - } -} - - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn timestamp_ops() { - let t = Timestamp(5); - assert_eq!(t.add(Duration::from_millis(10)), Timestamp(15)); - assert_eq!(t.sub(Duration::from_millis(10)), Timestamp(0)); - assert_eq!(t.diff(&Timestamp(3)), Duration(2)); - } - - #[test] - fn capabilities() { - let none = Capabilities::none(); - let all = Capabilities::all(); - let some = Capabilities::from(&[Capability::Keystore, Capability::Randomness][..]); - - assert!(!none.has(Capability::Keystore)); - assert!(all.has(Capability::Keystore)); - assert!(some.has(Capability::Keystore)); - assert!(!none.has(Capability::TransactionPool)); - assert!(all.has(Capability::TransactionPool)); - assert!(!some.has(Capability::TransactionPool)); - } -} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/storage.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/storage.rs deleted file mode 100644 index 7d7c711e..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/storage.rs +++ /dev/null @@ -1,297 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! In-memory implementation of offchain workers database. - -use std::collections::hash_map::{HashMap, Entry}; -use crate::offchain::OffchainStorage; -use std::iter::Iterator; - -/// In-memory storage for offchain workers. -#[derive(Debug, Clone, Default)] -pub struct InMemOffchainStorage { - storage: HashMap, Vec>, -} - -impl InMemOffchainStorage { - /// Consume the offchain storage and iterate over all key value pairs. - pub fn into_iter(self) -> impl Iterator,Vec)> { - self.storage.into_iter() - } - - /// Iterate over all key value pairs by reference. - pub fn iter<'a>(&'a self) -> impl Iterator,&'a Vec)> { - self.storage.iter() - } - - /// Remove a key and its associated value from the offchain database. - pub fn remove(&mut self, prefix: &[u8], key: &[u8]) { - let key: Vec = prefix.iter().chain(key).cloned().collect(); - let _ = self.storage.remove(&key); - } -} - -impl OffchainStorage for InMemOffchainStorage { - fn set(&mut self, prefix: &[u8], key: &[u8], value: &[u8]) { - let key = prefix.iter().chain(key).cloned().collect(); - self.storage.insert(key, value.to_vec()); - } - - fn remove(&mut self, prefix: &[u8], key: &[u8]) { - let key: Vec = prefix.iter().chain(key).cloned().collect(); - self.storage.remove(&key); - } - - fn get(&self, prefix: &[u8], key: &[u8]) -> Option> { - let key: Vec = prefix.iter().chain(key).cloned().collect(); - self.storage.get(&key).cloned() - } - - fn compare_and_set( - &mut self, - prefix: &[u8], - key: &[u8], - old_value: Option<&[u8]>, - new_value: &[u8], - ) -> bool { - let key = prefix.iter().chain(key).cloned().collect(); - - match self.storage.entry(key) { - Entry::Vacant(entry) => if old_value.is_none() { - entry.insert(new_value.to_vec()); - true - } else { false }, - Entry::Occupied(ref mut entry) if Some(entry.get().as_slice()) == old_value => { - entry.insert(new_value.to_vec()); - true - }, - _ => false, - } - } -} - - - - -/// Change to be applied to the offchain worker db in regards to a key. -#[derive(Debug,Clone,Hash,Eq,PartialEq)] -pub enum OffchainOverlayedChange { - /// Remove the data associated with the key - Remove, - /// Overwrite the value of an associated key - SetValue(Vec), -} - -/// In-memory storage for offchain workers recoding changes for the actual offchain storage implementation. -#[derive(Debug, Clone)] -pub enum OffchainOverlayedChanges { - /// Writing overlay changes to the offchain worker database is disabled by configuration. - Disabled, - /// Overlay changes can be recorded using the inner collection of this variant, - /// where the identifier is the tuple of `(prefix, key)`. - Enabled(HashMap<(Vec, Vec), OffchainOverlayedChange>), -} - -impl Default for OffchainOverlayedChanges { - fn default() -> Self { - Self::Disabled - } -} - -impl OffchainOverlayedChanges { - /// Create the disabled variant. - pub fn disabled() -> Self { - Self::Disabled - } - - /// Create the enabled variant. - pub fn enabled() -> Self { - Self::Enabled(HashMap::new()) - } - - /// Consume the offchain storage and iterate over all key value pairs. - pub fn into_iter(self) -> OffchainOverlayedChangesIntoIter { - OffchainOverlayedChangesIntoIter::new(self) - } - - /// Iterate over all key value pairs by reference. - pub fn iter<'a>(&'a self) -> OffchainOverlayedChangesIter { - OffchainOverlayedChangesIter::new(&self) - } - - /// Drain all elements of changeset. - pub fn drain<'a, 'd>(&'a mut self) -> OffchainOverlayedChangesDrain<'d> where 'a: 'd { - OffchainOverlayedChangesDrain::new(self) - } - - /// Remove a key and its associated value from the offchain database. - pub fn remove(&mut self, prefix: &[u8], key: &[u8]) { - if let Self::Enabled(ref mut storage) = self { - let _ = storage.insert((prefix.to_vec(), key.to_vec()), OffchainOverlayedChange::Remove); - } - } - - /// Set the value associated with a key under a prefix to the value provided. - pub fn set(&mut self, prefix: &[u8], key: &[u8], value: &[u8]) { - if let Self::Enabled(ref mut storage) = self { - let _ = storage.insert((prefix.to_vec(), key.to_vec()), OffchainOverlayedChange::SetValue(value.to_vec())); - } - } - - /// Obtain a associated value to the given key in storage with prefix. - pub fn get(&self, prefix: &[u8], key: &[u8]) -> Option { - if let Self::Enabled(ref storage) = self { - let key = (prefix.to_vec(), key.to_vec()); - storage.get(&key).cloned() - } else { - None - } - } -} - -use std::collections::hash_map; - -/// Iterate by reference over the prepared offchain worker storage changes. -pub struct OffchainOverlayedChangesIter<'i> { - inner: Option, Vec), OffchainOverlayedChange>>, -} - -impl<'i> Iterator for OffchainOverlayedChangesIter<'i> { - type Item = (&'i (Vec, Vec), &'i OffchainOverlayedChange); - fn next(&mut self) -> Option { - if let Some(ref mut iter) = self.inner { - iter.next() - } else { - None - } - } -} - -impl<'i> OffchainOverlayedChangesIter<'i> { - /// Create a new iterator based on a refernce to the parent container. - pub fn new(container: &'i OffchainOverlayedChanges) -> Self { - match container { - OffchainOverlayedChanges::Enabled(inner) => Self { - inner: Some(inner.iter()) - }, - OffchainOverlayedChanges::Disabled => Self { inner: None, }, - } - } -} - - -/// Iterate by value over the prepared offchain worker storage changes. -pub struct OffchainOverlayedChangesIntoIter { - inner: Option,Vec),OffchainOverlayedChange>>, -} - -impl Iterator for OffchainOverlayedChangesIntoIter { - type Item = ((Vec, Vec), OffchainOverlayedChange); - fn next(&mut self) -> Option { - if let Some(ref mut iter) = self.inner { - iter.next() - } else { - None - } - } -} - -impl OffchainOverlayedChangesIntoIter { - /// Create a new iterator by consuming the collection. - pub fn new(container: OffchainOverlayedChanges) -> Self { - match container { - OffchainOverlayedChanges::Enabled(inner) => Self { - inner: Some(inner.into_iter()) - }, - OffchainOverlayedChanges::Disabled => Self { inner: None, }, - } - } -} - -/// Iterate over all items while draining them from the collection. -pub struct OffchainOverlayedChangesDrain<'d> { - inner: Option, Vec), OffchainOverlayedChange>>, -} - -impl<'d> Iterator for OffchainOverlayedChangesDrain<'d> { - type Item = ((Vec, Vec), OffchainOverlayedChange); - fn next(&mut self) -> Option { - if let Some(ref mut iter) = self.inner { - iter.next() - } else { - None - } - } -} - -impl<'d> OffchainOverlayedChangesDrain<'d> { - /// Create a new iterator by taking a mut reference to the collection, - /// for the lifetime of the created drain iterator. - pub fn new(container: &'d mut OffchainOverlayedChanges) -> Self { - match container { - OffchainOverlayedChanges::Enabled(ref mut inner) => Self { - inner: Some(inner.drain()) - }, - OffchainOverlayedChanges::Disabled => Self { inner: None, }, - } - } -} - - -#[cfg(test)] -mod test { - use super::*; - use super::super::STORAGE_PREFIX; - - #[test] - fn test_drain() { - let mut ooc = OffchainOverlayedChanges::enabled(); - ooc.set(STORAGE_PREFIX,b"kkk", b"vvv"); - let drained = ooc.drain().count(); - assert_eq!(drained, 1); - let leftover = ooc.iter().count(); - assert_eq!(leftover, 0); - - ooc.set(STORAGE_PREFIX, b"a", b"v"); - ooc.set(STORAGE_PREFIX, b"b", b"v"); - ooc.set(STORAGE_PREFIX, b"c", b"v"); - ooc.set(STORAGE_PREFIX, b"d", b"v"); - ooc.set(STORAGE_PREFIX, b"e", b"v"); - assert_eq!(ooc.iter().count(), 5); - } - - #[test] - fn test_accumulated_set_remove_set() { - let mut ooc = OffchainOverlayedChanges::enabled(); - ooc.set(STORAGE_PREFIX, b"ppp", b"qqq"); - ooc.remove(STORAGE_PREFIX, b"ppp"); - // keys are equiv, so it will overwrite the value and the overlay will contain - // one item - assert_eq!(ooc.iter().count(), 1); - - ooc.set(STORAGE_PREFIX, b"ppp", b"rrr"); - let mut iter = ooc.into_iter(); - assert_eq!( - iter.next(), - Some( - ((STORAGE_PREFIX.to_vec(), b"ppp".to_vec()), - OffchainOverlayedChange::SetValue(b"rrr".to_vec())) - ) - ); - assert_eq!(iter.next(), None); - } -} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/testing.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/testing.rs deleted file mode 100644 index 3fe34cc0..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/offchain/testing.rs +++ /dev/null @@ -1,418 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Utilities for offchain calls testing. -//! -//! Namely all ExecutionExtensions that allow mocking -//! the extra APIs. - -use std::{ - collections::{BTreeMap, VecDeque}, - sync::Arc, -}; -use crate::OpaquePeerId; -use crate::offchain::{ - self, - storage::{InMemOffchainStorage, OffchainOverlayedChange, OffchainOverlayedChanges}, - HttpError, - HttpRequestId as RequestId, - HttpRequestStatus as RequestStatus, - Timestamp, - StorageKind, - OpaqueNetworkState, - TransactionPool, - OffchainStorage, -}; - -use parking_lot::RwLock; - -/// Pending request. -#[derive(Debug, Default, PartialEq, Eq)] -pub struct PendingRequest { - /// HTTP method - pub method: String, - /// URI - pub uri: String, - /// Encoded Metadata - pub meta: Vec, - /// Request headers - pub headers: Vec<(String, String)>, - /// Request body - pub body: Vec, - /// Has the request been sent already. - pub sent: bool, - /// Response body - pub response: Option>, - /// Number of bytes already read from the response body. - pub read: usize, - /// Response headers - pub response_headers: Vec<(String, String)>, -} - -/// Sharable "persistent" offchain storage for test. -#[derive(Debug, Clone, Default)] -pub struct TestPersistentOffchainDB { - persistent: Arc>, -} - -impl TestPersistentOffchainDB { - /// Create a new and empty offchain storage db for persistent items - pub fn new() -> Self { - Self { - persistent: Arc::new(RwLock::new(InMemOffchainStorage::default())) - } - } - - /// Apply a set of off-chain changes directly to the test backend - pub fn apply_offchain_changes(&mut self, changes: &mut OffchainOverlayedChanges) { - let mut me = self.persistent.write(); - for ((_prefix, key), value_operation) in changes.drain() { - match value_operation { - OffchainOverlayedChange::SetValue(val) => me.set(b"", key.as_slice(), val.as_slice()), - OffchainOverlayedChange::Remove => me.remove(b"", key.as_slice()), - } - } - } -} - -impl OffchainStorage for TestPersistentOffchainDB { - fn set(&mut self, prefix: &[u8], key: &[u8], value: &[u8]) { - self.persistent.write().set(prefix, key, value); - } - - fn remove(&mut self, prefix: &[u8], key: &[u8]) { - self.persistent.write().remove(prefix, key); - } - - fn get(&self, prefix: &[u8], key: &[u8]) -> Option> { - self.persistent.read().get(prefix, key) - } - - fn compare_and_set( - &mut self, - prefix: &[u8], - key: &[u8], - old_value: Option<&[u8]>, - new_value: &[u8], - ) -> bool { - self.persistent.write().compare_and_set(prefix, key, old_value, new_value) - } -} - - -/// Internal state of the externalities. -/// -/// This can be used in tests to respond or assert stuff about interactions. -#[derive(Debug, Default)] -pub struct OffchainState { - /// A list of pending requests. - pub requests: BTreeMap, - // Queue of requests that the test is expected to perform (in order). - expected_requests: VecDeque, - /// Persistent local storage - pub persistent_storage: TestPersistentOffchainDB, - /// Local storage - pub local_storage: InMemOffchainStorage, - /// A supposedly random seed. - pub seed: [u8; 32], - /// A timestamp simulating the current time. - pub timestamp: Timestamp, -} - -impl OffchainState { - /// Asserts that pending request has been submitted and fills it's response. - pub fn fulfill_pending_request( - &mut self, - id: u16, - expected: PendingRequest, - response: impl Into>, - response_headers: impl IntoIterator, - ) { - match self.requests.get_mut(&RequestId(id)) { - None => { - panic!("Missing pending request: {:?}.\n\nAll: {:?}", id, self.requests); - } - Some(req) => { - assert_eq!( - *req, - expected, - ); - req.response = Some(response.into()); - req.response_headers = response_headers.into_iter().collect(); - } - } - } - - fn fulfill_expected(&mut self, id: u16) { - if let Some(mut req) = self.expected_requests.pop_back() { - let response = req.response.take().expect("Response checked when added."); - let headers = std::mem::take(&mut req.response_headers); - self.fulfill_pending_request(id, req, response, headers); - } - } - - /// Add expected HTTP request. - /// - /// This method can be used to initialize expected HTTP requests and their responses - /// before running the actual code that utilizes them (for instance before calling into runtime). - /// Expected request has to be fulfilled before this struct is dropped, - /// the `response` and `response_headers` fields will be used to return results to the callers. - /// Requests are expected to be performed in the insertion order. - pub fn expect_request(&mut self, expected: PendingRequest) { - if expected.response.is_none() { - panic!("Expected request needs to have a response."); - } - self.expected_requests.push_front(expected); - } -} - -impl Drop for OffchainState { - fn drop(&mut self) { - // If we panic! while we are already in a panic, the test dies with an illegal instruction. - if !self.expected_requests.is_empty() && !std::thread::panicking() { - panic!("Unfulfilled expected requests: {:?}", self.expected_requests); - } - } -} - -/// Implementation of offchain externalities used for tests. -#[derive(Clone, Default, Debug)] -pub struct TestOffchainExt(pub Arc>); - -impl TestOffchainExt { - /// Create new `TestOffchainExt` and a reference to the internal state. - pub fn new() -> (Self, Arc>) { - let ext = Self::default(); - let state = ext.0.clone(); - (ext, state) - } - - /// Create new `TestOffchainExt` and a reference to the internal state. - pub fn with_offchain_db(offchain_db: TestPersistentOffchainDB) -> (Self, Arc>) { - let (ext, state) = Self::new(); - ext.0.write().persistent_storage = offchain_db; - (ext, state) - } -} - -impl offchain::Externalities for TestOffchainExt { - fn is_validator(&self) -> bool { - true - } - - fn network_state(&self) -> Result { - Ok(OpaqueNetworkState { - peer_id: Default::default(), - external_addresses: vec![], - }) - } - - fn timestamp(&mut self) -> Timestamp { - self.0.read().timestamp - } - - fn sleep_until(&mut self, deadline: Timestamp) { - self.0.write().timestamp = deadline; - } - - fn random_seed(&mut self) -> [u8; 32] { - self.0.read().seed - } - - fn local_storage_set(&mut self, kind: StorageKind, key: &[u8], value: &[u8]) { - let mut state = self.0.write(); - match kind { - StorageKind::LOCAL => state.local_storage.set(b"", key, value), - StorageKind::PERSISTENT => state.persistent_storage.set(b"", key, value), - }; - } - - fn local_storage_clear(&mut self, kind: StorageKind, key: &[u8]) { - let mut state = self.0.write(); - match kind { - StorageKind::LOCAL => state.local_storage.remove(b"", key), - StorageKind::PERSISTENT => state.persistent_storage.remove(b"", key), - }; - } - - fn local_storage_compare_and_set( - &mut self, - kind: StorageKind, - key: &[u8], - old_value: Option<&[u8]>, - new_value: &[u8] - ) -> bool { - let mut state = self.0.write(); - match kind { - StorageKind::LOCAL => state.local_storage.compare_and_set(b"", key, old_value, new_value), - StorageKind::PERSISTENT => state.persistent_storage.compare_and_set(b"", key, old_value, new_value), - } - } - - fn local_storage_get(&mut self, kind: StorageKind, key: &[u8]) -> Option> { - let state = self.0.read(); - match kind { - StorageKind::LOCAL => state.local_storage.get(b"", key), - StorageKind::PERSISTENT => state.persistent_storage.get(b"", key), - } - } - - fn http_request_start(&mut self, method: &str, uri: &str, meta: &[u8]) -> Result { - let mut state = self.0.write(); - let id = RequestId(state.requests.len() as u16); - state.requests.insert(id.clone(), PendingRequest { - method: method.into(), - uri: uri.into(), - meta: meta.into(), - ..Default::default() - }); - Ok(id) - } - - fn http_request_add_header( - &mut self, - request_id: RequestId, - name: &str, - value: &str, - ) -> Result<(), ()> { - let mut state = self.0.write(); - if let Some(req) = state.requests.get_mut(&request_id) { - req.headers.push((name.into(), value.into())); - Ok(()) - } else { - Err(()) - } - } - - fn http_request_write_body( - &mut self, - request_id: RequestId, - chunk: &[u8], - _deadline: Option - ) -> Result<(), HttpError> { - let mut state = self.0.write(); - - let sent = { - let req = state.requests.get_mut(&request_id).ok_or(HttpError::IoError)?; - req.body.extend(chunk); - if chunk.is_empty() { - req.sent = true; - } - req.sent - }; - - if sent { - state.fulfill_expected(request_id.0); - } - - Ok(()) - } - - fn http_response_wait( - &mut self, - ids: &[RequestId], - _deadline: Option, - ) -> Vec { - let state = self.0.read(); - - ids.iter().map(|id| match state.requests.get(id) { - Some(req) if req.response.is_none() => - panic!("No `response` provided for request with id: {:?}", id), - None => RequestStatus::Invalid, - _ => RequestStatus::Finished(200), - }).collect() - } - - fn http_response_headers(&mut self, request_id: RequestId) -> Vec<(Vec, Vec)> { - let state = self.0.read(); - if let Some(req) = state.requests.get(&request_id) { - req.response_headers - .clone() - .into_iter() - .map(|(k, v)| (k.into_bytes(), v.into_bytes())) - .collect() - } else { - Default::default() - } - } - - fn http_response_read_body( - &mut self, - request_id: RequestId, - buffer: &mut [u8], - _deadline: Option - ) -> Result { - let mut state = self.0.write(); - if let Some(req) = state.requests.get_mut(&request_id) { - let response = req.response - .as_mut() - .unwrap_or_else(|| panic!("No response provided for request: {:?}", request_id)); - - if req.read >= response.len() { - // Remove the pending request as per spec. - state.requests.remove(&request_id); - Ok(0) - } else { - let read = std::cmp::min(buffer.len(), response[req.read..].len()); - buffer[0..read].copy_from_slice(&response[req.read..read]); - req.read += read; - Ok(read) - } - } else { - Err(HttpError::IoError) - } - } - - fn set_authorized_nodes(&mut self, _nodes: Vec, _authorized_only: bool) { - unimplemented!() - } -} - -/// The internal state of the fake transaction pool. -#[derive(Default)] -pub struct PoolState { - /// A vector of transactions submitted from the runtime. - pub transactions: Vec>, -} - -/// Implementation of transaction pool used for test. -/// -/// Note that this implementation does not verify correctness -/// of sent extrinsics. It's meant to be used in contexts -/// where an actual runtime is not known. -/// -/// It's advised to write integration tests that include the -/// actual transaction pool to make sure the produced -/// transactions are valid. -#[derive(Default)] -pub struct TestTransactionPoolExt(Arc>); - -impl TestTransactionPoolExt { - /// Create new `TestTransactionPoolExt` and a reference to the internal state. - pub fn new() -> (Self, Arc>) { - let ext = Self::default(); - let state = ext.0.clone(); - (ext, state) - } -} - -impl TransactionPool for TestTransactionPoolExt { - fn submit_transaction(&mut self, extrinsic: Vec) -> Result<(), ()> { - self.0.write().transactions.push(extrinsic); - Ok(()) - } -} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/sandbox.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/sandbox.rs deleted file mode 100644 index 4cb5bd41..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/sandbox.rs +++ /dev/null @@ -1,128 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Definition of a sandbox environment. - -use codec::{Encode, Decode}; -use sp_std::vec::Vec; - -/// Error error that can be returned from host function. -#[derive(Encode, Decode)] -#[derive(crate::RuntimeDebug)] -pub struct HostError; - -/// Describes an entity to define or import into the environment. -#[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[derive(crate::RuntimeDebug)] -pub enum ExternEntity { - /// Function that is specified by an index in a default table of - /// a module that creates the sandbox. - #[codec(index = "1")] - Function(u32), - - /// Linear memory that is specified by some identifier returned by sandbox - /// module upon creation new sandboxed memory. - #[codec(index = "2")] - Memory(u32), -} - -/// An entry in a environment definition table. -/// -/// Each entry has a two-level name and description of an entity -/// being defined. -#[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[derive(crate::RuntimeDebug)] -pub struct Entry { - /// Module name of which corresponding entity being defined. - pub module_name: Vec, - /// Field name in which corresponding entity being defined. - pub field_name: Vec, - /// External entity being defined. - pub entity: ExternEntity, -} - -/// Definition of runtime that could be used by sandboxed code. -#[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[derive(crate::RuntimeDebug)] -pub struct EnvironmentDefinition { - /// Vector of all entries in the environment definition. - pub entries: Vec, -} - -/// Constant for specifying no limit when creating a sandboxed -/// memory instance. For FFI purposes. -pub const MEM_UNLIMITED: u32 = -1i32 as u32; - -/// No error happened. -/// -/// For FFI purposes. -pub const ERR_OK: u32 = 0; - -/// Validation or instantiation error occurred when creating new -/// sandboxed module instance. -/// -/// For FFI purposes. -pub const ERR_MODULE: u32 = -1i32 as u32; - -/// Out-of-bounds access attempted with memory or table. -/// -/// For FFI purposes. -pub const ERR_OUT_OF_BOUNDS: u32 = -2i32 as u32; - -/// Execution error occurred (typically trap). -/// -/// For FFI purposes. -pub const ERR_EXECUTION: u32 = -3i32 as u32; - -#[cfg(test)] -mod tests { - use super::*; - use std::fmt; - use codec::Codec; - - fn roundtrip(s: S) { - let encoded = s.encode(); - assert_eq!(S::decode(&mut &encoded[..]).unwrap(), s); - } - - #[test] - fn env_def_roundtrip() { - roundtrip(EnvironmentDefinition { - entries: vec![], - }); - - roundtrip(EnvironmentDefinition { - entries: vec![ - Entry { - module_name: b"kernel"[..].into(), - field_name: b"memory"[..].into(), - entity: ExternEntity::Memory(1337), - }, - ], - }); - - roundtrip(EnvironmentDefinition { - entries: vec![ - Entry { - module_name: b"env"[..].into(), - field_name: b"abort"[..].into(), - entity: ExternEntity::Function(228), - }, - ], - }); - } -} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/sr25519.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/sr25519.rs deleted file mode 100644 index 9a757c89..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/sr25519.rs +++ /dev/null @@ -1,889 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// tag::description[] -//! Simple sr25519 (Schnorr-Ristretto) API. -//! -//! Note: `CHAIN_CODE_LENGTH` must be equal to `crate::crypto::JUNCTION_ID_LEN` -//! for this to work. -// end::description[] -#[cfg(feature = "full_crypto")] -use sp_std::vec::Vec; -#[cfg(feature = "full_crypto")] -use schnorrkel::{signing_context, ExpansionMode, Keypair, SecretKey, MiniSecretKey, PublicKey, - derive::{Derivation, ChainCode, CHAIN_CODE_LENGTH} -}; -#[cfg(feature = "std")] -use std::convert::TryFrom; -#[cfg(feature = "std")] -use substrate_bip39::mini_secret_from_entropy; -#[cfg(feature = "std")] -use bip39::{Mnemonic, Language, MnemonicType}; -#[cfg(feature = "full_crypto")] -use crate::crypto::{ - Pair as TraitPair, DeriveJunction, Infallible, SecretStringError -}; -#[cfg(feature = "std")] -use crate::crypto::Ss58Codec; - -use crate::crypto::{Public as TraitPublic, CryptoTypePublicPair, UncheckedFrom, CryptoType, Derive, CryptoTypeId}; -use crate::hash::{H256, H512}; -use codec::{Encode, Decode}; -use sp_std::ops::Deref; - -#[cfg(feature = "std")] -use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; -#[cfg(feature = "full_crypto")] -use schnorrkel::keys::{MINI_SECRET_KEY_LENGTH, SECRET_KEY_LENGTH}; -use sp_runtime_interface::pass_by::PassByInner; - -// signing context -#[cfg(feature = "full_crypto")] -const SIGNING_CTX: &[u8] = b"substrate"; - -/// An identifier used to match public keys against sr25519 keys -pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"sr25"); - -/// An Schnorrkel/Ristretto x25519 ("sr25519") public key. -#[cfg_attr(feature = "full_crypto", derive(Hash))] -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Encode, Decode, Default, PassByInner)] -pub struct Public(pub [u8; 32]); - -/// An Schnorrkel/Ristretto x25519 ("sr25519") key pair. -#[cfg(feature = "full_crypto")] -pub struct Pair(Keypair); - -#[cfg(feature = "full_crypto")] -impl Clone for Pair { - fn clone(&self) -> Self { - Pair(schnorrkel::Keypair { - public: self.0.public, - secret: schnorrkel::SecretKey::from_bytes(&self.0.secret.to_bytes()[..]) - .expect("key is always the correct size; qed") - }) - } -} - -impl AsRef<[u8; 32]> for Public { - fn as_ref(&self) -> &[u8; 32] { - &self.0 - } -} - -impl AsRef<[u8]> for Public { - fn as_ref(&self) -> &[u8] { - &self.0[..] - } -} - -impl AsMut<[u8]> for Public { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0[..] - } -} - -impl Deref for Public { - type Target = [u8]; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl From for [u8; 32] { - fn from(x: Public) -> [u8; 32] { - x.0 - } -} - -impl From for H256 { - fn from(x: Public) -> H256 { - x.0.into() - } -} - -#[cfg(feature = "std")] -impl std::str::FromStr for Public { - type Err = crate::crypto::PublicError; - - fn from_str(s: &str) -> Result { - Self::from_ss58check(s) - } -} - -impl sp_std::convert::TryFrom<&[u8]> for Public { - type Error = (); - - fn try_from(data: &[u8]) -> Result { - if data.len() == 32 { - let mut inner = [0u8; 32]; - inner.copy_from_slice(data); - Ok(Public(inner)) - } else { - Err(()) - } - } -} - -impl UncheckedFrom<[u8; 32]> for Public { - fn unchecked_from(x: [u8; 32]) -> Self { - Public::from_raw(x) - } -} - -impl UncheckedFrom for Public { - fn unchecked_from(x: H256) -> Self { - Public::from_h256(x) - } -} - -#[cfg(feature = "std")] -impl std::fmt::Display for Public { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{}", self.to_ss58check()) - } -} - -impl sp_std::fmt::Debug for Public { - #[cfg(feature = "std")] - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - let s = self.to_ss58check(); - write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) - } - - #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - Ok(()) - } -} - -#[cfg(feature = "std")] -impl Serialize for Public { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - serializer.serialize_str(&self.to_ss58check()) - } -} - -#[cfg(feature = "std")] -impl<'de> Deserialize<'de> for Public { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { - Public::from_ss58check(&String::deserialize(deserializer)?) - .map_err(|e| de::Error::custom(format!("{:?}", e))) - } -} - -/// An Schnorrkel/Ristretto x25519 ("sr25519") signature. -/// -/// Instead of importing it for the local module, alias it to be available as a public type -#[derive(Encode, Decode, PassByInner)] -pub struct Signature(pub [u8; 64]); - -impl sp_std::convert::TryFrom<&[u8]> for Signature { - type Error = (); - - fn try_from(data: &[u8]) -> Result { - if data.len() == 64 { - let mut inner = [0u8; 64]; - inner.copy_from_slice(data); - Ok(Signature(inner)) - } else { - Err(()) - } - } -} - -#[cfg(feature = "std")] -impl Serialize for Signature { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - serializer.serialize_str(&hex::encode(self)) - } -} - -#[cfg(feature = "std")] -impl<'de> Deserialize<'de> for Signature { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { - let signature_hex = hex::decode(&String::deserialize(deserializer)?) - .map_err(|e| de::Error::custom(format!("{:?}", e)))?; - Ok(Signature::try_from(signature_hex.as_ref()) - .map_err(|e| de::Error::custom(format!("{:?}", e)))?) - } -} - -impl Clone for Signature { - fn clone(&self) -> Self { - let mut r = [0u8; 64]; - r.copy_from_slice(&self.0[..]); - Signature(r) - } -} - -impl Default for Signature { - fn default() -> Self { - Signature([0u8; 64]) - } -} - -impl PartialEq for Signature { - fn eq(&self, b: &Self) -> bool { - self.0[..] == b.0[..] - } -} - -impl Eq for Signature {} - -impl From for [u8; 64] { - fn from(v: Signature) -> [u8; 64] { - v.0 - } -} - -impl From for H512 { - fn from(v: Signature) -> H512 { - H512::from(v.0) - } -} - -impl AsRef<[u8; 64]> for Signature { - fn as_ref(&self) -> &[u8; 64] { - &self.0 - } -} - -impl AsRef<[u8]> for Signature { - fn as_ref(&self) -> &[u8] { - &self.0[..] - } -} - -impl AsMut<[u8]> for Signature { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0[..] - } -} - -#[cfg(feature = "full_crypto")] -impl From for Signature { - fn from(s: schnorrkel::Signature) -> Signature { - Signature(s.to_bytes()) - } -} - -impl sp_std::fmt::Debug for Signature { - #[cfg(feature = "std")] - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0)) - } - - #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - Ok(()) - } -} - -#[cfg(feature = "full_crypto")] -impl sp_std::hash::Hash for Signature { - fn hash(&self, state: &mut H) { - sp_std::hash::Hash::hash(&self.0[..], state); - } -} - -/// A localized signature also contains sender information. -/// NOTE: Encode and Decode traits are supported in ed25519 but not possible for now here. -#[cfg(feature = "std")] -#[derive(PartialEq, Eq, Clone, Debug)] -pub struct LocalizedSignature { - /// The signer of the signature. - pub signer: Public, - /// The signature itself. - pub signature: Signature, -} - -impl Signature { - /// A new instance from the given 64-byte `data`. - /// - /// NOTE: No checking goes on to ensure this is a real signature. Only use - /// it if you are certain that the array actually is a signature, or if you - /// immediately verify the signature. All functions that verify signatures - /// will fail if the `Signature` is not actually a valid signature. - pub fn from_raw(data: [u8; 64]) -> Signature { - Signature(data) - } - - /// A new instance from the given slice that should be 64 bytes long. - /// - /// NOTE: No checking goes on to ensure this is a real signature. Only use it if - /// you are certain that the array actually is a signature. GIGO! - pub fn from_slice(data: &[u8]) -> Self { - let mut r = [0u8; 64]; - r.copy_from_slice(data); - Signature(r) - } - - /// A new instance from an H512. - /// - /// NOTE: No checking goes on to ensure this is a real signature. Only use it if - /// you are certain that the array actually is a signature. GIGO! - pub fn from_h512(v: H512) -> Signature { - Signature(v.into()) - } -} - -impl Derive for Public { - /// Derive a child key from a series of given junctions. - /// - /// `None` if there are any hard junctions in there. - #[cfg(feature = "std")] - fn derive>(&self, path: Iter) -> Option { - let mut acc = PublicKey::from_bytes(self.as_ref()).ok()?; - for j in path { - match j { - DeriveJunction::Soft(cc) => acc = acc.derived_key_simple(ChainCode(cc), &[]).0, - DeriveJunction::Hard(_cc) => return None, - } - } - Some(Self(acc.to_bytes())) - } -} - -impl Public { - /// A new instance from the given 32-byte `data`. - /// - /// NOTE: No checking goes on to ensure this is a real public key. Only use it if - /// you are certain that the array actually is a pubkey. GIGO! - pub fn from_raw(data: [u8; 32]) -> Self { - Public(data) - } - - /// A new instance from an H256. - /// - /// NOTE: No checking goes on to ensure this is a real public key. Only use it if - /// you are certain that the array actually is a pubkey. GIGO! - pub fn from_h256(x: H256) -> Self { - Public(x.into()) - } - - /// Return a slice filled with raw data. - pub fn as_array_ref(&self) -> &[u8; 32] { - self.as_ref() - } -} - -impl TraitPublic for Public { - /// A new instance from the given slice that should be 32 bytes long. - /// - /// NOTE: No checking goes on to ensure this is a real public key. Only use it if - /// you are certain that the array actually is a pubkey. GIGO! - fn from_slice(data: &[u8]) -> Self { - let mut r = [0u8; 32]; - r.copy_from_slice(data); - Public(r) - } - - fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { - CryptoTypePublicPair(CRYPTO_ID, self.to_raw_vec()) - } -} - -impl From for CryptoTypePublicPair { - fn from(key: Public) -> Self { - (&key).into() - } -} - -impl From<&Public> for CryptoTypePublicPair { - fn from(key: &Public) -> Self { - CryptoTypePublicPair(CRYPTO_ID, key.to_raw_vec()) - } -} - -#[cfg(feature = "std")] -impl From for Pair { - fn from(sec: MiniSecretKey) -> Pair { - Pair(sec.expand_to_keypair(ExpansionMode::Ed25519)) - } -} - -#[cfg(feature = "std")] -impl From for Pair { - fn from(sec: SecretKey) -> Pair { - Pair(Keypair::from(sec)) - } -} - -#[cfg(feature = "full_crypto")] -impl From for Pair { - fn from(p: schnorrkel::Keypair) -> Pair { - Pair(p) - } -} - -#[cfg(feature = "full_crypto")] -impl From for schnorrkel::Keypair { - fn from(p: Pair) -> schnorrkel::Keypair { - p.0 - } -} - -#[cfg(feature = "full_crypto")] -impl AsRef for Pair { - fn as_ref(&self) -> &schnorrkel::Keypair { - &self.0 - } -} - -/// Derive a single hard junction. -#[cfg(feature = "full_crypto")] -fn derive_hard_junction(secret: &SecretKey, cc: &[u8; CHAIN_CODE_LENGTH]) -> MiniSecretKey { - secret.hard_derive_mini_secret_key(Some(ChainCode(cc.clone())), b"").0 -} - -/// The raw secret seed, which can be used to recreate the `Pair`. -#[cfg(feature = "full_crypto")] -type Seed = [u8; MINI_SECRET_KEY_LENGTH]; - -#[cfg(feature = "full_crypto")] -impl TraitPair for Pair { - type Public = Public; - type Seed = Seed; - type Signature = Signature; - type DeriveError = Infallible; - - /// Make a new key pair from raw secret seed material. - /// - /// This is generated using schnorrkel's Mini-Secret-Keys. - /// - /// A MiniSecretKey is literally what Ed25519 calls a SecretKey, which is just 32 random bytes. - fn from_seed(seed: &Seed) -> Pair { - Self::from_seed_slice(&seed[..]) - .expect("32 bytes can always build a key; qed") - } - - /// Get the public key. - fn public(&self) -> Public { - let mut pk = [0u8; 32]; - pk.copy_from_slice(&self.0.public.to_bytes()); - Public(pk) - } - - /// Make a new key pair from secret seed material. The slice must be 32 bytes long or it - /// will return `None`. - /// - /// You should never need to use this; generate(), generate_with_phrase(), from_phrase() - fn from_seed_slice(seed: &[u8]) -> Result { - match seed.len() { - MINI_SECRET_KEY_LENGTH => { - Ok(Pair( - MiniSecretKey::from_bytes(seed) - .map_err(|_| SecretStringError::InvalidSeed)? - .expand_to_keypair(ExpansionMode::Ed25519) - )) - } - SECRET_KEY_LENGTH => { - Ok(Pair( - SecretKey::from_bytes(seed) - .map_err(|_| SecretStringError::InvalidSeed)? - .to_keypair() - )) - } - _ => Err(SecretStringError::InvalidSeedLength) - } - } - #[cfg(feature = "std")] - fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) { - let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English); - let phrase = mnemonic.phrase(); - let (pair, seed) = Self::from_phrase(phrase, password) - .expect("All phrases generated by Mnemonic are valid; qed"); - ( - pair, - phrase.to_owned(), - seed, - ) - } - #[cfg(feature = "std")] - fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> { - Mnemonic::from_phrase(phrase, Language::English) - .map_err(|_| SecretStringError::InvalidPhrase) - .map(|m| Self::from_entropy(m.entropy(), password)) - } - - fn derive>(&self, - path: Iter, - seed: Option, - ) -> Result<(Pair, Option), Self::DeriveError> { - let seed = if let Some(s) = seed { - if let Ok(msk) = MiniSecretKey::from_bytes(&s) { - if msk.expand(ExpansionMode::Ed25519) == self.0.secret { - Some(msk) - } else { None } - } else { None } - } else { None }; - let init = self.0.secret.clone(); - let (result, seed) = path.fold((init, seed), |(acc, acc_seed), j| match (j, acc_seed) { - (DeriveJunction::Soft(cc), _) => - (acc.derived_key_simple(ChainCode(cc), &[]).0, None), - (DeriveJunction::Hard(cc), maybe_seed) => { - let seed = derive_hard_junction(&acc, &cc); - (seed.expand(ExpansionMode::Ed25519), maybe_seed.map(|_| seed)) - } - }); - Ok((Self(result.into()), seed.map(|s| MiniSecretKey::to_bytes(&s)))) - } - - fn sign(&self, message: &[u8]) -> Signature { - let context = signing_context(SIGNING_CTX); - self.0.sign(context.bytes(message)).into() - } - - fn verify>(sig: &Self::Signature, message: M, pubkey: &Self::Public) -> bool { - Self::verify_weak(&sig.0[..], message, pubkey) - } - - fn verify_weak, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool { - let signature = match schnorrkel::Signature::from_bytes(sig) { - Ok(signature) => signature, - Err(_) => return false, - }; - - let pub_key = match PublicKey::from_bytes(pubkey.as_ref()) { - Ok(pub_key) => pub_key, - Err(_) => return false, - }; - - pub_key.verify_simple(SIGNING_CTX, message.as_ref(), &signature).is_ok() - } - - fn to_raw_vec(&self) -> Vec { - self.0.secret.to_bytes().to_vec() - } -} - -#[cfg(feature = "std")] -impl Pair { - /// Make a new key pair from binary data derived from a valid seed phrase. - /// - /// This uses a key derivation function to convert the entropy into a seed, then returns - /// the pair generated from it. - pub fn from_entropy(entropy: &[u8], password: Option<&str>) -> (Pair, Seed) { - let mini_key: MiniSecretKey = mini_secret_from_entropy(entropy, password.unwrap_or("")) - .expect("32 bytes can always build a key; qed"); - - let kp = mini_key.expand_to_keypair(ExpansionMode::Ed25519); - (Pair(kp), mini_key.to_bytes()) - } - - /// Verify a signature on a message. Returns `true` if the signature is good. - /// Supports old 0.1.1 deprecated signatures and should be used only for backward - /// compatibility. - pub fn verify_deprecated>(sig: &Signature, message: M, pubkey: &Public) -> bool { - // Match both schnorrkel 0.1.1 and 0.8.0+ signatures, supporting both wallets - // that have not been upgraded and those that have. - match PublicKey::from_bytes(pubkey.as_ref()) { - Ok(pk) => pk.verify_simple_preaudit_deprecated( - SIGNING_CTX, message.as_ref(), &sig.0[..], - ).is_ok(), - Err(_) => false, - } - } -} - -impl CryptoType for Public { - #[cfg(feature = "full_crypto")] - type Pair = Pair; -} - -impl CryptoType for Signature { - #[cfg(feature = "full_crypto")] - type Pair = Pair; -} - -#[cfg(feature = "full_crypto")] -impl CryptoType for Pair { - type Pair = Pair; -} - -/// Batch verification. -/// -/// `messages`, `signatures` and `pub_keys` should all have equal length. -/// -/// Returns `true` if all signatures are correct, `false` otherwise. -#[cfg(feature = "std")] -pub fn verify_batch( - messages: Vec<&[u8]>, - signatures: Vec<&Signature>, - pub_keys: Vec<&Public>, -) -> bool { - let mut sr_pub_keys = Vec::with_capacity(pub_keys.len()); - for pub_key in pub_keys { - match schnorrkel::PublicKey::from_bytes(pub_key.as_ref()) { - Ok(pk) => sr_pub_keys.push(pk), - Err(_) => return false, - }; - } - - let mut sr_signatures = Vec::with_capacity(signatures.len()); - for signature in signatures { - match schnorrkel::Signature::from_bytes(signature.as_ref()) { - Ok(s) => sr_signatures.push(s), - Err(_) => return false - }; - } - - let mut messages: Vec = messages.into_iter().map( - |msg| signing_context(SIGNING_CTX).bytes(msg) - ).collect(); - - schnorrkel::verify_batch( - &mut messages, - &sr_signatures, - &sr_pub_keys, - true, - ).is_ok() -} - -#[cfg(test)] -mod compatibility_test { - use super::*; - use crate::crypto::DEV_PHRASE; - use hex_literal::hex; - - // NOTE: tests to ensure addresses that are created with the `0.1.x` version (pre-audit) are - // still functional. - - #[test] - fn derive_soft_known_pair_should_work() { - let pair = Pair::from_string(&format!("{}/Alice", DEV_PHRASE), None).unwrap(); - // known address of DEV_PHRASE with 1.1 - let known = hex!("d6c71059dbbe9ad2b0ed3f289738b800836eb425544ce694825285b958ca755e"); - assert_eq!(pair.public().to_raw_vec(), known); - } - - #[test] - fn derive_hard_known_pair_should_work() { - let pair = Pair::from_string(&format!("{}//Alice", DEV_PHRASE), None).unwrap(); - // known address of DEV_PHRASE with 1.1 - let known = hex!("d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"); - assert_eq!(pair.public().to_raw_vec(), known); - } - - #[test] - fn verify_known_old_message_should_work() { - let public = Public::from_raw(hex!("b4bfa1f7a5166695eb75299fd1c4c03ea212871c342f2c5dfea0902b2c246918")); - // signature generated by the 1.1 version with the same ^^ public key. - let signature = Signature::from_raw(hex!( - "5a9755f069939f45d96aaf125cf5ce7ba1db998686f87f2fb3cbdea922078741a73891ba265f70c31436e18a9acd14d189d73c12317ab6c313285cd938453202" - )); - let message = b"Verifying that I am the owner of 5G9hQLdsKQswNPgB499DeA5PkFBbgkLPJWkkS6FAM6xGQ8xD. Hash: 221455a3\n"; - assert!(Pair::verify_deprecated(&signature, &message[..], &public)); - assert!(!Pair::verify(&signature, &message[..], &public)); - } -} - -#[cfg(test)] -mod test { - use super::*; - use crate::crypto::{Ss58Codec, DEV_PHRASE, DEV_ADDRESS}; - use hex_literal::hex; - use serde_json; - - #[test] - fn default_phrase_should_be_used() { - assert_eq!( - Pair::from_string("//Alice///password", None).unwrap().public(), - Pair::from_string(&format!("{}//Alice", DEV_PHRASE), Some("password")).unwrap().public(), - ); - assert_eq!( - Pair::from_string(&format!("{}/Alice", DEV_PHRASE), None).as_ref().map(Pair::public), - Pair::from_string("/Alice", None).as_ref().map(Pair::public) - ); - } - - #[test] - fn default_address_should_be_used() { - assert_eq!( - Public::from_string(&format!("{}/Alice", DEV_ADDRESS)), - Public::from_string("/Alice") - ); - } - - #[test] - fn default_phrase_should_correspond_to_default_address() { - assert_eq!( - Pair::from_string(&format!("{}/Alice", DEV_PHRASE), None).unwrap().public(), - Public::from_string(&format!("{}/Alice", DEV_ADDRESS)).unwrap(), - ); - assert_eq!( - Pair::from_string("/Alice", None).unwrap().public(), - Public::from_string("/Alice").unwrap() - ); - } - - #[test] - fn derive_soft_should_work() { - let pair = Pair::from_seed(&hex!( - "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" - )); - let derive_1 = pair.derive(Some(DeriveJunction::soft(1)).into_iter(), None).unwrap().0; - let derive_1b = pair.derive(Some(DeriveJunction::soft(1)).into_iter(), None).unwrap().0; - let derive_2 = pair.derive(Some(DeriveJunction::soft(2)).into_iter(), None).unwrap().0; - assert_eq!(derive_1.public(), derive_1b.public()); - assert_ne!(derive_1.public(), derive_2.public()); - } - - #[test] - fn derive_hard_should_work() { - let pair = Pair::from_seed(&hex!( - "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" - )); - let derive_1 = pair.derive(Some(DeriveJunction::hard(1)).into_iter(), None).unwrap().0; - let derive_1b = pair.derive(Some(DeriveJunction::hard(1)).into_iter(), None).unwrap().0; - let derive_2 = pair.derive(Some(DeriveJunction::hard(2)).into_iter(), None).unwrap().0; - assert_eq!(derive_1.public(), derive_1b.public()); - assert_ne!(derive_1.public(), derive_2.public()); - } - - #[test] - fn derive_soft_public_should_work() { - let pair = Pair::from_seed(&hex!( - "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" - )); - let path = Some(DeriveJunction::soft(1)); - let pair_1 = pair.derive(path.clone().into_iter(), None).unwrap().0; - let public_1 = pair.public().derive(path.into_iter()).unwrap(); - assert_eq!(pair_1.public(), public_1); - } - - #[test] - fn derive_hard_public_should_fail() { - let pair = Pair::from_seed(&hex!( - "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" - )); - let path = Some(DeriveJunction::hard(1)); - assert!(pair.public().derive(path.into_iter()).is_none()); - } - - #[test] - fn sr_test_vector_should_work() { - let pair = Pair::from_seed(&hex!( - "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" - )); - let public = pair.public(); - assert_eq!( - public, - Public::from_raw(hex!( - "44a996beb1eef7bdcab976ab6d2ca26104834164ecf28fb375600576fcc6eb0f" - )) - ); - let message = b""; - let signature = pair.sign(message); - assert!(Pair::verify(&signature, &message[..], &public)); - } - - #[test] - fn generated_pair_should_work() { - let (pair, _) = Pair::generate(); - let public = pair.public(); - let message = b"Something important"; - let signature = pair.sign(&message[..]); - assert!(Pair::verify(&signature, &message[..], &public)); - } - - #[test] - fn messed_signature_should_not_work() { - let (pair, _) = Pair::generate(); - let public = pair.public(); - let message = b"Signed payload"; - let Signature(mut bytes) = pair.sign(&message[..]); - bytes[0] = !bytes[0]; - bytes[2] = !bytes[2]; - let signature = Signature(bytes); - assert!(!Pair::verify(&signature, &message[..], &public)); - } - - #[test] - fn messed_message_should_not_work() { - let (pair, _) = Pair::generate(); - let public = pair.public(); - let message = b"Something important"; - let signature = pair.sign(&message[..]); - assert!(!Pair::verify(&signature, &b"Something unimportant", &public)); - } - - #[test] - fn seeded_pair_should_work() { - let pair = Pair::from_seed(b"12345678901234567890123456789012"); - let public = pair.public(); - assert_eq!( - public, - Public::from_raw(hex!( - "741c08a06f41c596608f6774259bd9043304adfa5d3eea62760bd9be97634d63" - )) - ); - let message = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000200d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000"); - let signature = pair.sign(&message[..]); - assert!(Pair::verify(&signature, &message[..], &public)); - } - - #[test] - fn ss58check_roundtrip_works() { - let (pair, _) = Pair::generate(); - let public = pair.public(); - let s = public.to_ss58check(); - println!("Correct: {}", s); - let cmp = Public::from_ss58check(&s).unwrap(); - assert_eq!(cmp, public); - } - - #[test] - fn verify_from_old_wasm_works() { - // The values in this test case are compared to the output of `node-test.js` in schnorrkel-js. - // - // This is to make sure that the wasm library is compatible. - let pk = Pair::from_seed( - &hex!("0000000000000000000000000000000000000000000000000000000000000000") - ); - let public = pk.public(); - let js_signature = Signature::from_raw(hex!( - "28a854d54903e056f89581c691c1f7d2ff39f8f896c9e9c22475e60902cc2b3547199e0e91fa32902028f2ca2355e8cdd16cfe19ba5e8b658c94aa80f3b81a00" - )); - assert!(Pair::verify_deprecated(&js_signature, b"SUBSTRATE", &public)); - assert!(!Pair::verify(&js_signature, b"SUBSTRATE", &public)); - } - - #[test] - fn signature_serialization_works() { - let pair = Pair::from_seed(b"12345678901234567890123456789012"); - let message = b"Something important"; - let signature = pair.sign(&message[..]); - let serialized_signature = serde_json::to_string(&signature).unwrap(); - // Signature is 64 bytes, so 128 chars + 2 quote chars - assert_eq!(serialized_signature.len(), 130); - let signature = serde_json::from_str(&serialized_signature).unwrap(); - assert!(Pair::verify(&signature, &message[..], &pair.public())); - } - - #[test] - fn signature_serialization_doesnt_panic() { - fn deserialize_signature(text: &str) -> Result { - Ok(serde_json::from_str(text)?) - } - assert!(deserialize_signature("Not valid json.").is_err()); - assert!(deserialize_signature("\"Not an actual signature.\"").is_err()); - // Poorly-sized - assert!(deserialize_signature("\"abc123\"").is_err()); - } -} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/testing.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/testing.rs deleted file mode 100644 index 5c4af736..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/testing.rs +++ /dev/null @@ -1,464 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Types that should only be used for testing! - -use crate::crypto::KeyTypeId; -#[cfg(feature = "std")] -use crate::{ - crypto::{Pair, Public, CryptoTypePublicPair}, - ed25519, sr25519, ecdsa, - traits::Error, - vrf::{VRFTranscriptData, VRFSignature, make_transcript}, -}; -#[cfg(feature = "std")] -use std::collections::HashSet; - -/// Key type for generic Ed25519 key. -pub const ED25519: KeyTypeId = KeyTypeId(*b"ed25"); -/// Key type for generic Sr 25519 key. -pub const SR25519: KeyTypeId = KeyTypeId(*b"sr25"); -/// Key type for generic Sr 25519 key. -pub const ECDSA: KeyTypeId = KeyTypeId(*b"ecds"); - -/// A keystore implementation usable in tests. -#[cfg(feature = "std")] -#[derive(Default)] -pub struct KeyStore { - /// `KeyTypeId` maps to public keys and public keys map to private keys. - keys: std::collections::HashMap, String>>, -} - -#[cfg(feature = "std")] -impl KeyStore { - /// Creates a new instance of `Self`. - pub fn new() -> crate::traits::BareCryptoStorePtr { - std::sync::Arc::new(parking_lot::RwLock::new(Self::default())) - } - - fn sr25519_key_pair(&self, id: KeyTypeId, pub_key: &sr25519::Public) -> Option { - self.keys.get(&id) - .and_then(|inner| - inner.get(pub_key.as_slice()) - .map(|s| sr25519::Pair::from_string(s, None).expect("`sr25519` seed slice is valid")) - ) - } - - fn ed25519_key_pair(&self, id: KeyTypeId, pub_key: &ed25519::Public) -> Option { - self.keys.get(&id) - .and_then(|inner| - inner.get(pub_key.as_slice()) - .map(|s| ed25519::Pair::from_string(s, None).expect("`ed25519` seed slice is valid")) - ) - } - - fn ecdsa_key_pair(&self, id: KeyTypeId, pub_key: &ecdsa::Public) -> Option { - self.keys.get(&id) - .and_then(|inner| - inner.get(pub_key.as_slice()) - .map(|s| ecdsa::Pair::from_string(s, None).expect("`ecdsa` seed slice is valid")) - ) - } - -} - -#[cfg(feature = "std")] -impl crate::traits::BareCryptoStore for KeyStore { - fn keys(&self, id: KeyTypeId) -> Result, Error> { - self.keys - .get(&id) - .map(|map| { - Ok(map.keys() - .fold(Vec::new(), |mut v, k| { - v.push(CryptoTypePublicPair(sr25519::CRYPTO_ID, k.clone())); - v.push(CryptoTypePublicPair(ed25519::CRYPTO_ID, k.clone())); - v.push(CryptoTypePublicPair(ecdsa::CRYPTO_ID, k.clone())); - v - })) - }) - .unwrap_or_else(|| Ok(vec![])) - } - - fn sr25519_public_keys(&self, id: KeyTypeId) -> Vec { - self.keys.get(&id) - .map(|keys| - keys.values() - .map(|s| sr25519::Pair::from_string(s, None).expect("`sr25519` seed slice is valid")) - .map(|p| p.public()) - .collect() - ) - .unwrap_or_default() - } - - fn sr25519_generate_new( - &mut self, - id: KeyTypeId, - seed: Option<&str>, - ) -> Result { - match seed { - Some(seed) => { - let pair = sr25519::Pair::from_string(seed, None) - .map_err(|_| Error::ValidationError("Generates an `sr25519` pair.".to_owned()))?; - self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into()); - Ok(pair.public()) - }, - None => { - let (pair, phrase, _) = sr25519::Pair::generate_with_phrase(None); - self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), phrase); - Ok(pair.public()) - } - } - } - - fn ed25519_public_keys(&self, id: KeyTypeId) -> Vec { - self.keys.get(&id) - .map(|keys| - keys.values() - .map(|s| ed25519::Pair::from_string(s, None).expect("`ed25519` seed slice is valid")) - .map(|p| p.public()) - .collect() - ) - .unwrap_or_default() - } - - fn ed25519_generate_new( - &mut self, - id: KeyTypeId, - seed: Option<&str>, - ) -> Result { - match seed { - Some(seed) => { - let pair = ed25519::Pair::from_string(seed, None) - .map_err(|_| Error::ValidationError("Generates an `ed25519` pair.".to_owned()))?; - self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into()); - Ok(pair.public()) - }, - None => { - let (pair, phrase, _) = ed25519::Pair::generate_with_phrase(None); - self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), phrase); - Ok(pair.public()) - } - } - } - - fn ecdsa_public_keys(&self, id: KeyTypeId) -> Vec { - self.keys.get(&id) - .map(|keys| - keys.values() - .map(|s| ecdsa::Pair::from_string(s, None).expect("`ecdsa` seed slice is valid")) - .map(|p| p.public()) - .collect() - ) - .unwrap_or_default() - } - - fn ecdsa_generate_new( - &mut self, - id: KeyTypeId, - seed: Option<&str>, - ) -> Result { - match seed { - Some(seed) => { - let pair = ecdsa::Pair::from_string(seed, None) - .map_err(|_| Error::ValidationError("Generates an `ecdsa` pair.".to_owned()))?; - self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into()); - Ok(pair.public()) - }, - None => { - let (pair, phrase, _) = ecdsa::Pair::generate_with_phrase(None); - self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), phrase); - Ok(pair.public()) - } - } - } - - fn insert_unknown(&mut self, id: KeyTypeId, suri: &str, public: &[u8]) -> Result<(), ()> { - self.keys.entry(id).or_default().insert(public.to_owned(), suri.to_string()); - Ok(()) - } - - fn password(&self) -> Option<&str> { - None - } - - fn has_keys(&self, public_keys: &[(Vec, KeyTypeId)]) -> bool { - public_keys.iter().all(|(k, t)| self.keys.get(&t).and_then(|s| s.get(k)).is_some()) - } - - fn supported_keys( - &self, - id: KeyTypeId, - keys: Vec, - ) -> std::result::Result, Error> { - let provided_keys = keys.into_iter().collect::>(); - let all_keys = self.keys(id)?.into_iter().collect::>(); - - Ok(provided_keys.intersection(&all_keys).cloned().collect()) - } - - fn sign_with( - &self, - id: KeyTypeId, - key: &CryptoTypePublicPair, - msg: &[u8], - ) -> Result, Error> { - use codec::Encode; - - match key.0 { - ed25519::CRYPTO_ID => { - let key_pair: ed25519::Pair = self - .ed25519_key_pair(id, &ed25519::Public::from_slice(key.1.as_slice())) - .ok_or_else(|| Error::PairNotFound("ed25519".to_owned()))?; - return Ok(key_pair.sign(msg).encode()); - } - sr25519::CRYPTO_ID => { - let key_pair: sr25519::Pair = self - .sr25519_key_pair(id, &sr25519::Public::from_slice(key.1.as_slice())) - .ok_or_else(|| Error::PairNotFound("sr25519".to_owned()))?; - return Ok(key_pair.sign(msg).encode()); - } - ecdsa::CRYPTO_ID => { - let key_pair: ecdsa::Pair = self - .ecdsa_key_pair(id, &ecdsa::Public::from_slice(key.1.as_slice())) - .ok_or_else(|| Error::PairNotFound("ecdsa".to_owned()))?; - return Ok(key_pair.sign(msg).encode()); - } - _ => Err(Error::KeyNotSupported(id)) - } - } - - fn sr25519_vrf_sign( - &self, - key_type: KeyTypeId, - public: &sr25519::Public, - transcript_data: VRFTranscriptData, - ) -> Result { - let transcript = make_transcript(transcript_data); - let pair = self.sr25519_key_pair(key_type, public) - .ok_or_else(|| Error::PairNotFound("Not found".to_owned()))?; - - let (inout, proof, _) = pair.as_ref().vrf_sign(transcript); - Ok(VRFSignature { - output: inout.to_output(), - proof, - }) - } -} - -/// Macro for exporting functions from wasm in with the expected signature for using it with the -/// wasm executor. This is useful for tests where you need to call a function in wasm. -/// -/// The input parameters are expected to be SCALE encoded and will be automatically decoded for you. -/// The output value is also SCALE encoded when returned back to the host. -/// -/// The functions are feature-gated with `#[cfg(not(feature = "std"))]`, so they are only available -/// from within wasm. -/// -/// # Example -/// -/// ``` -/// # use sp_core::wasm_export_functions; -/// -/// wasm_export_functions! { -/// fn test_in_wasm(value: bool, another_value: Vec) -> bool { -/// value && another_value.is_empty() -/// } -/// -/// fn without_return_value() { -/// // do something -/// } -/// } -/// ``` -#[macro_export] -macro_rules! wasm_export_functions { - ( - $( - fn $name:ident ( - $( $arg_name:ident: $arg_ty:ty ),* $(,)? - ) $( -> $ret_ty:ty )? { $( $fn_impl:tt )* } - )* - ) => { - $( - $crate::wasm_export_functions! { - @IMPL - fn $name ( - $( $arg_name: $arg_ty ),* - ) $( -> $ret_ty )? { $( $fn_impl )* } - } - )* - }; - (@IMPL - fn $name:ident ( - $( $arg_name:ident: $arg_ty:ty ),* - ) { $( $fn_impl:tt )* } - ) => { - #[no_mangle] - #[allow(unreachable_code)] - #[cfg(not(feature = "std"))] - pub fn $name(input_data: *mut u8, input_len: usize) -> u64 { - let input: &[u8] = if input_len == 0 { - &[0u8; 0] - } else { - unsafe { - $crate::sp_std::slice::from_raw_parts(input_data, input_len) - } - }; - - { - let ($( $arg_name ),*) : ($( $arg_ty ),*) = $crate::Decode::decode( - &mut &input[..], - ).expect("Input data is correctly encoded"); - - $( $fn_impl )* - } - - $crate::to_substrate_wasm_fn_return_value(&()) - } - }; - (@IMPL - fn $name:ident ( - $( $arg_name:ident: $arg_ty:ty ),* - ) $( -> $ret_ty:ty )? { $( $fn_impl:tt )* } - ) => { - #[no_mangle] - #[allow(unreachable_code)] - #[cfg(not(feature = "std"))] - pub fn $name(input_data: *mut u8, input_len: usize) -> u64 { - let input: &[u8] = if input_len == 0 { - &[0u8; 0] - } else { - unsafe { - $crate::sp_std::slice::from_raw_parts(input_data, input_len) - } - }; - - let output $( : $ret_ty )? = { - let ($( $arg_name ),*) : ($( $arg_ty ),*) = $crate::Decode::decode( - &mut &input[..], - ).expect("Input data is correctly encoded"); - - $( $fn_impl )* - }; - - $crate::to_substrate_wasm_fn_return_value(&output) - } - }; -} - -/// A task executor that can be used in tests. -/// -/// Internally this just wraps a `ThreadPool` with a pool size of `8`. This -/// should ensure that we have enough threads in tests for spawning blocking futures. -#[cfg(feature = "std")] -#[derive(Clone)] -pub struct TaskExecutor(futures::executor::ThreadPool); - -#[cfg(feature = "std")] -impl TaskExecutor { - /// Create a new instance of `Self`. - pub fn new() -> Self { - let mut builder = futures::executor::ThreadPoolBuilder::new(); - Self(builder.pool_size(8).create().expect("Failed to create thread pool")) - } -} - -#[cfg(feature = "std")] -impl crate::traits::SpawnNamed for TaskExecutor { - fn spawn_blocking(&self, _: &'static str, future: futures::future::BoxFuture<'static, ()>) { - self.0.spawn_ok(future); - } - fn spawn(&self, _: &'static str, future: futures::future::BoxFuture<'static, ()>) { - self.0.spawn_ok(future); - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::sr25519; - use crate::testing::{ED25519, SR25519}; - use crate::vrf::VRFTranscriptValue; - - #[test] - fn store_key_and_extract() { - let store = KeyStore::new(); - - let public = store.write() - .ed25519_generate_new(ED25519, None) - .expect("Generates key"); - - let public_keys = store.read().keys(ED25519).unwrap(); - - assert!(public_keys.contains(&public.into())); - } - - #[test] - fn store_unknown_and_extract_it() { - let store = KeyStore::new(); - - let secret_uri = "//Alice"; - let key_pair = sr25519::Pair::from_string(secret_uri, None).expect("Generates key pair"); - - store.write().insert_unknown( - SR25519, - secret_uri, - key_pair.public().as_ref(), - ).expect("Inserts unknown key"); - - let public_keys = store.read().keys(SR25519).unwrap(); - - assert!(public_keys.contains(&key_pair.public().into())); - } - - #[test] - fn vrf_sign() { - let store = KeyStore::new(); - - let secret_uri = "//Alice"; - let key_pair = sr25519::Pair::from_string(secret_uri, None).expect("Generates key pair"); - - let transcript_data = VRFTranscriptData { - label: b"Test", - items: vec![ - ("one", VRFTranscriptValue::U64(1)), - ("two", VRFTranscriptValue::U64(2)), - ("three", VRFTranscriptValue::Bytes("test".as_bytes())), - ] - }; - - let result = store.read().sr25519_vrf_sign( - SR25519, - &key_pair.public(), - transcript_data.clone(), - ); - assert!(result.is_err()); - - store.write().insert_unknown( - SR25519, - secret_uri, - key_pair.public().as_ref(), - ).expect("Inserts unknown key"); - - let result = store.read().sr25519_vrf_sign( - SR25519, - &key_pair.public(), - transcript_data, - ); - - assert!(result.is_ok()); - } -} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/traits.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/traits.rs deleted file mode 100644 index ab409b60..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/traits.rs +++ /dev/null @@ -1,388 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Shareable Substrate traits. - -use crate::{ - crypto::{KeyTypeId, CryptoTypePublicPair}, - vrf::{VRFTranscriptData, VRFSignature}, - ed25519, sr25519, ecdsa, -}; -use std::{ - borrow::Cow, - fmt::{Debug, Display}, - panic::UnwindSafe, - sync::Arc, -}; - -pub use sp_externalities::{Externalities, ExternalitiesExt}; - -/// BareCryptoStore error -#[derive(Debug, derive_more::Display)] -pub enum Error { - /// Public key type is not supported - #[display(fmt="Key not supported: {:?}", _0)] - KeyNotSupported(KeyTypeId), - /// Pair not found for public key and KeyTypeId - #[display(fmt="Pair was not found: {}", _0)] - PairNotFound(String), - /// Validation error - #[display(fmt="Validation error: {}", _0)] - ValidationError(String), - /// Keystore unavailable - #[display(fmt="Keystore unavailable")] - Unavailable, - /// Programming errors - #[display(fmt="An unknown keystore error occurred: {}", _0)] - Other(String) -} - -/// Something that generates, stores and provides access to keys. -pub trait BareCryptoStore: Send + Sync { - /// Returns all sr25519 public keys for the given key type. - fn sr25519_public_keys(&self, id: KeyTypeId) -> Vec; - /// Generate a new sr25519 key pair for the given key type and an optional seed. - /// - /// If the given seed is `Some(_)`, the key pair will only be stored in memory. - /// - /// Returns the public key of the generated key pair. - fn sr25519_generate_new( - &mut self, - id: KeyTypeId, - seed: Option<&str>, - ) -> Result; - /// Returns all ed25519 public keys for the given key type. - fn ed25519_public_keys(&self, id: KeyTypeId) -> Vec; - /// Generate a new ed25519 key pair for the given key type and an optional seed. - /// - /// If the given seed is `Some(_)`, the key pair will only be stored in memory. - /// - /// Returns the public key of the generated key pair. - fn ed25519_generate_new( - &mut self, - id: KeyTypeId, - seed: Option<&str>, - ) -> Result; - /// Returns all ecdsa public keys for the given key type. - fn ecdsa_public_keys(&self, id: KeyTypeId) -> Vec; - /// Generate a new ecdsa key pair for the given key type and an optional seed. - /// - /// If the given seed is `Some(_)`, the key pair will only be stored in memory. - /// - /// Returns the public key of the generated key pair. - fn ecdsa_generate_new( - &mut self, - id: KeyTypeId, - seed: Option<&str>, - ) -> Result; - - /// Insert a new key. This doesn't require any known of the crypto; but a public key must be - /// manually provided. - /// - /// Places it into the file system store. - /// - /// `Err` if there's some sort of weird filesystem error, but should generally be `Ok`. - fn insert_unknown(&mut self, _key_type: KeyTypeId, _suri: &str, _public: &[u8]) -> Result<(), ()>; - - /// Get the password for this store. - fn password(&self) -> Option<&str>; - /// Find intersection between provided keys and supported keys - /// - /// Provided a list of (CryptoTypeId,[u8]) pairs, this would return - /// a filtered set of public keys which are supported by the keystore. - fn supported_keys( - &self, - id: KeyTypeId, - keys: Vec - ) -> Result, Error>; - /// List all supported keys - /// - /// Returns a set of public keys the signer supports. - fn keys(&self, id: KeyTypeId) -> Result, Error>; - - /// Checks if the private keys for the given public key and key type combinations exist. - /// - /// Returns `true` iff all private keys could be found. - fn has_keys(&self, public_keys: &[(Vec, KeyTypeId)]) -> bool; - - /// Sign with key - /// - /// Signs a message with the private key that matches - /// the public key passed. - /// - /// Returns the SCALE encoded signature if key is found & supported, - /// an error otherwise. - fn sign_with( - &self, - id: KeyTypeId, - key: &CryptoTypePublicPair, - msg: &[u8], - ) -> Result, Error>; - - /// Sign with any key - /// - /// Given a list of public keys, find the first supported key and - /// sign the provided message with that key. - /// - /// Returns a tuple of the used key and the SCALE encoded signature. - fn sign_with_any( - &self, - id: KeyTypeId, - keys: Vec, - msg: &[u8] - ) -> Result<(CryptoTypePublicPair, Vec), Error> { - if keys.len() == 1 { - return self.sign_with(id, &keys[0], msg).map(|s| (keys[0].clone(), s)); - } else { - for k in self.supported_keys(id, keys)? { - if let Ok(sign) = self.sign_with(id, &k, msg) { - return Ok((k, sign)); - } - } - } - Err(Error::KeyNotSupported(id)) - } - - /// Sign with all keys - /// - /// Provided a list of public keys, sign a message with - /// each key given that the key is supported. - /// - /// Returns a list of `Result`s each representing the SCALE encoded - /// signature of each key or a Error for non-supported keys. - fn sign_with_all( - &self, - id: KeyTypeId, - keys: Vec, - msg: &[u8], - ) -> Result, Error>>, ()>{ - Ok(keys.iter().map(|k| self.sign_with(id, k, msg)).collect()) - } - - /// Generate VRF signature for given transcript data. - /// - /// Receives KeyTypeId and Public key to be able to map - /// them to a private key that exists in the keystore which - /// is, in turn, used for signing the provided transcript. - /// - /// Returns a result containing the signature data. - /// Namely, VRFOutput and VRFProof which are returned - /// inside the `VRFSignature` container struct. - /// - /// This function will return an error in the cases where - /// the public key and key type provided do not match a private - /// key in the keystore. Or, in the context of remote signing - /// an error could be a network one. - fn sr25519_vrf_sign( - &self, - key_type: KeyTypeId, - public: &sr25519::Public, - transcript_data: VRFTranscriptData, - ) -> Result; -} - -/// A pointer to the key store. -pub type BareCryptoStorePtr = Arc>; - -sp_externalities::decl_extension! { - /// The keystore extension to register/retrieve from the externalities. - pub struct KeystoreExt(BareCryptoStorePtr); -} - -/// Code execution engine. -pub trait CodeExecutor: Sized + Send + Sync + CallInWasm + Clone + 'static { - /// Externalities error type. - type Error: Display + Debug + Send + 'static; - - /// Call a given method in the runtime. Returns a tuple of the result (either the output data - /// or an execution error) together with a `bool`, which is true if native execution was used. - fn call< - R: codec::Codec + PartialEq, - NC: FnOnce() -> Result + UnwindSafe, - >( - &self, - ext: &mut dyn Externalities, - runtime_code: &RuntimeCode, - method: &str, - data: &[u8], - use_native: bool, - native_call: Option, - ) -> (Result, Self::Error>, bool); -} - -/// Something that can fetch the runtime `:code`. -pub trait FetchRuntimeCode { - /// Fetch the runtime `:code`. - /// - /// If the `:code` could not be found/not available, `None` should be returned. - fn fetch_runtime_code<'a>(&'a self) -> Option>; -} - -/// Wrapper to use a `u8` slice or `Vec` as [`FetchRuntimeCode`]. -pub struct WrappedRuntimeCode<'a>(pub std::borrow::Cow<'a, [u8]>); - -impl<'a> FetchRuntimeCode for WrappedRuntimeCode<'a> { - fn fetch_runtime_code<'b>(&'b self) -> Option> { - Some(self.0.as_ref().into()) - } -} - -/// Type that implements [`FetchRuntimeCode`] and always returns `None`. -pub struct NoneFetchRuntimeCode; - -impl FetchRuntimeCode for NoneFetchRuntimeCode { - fn fetch_runtime_code<'a>(&'a self) -> Option> { - None - } -} - -/// The Wasm code of a Substrate runtime. -#[derive(Clone)] -pub struct RuntimeCode<'a> { - /// The code fetcher that can be used to lazily fetch the code. - pub code_fetcher: &'a dyn FetchRuntimeCode, - /// The optional heap pages this `code` should be executed with. - /// - /// If `None` are given, the default value of the executor will be used. - pub heap_pages: Option, - /// The SCALE encoded hash of `code`. - /// - /// The hashing algorithm isn't that important, as long as all runtime - /// code instances use the same. - pub hash: Vec, -} - -impl<'a> PartialEq for RuntimeCode<'a> { - fn eq(&self, other: &Self) -> bool { - self.hash == other.hash - } -} - -impl<'a> RuntimeCode<'a> { - /// Create an empty instance. - /// - /// This is only useful for tests that don't want to execute any code. - pub fn empty() -> Self { - Self { - code_fetcher: &NoneFetchRuntimeCode, - hash: Vec::new(), - heap_pages: None, - } - } -} - -impl<'a> FetchRuntimeCode for RuntimeCode<'a> { - fn fetch_runtime_code<'b>(&'b self) -> Option> { - self.code_fetcher.fetch_runtime_code() - } -} - -/// Could not find the `:code` in the externalities while initializing the [`RuntimeCode`]. -#[derive(Debug)] -pub struct CodeNotFound; - -impl std::fmt::Display for CodeNotFound { - fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { - write!(f, "the storage entry `:code` doesn't have any code") - } -} - -/// `Allow` or `Disallow` missing host functions when instantiating a WASM blob. -#[derive(Clone, Copy, Debug)] -pub enum MissingHostFunctions { - /// Any missing host function will be replaced by a stub that returns an error when - /// being called. - Allow, - /// Any missing host function will result in an error while instantiating the WASM blob, - Disallow, -} - -impl MissingHostFunctions { - /// Are missing host functions allowed? - pub fn allowed(self) -> bool { - matches!(self, Self::Allow) - } -} - -/// Something that can call a method in a WASM blob. -pub trait CallInWasm: Send + Sync { - /// Call the given `method` in the given `wasm_blob` using `call_data` (SCALE encoded arguments) - /// to decode the arguments for the method. - /// - /// Returns the SCALE encoded return value of the method. - /// - /// # Note - /// - /// If `code_hash` is `Some(_)` the `wasm_code` module and instance will be cached internally, - /// otherwise it is thrown away after the call. - fn call_in_wasm( - &self, - wasm_code: &[u8], - code_hash: Option>, - method: &str, - call_data: &[u8], - ext: &mut dyn Externalities, - missing_host_functions: MissingHostFunctions, - ) -> Result, String>; -} - -sp_externalities::decl_extension! { - /// The call-in-wasm extension to register/retrieve from the externalities. - pub struct CallInWasmExt(Box); -} - -impl CallInWasmExt { - /// Creates a new instance of `Self`. - pub fn new(inner: T) -> Self { - Self(Box::new(inner)) - } -} - -sp_externalities::decl_extension! { - /// Task executor extension. - pub struct TaskExecutorExt(Box); -} - -impl TaskExecutorExt { - /// New instance of task executor extension. - pub fn new(spawn_handle: impl SpawnNamed + Send + 'static) -> Self { - Self(Box::new(spawn_handle)) - } -} - -/// Something that can spawn futures (blocking and non-blocking) with an assigned name. -#[dyn_clonable::clonable] -pub trait SpawnNamed: Clone + Send + Sync { - /// Spawn the given blocking future. - /// - /// The given `name` is used to identify the future in tracing. - fn spawn_blocking(&self, name: &'static str, future: futures::future::BoxFuture<'static, ()>); - /// Spawn the given non-blocking future. - /// - /// The given `name` is used to identify the future in tracing. - fn spawn(&self, name: &'static str, future: futures::future::BoxFuture<'static, ()>); -} - -impl SpawnNamed for Box { - fn spawn_blocking(&self, name: &'static str, future: futures::future::BoxFuture<'static, ()>) { - (**self).spawn_blocking(name, future) - } - - fn spawn(&self, name: &'static str, future: futures::future::BoxFuture<'static, ()>) { - (**self).spawn(name, future) - } -} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/u32_trait.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/u32_trait.rs deleted file mode 100644 index 6f73e1f6..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/u32_trait.rs +++ /dev/null @@ -1,244 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! An u32 trait with "values" as impl'd types. - -/// A u32 value, wrapped in a trait because we don't yet have const generics. -pub trait Value { - /// The actual value represented by the impl'ing type. - const VALUE: u32; -} - -/// Type representing the value 0 for the `Value` trait. -pub struct _0; impl Value for _0 { const VALUE: u32 = 0; } -/// Type representing the value 1 for the `Value` trait. -pub struct _1; impl Value for _1 { const VALUE: u32 = 1; } -/// Type representing the value 2 for the `Value` trait. -pub struct _2; impl Value for _2 { const VALUE: u32 = 2; } -/// Type representing the value 3 for the `Value` trait. -pub struct _3; impl Value for _3 { const VALUE: u32 = 3; } -/// Type representing the value 4 for the `Value` trait. -pub struct _4; impl Value for _4 { const VALUE: u32 = 4; } -/// Type representing the value 5 for the `Value` trait. -pub struct _5; impl Value for _5 { const VALUE: u32 = 5; } -/// Type representing the value 6 for the `Value` trait. -pub struct _6; impl Value for _6 { const VALUE: u32 = 6; } -/// Type representing the value 7 for the `Value` trait. -pub struct _7; impl Value for _7 { const VALUE: u32 = 7; } -/// Type representing the value 8 for the `Value` trait. -pub struct _8; impl Value for _8 { const VALUE: u32 = 8; } -/// Type representing the value 9 for the `Value` trait. -pub struct _9; impl Value for _9 { const VALUE: u32 = 9; } -/// Type representing the value 10 for the `Value` trait. -pub struct _10; impl Value for _10 { const VALUE: u32 = 10; } -/// Type representing the value 11 for the `Value` trait. -pub struct _11; impl Value for _11 { const VALUE: u32 = 11; } -/// Type representing the value 12 for the `Value` trait. -pub struct _12; impl Value for _12 { const VALUE: u32 = 12; } -/// Type representing the value 13 for the `Value` trait. -pub struct _13; impl Value for _13 { const VALUE: u32 = 13; } -/// Type representing the value 14 for the `Value` trait. -pub struct _14; impl Value for _14 { const VALUE: u32 = 14; } -/// Type representing the value 15 for the `Value` trait. -pub struct _15; impl Value for _15 { const VALUE: u32 = 15; } -/// Type representing the value 16 for the `Value` trait. -pub struct _16; impl Value for _16 { const VALUE: u32 = 16; } -/// Type representing the value 17 for the `Value` trait. -pub struct _17; impl Value for _17 { const VALUE: u32 = 17; } -/// Type representing the value 18 for the `Value` trait. -pub struct _18; impl Value for _18 { const VALUE: u32 = 18; } -/// Type representing the value 19 for the `Value` trait. -pub struct _19; impl Value for _19 { const VALUE: u32 = 19; } -/// Type representing the value 20 for the `Value` trait. -pub struct _20; impl Value for _20 { const VALUE: u32 = 20; } -/// Type representing the value 21 for the `Value` trait. -pub struct _21; impl Value for _21 { const VALUE: u32 = 21; } -/// Type representing the value 22 for the `Value` trait. -pub struct _22; impl Value for _22 { const VALUE: u32 = 22; } -/// Type representing the value 23 for the `Value` trait. -pub struct _23; impl Value for _23 { const VALUE: u32 = 23; } -/// Type representing the value 24 for the `Value` trait. -pub struct _24; impl Value for _24 { const VALUE: u32 = 24; } -/// Type representing the value 25 for the `Value` trait. -pub struct _25; impl Value for _25 { const VALUE: u32 = 25; } -/// Type representing the value 26 for the `Value` trait. -pub struct _26; impl Value for _26 { const VALUE: u32 = 26; } -/// Type representing the value 27 for the `Value` trait. -pub struct _27; impl Value for _27 { const VALUE: u32 = 27; } -/// Type representing the value 28 for the `Value` trait. -pub struct _28; impl Value for _28 { const VALUE: u32 = 28; } -/// Type representing the value 29 for the `Value` trait. -pub struct _29; impl Value for _29 { const VALUE: u32 = 29; } -/// Type representing the value 30 for the `Value` trait. -pub struct _30; impl Value for _30 { const VALUE: u32 = 30; } -/// Type representing the value 31 for the `Value` trait. -pub struct _31; impl Value for _31 { const VALUE: u32 = 31; } -/// Type representing the value 32 for the `Value` trait. -pub struct _32; impl Value for _32 { const VALUE: u32 = 32; } -/// Type representing the value 33 for the `Value` trait. -pub struct _33; impl Value for _33 { const VALUE: u32 = 33; } -/// Type representing the value 34 for the `Value` trait. -pub struct _34; impl Value for _34 { const VALUE: u32 = 34; } -/// Type representing the value 35 for the `Value` trait. -pub struct _35; impl Value for _35 { const VALUE: u32 = 35; } -/// Type representing the value 36 for the `Value` trait. -pub struct _36; impl Value for _36 { const VALUE: u32 = 36; } -/// Type representing the value 37 for the `Value` trait. -pub struct _37; impl Value for _37 { const VALUE: u32 = 37; } -/// Type representing the value 38 for the `Value` trait. -pub struct _38; impl Value for _38 { const VALUE: u32 = 38; } -/// Type representing the value 39 for the `Value` trait. -pub struct _39; impl Value for _39 { const VALUE: u32 = 39; } -/// Type representing the value 40 for the `Value` trait. -pub struct _40; impl Value for _40 { const VALUE: u32 = 40; } -/// Type representing the value 41 for the `Value` trait. -pub struct _41; impl Value for _41 { const VALUE: u32 = 41; } -/// Type representing the value 42 for the `Value` trait. -pub struct _42; impl Value for _42 { const VALUE: u32 = 42; } -/// Type representing the value 43 for the `Value` trait. -pub struct _43; impl Value for _43 { const VALUE: u32 = 43; } -/// Type representing the value 44 for the `Value` trait. -pub struct _44; impl Value for _44 { const VALUE: u32 = 44; } -/// Type representing the value 45 for the `Value` trait. -pub struct _45; impl Value for _45 { const VALUE: u32 = 45; } -/// Type representing the value 46 for the `Value` trait. -pub struct _46; impl Value for _46 { const VALUE: u32 = 46; } -/// Type representing the value 47 for the `Value` trait. -pub struct _47; impl Value for _47 { const VALUE: u32 = 47; } -/// Type representing the value 48 for the `Value` trait. -pub struct _48; impl Value for _48 { const VALUE: u32 = 48; } -/// Type representing the value 49 for the `Value` trait. -pub struct _49; impl Value for _49 { const VALUE: u32 = 49; } -/// Type representing the value 50 for the `Value` trait. -pub struct _50; impl Value for _50 { const VALUE: u32 = 50; } -/// Type representing the value 51 for the `Value` trait. -pub struct _51; impl Value for _51 { const VALUE: u32 = 51; } -/// Type representing the value 52 for the `Value` trait. -pub struct _52; impl Value for _52 { const VALUE: u32 = 52; } -/// Type representing the value 53 for the `Value` trait. -pub struct _53; impl Value for _53 { const VALUE: u32 = 53; } -/// Type representing the value 54 for the `Value` trait. -pub struct _54; impl Value for _54 { const VALUE: u32 = 54; } -/// Type representing the value 55 for the `Value` trait. -pub struct _55; impl Value for _55 { const VALUE: u32 = 55; } -/// Type representing the value 56 for the `Value` trait. -pub struct _56; impl Value for _56 { const VALUE: u32 = 56; } -/// Type representing the value 57 for the `Value` trait. -pub struct _57; impl Value for _57 { const VALUE: u32 = 57; } -/// Type representing the value 58 for the `Value` trait. -pub struct _58; impl Value for _58 { const VALUE: u32 = 58; } -/// Type representing the value 59 for the `Value` trait. -pub struct _59; impl Value for _59 { const VALUE: u32 = 59; } -/// Type representing the value 60 for the `Value` trait. -pub struct _60; impl Value for _60 { const VALUE: u32 = 60; } -/// Type representing the value 61 for the `Value` trait. -pub struct _61; impl Value for _61 { const VALUE: u32 = 61; } -/// Type representing the value 62 for the `Value` trait. -pub struct _62; impl Value for _62 { const VALUE: u32 = 62; } -/// Type representing the value 63 for the `Value` trait. -pub struct _63; impl Value for _63 { const VALUE: u32 = 63; } -/// Type representing the value 64 for the `Value` trait. -pub struct _64; impl Value for _64 { const VALUE: u32 = 64; } -/// Type representing the value 65 for the `Value` trait. -pub struct _65; impl Value for _65 { const VALUE: u32 = 65; } -/// Type representing the value 66 for the `Value` trait. -pub struct _66; impl Value for _66 { const VALUE: u32 = 66; } -/// Type representing the value 67 for the `Value` trait. -pub struct _67; impl Value for _67 { const VALUE: u32 = 67; } -/// Type representing the value 68 for the `Value` trait. -pub struct _68; impl Value for _68 { const VALUE: u32 = 68; } -/// Type representing the value 69 for the `Value` trait. -pub struct _69; impl Value for _69 { const VALUE: u32 = 69; } -/// Type representing the value 70 for the `Value` trait. -pub struct _70; impl Value for _70 { const VALUE: u32 = 70; } -/// Type representing the value 71 for the `Value` trait. -pub struct _71; impl Value for _71 { const VALUE: u32 = 71; } -/// Type representing the value 72 for the `Value` trait. -pub struct _72; impl Value for _72 { const VALUE: u32 = 72; } -/// Type representing the value 73 for the `Value` trait. -pub struct _73; impl Value for _73 { const VALUE: u32 = 73; } -/// Type representing the value 74 for the `Value` trait. -pub struct _74; impl Value for _74 { const VALUE: u32 = 74; } -/// Type representing the value 75 for the `Value` trait. -pub struct _75; impl Value for _75 { const VALUE: u32 = 75; } -/// Type representing the value 76 for the `Value` trait. -pub struct _76; impl Value for _76 { const VALUE: u32 = 76; } -/// Type representing the value 77 for the `Value` trait. -pub struct _77; impl Value for _77 { const VALUE: u32 = 77; } -/// Type representing the value 78 for the `Value` trait. -pub struct _78; impl Value for _78 { const VALUE: u32 = 78; } -/// Type representing the value 79 for the `Value` trait. -pub struct _79; impl Value for _79 { const VALUE: u32 = 79; } -/// Type representing the value 80 for the `Value` trait. -pub struct _80; impl Value for _80 { const VALUE: u32 = 80; } -/// Type representing the value 81 for the `Value` trait. -pub struct _81; impl Value for _81 { const VALUE: u32 = 81; } -/// Type representing the value 82 for the `Value` trait. -pub struct _82; impl Value for _82 { const VALUE: u32 = 82; } -/// Type representing the value 83 for the `Value` trait. -pub struct _83; impl Value for _83 { const VALUE: u32 = 83; } -/// Type representing the value 84 for the `Value` trait. -pub struct _84; impl Value for _84 { const VALUE: u32 = 84; } -/// Type representing the value 85 for the `Value` trait. -pub struct _85; impl Value for _85 { const VALUE: u32 = 85; } -/// Type representing the value 86 for the `Value` trait. -pub struct _86; impl Value for _86 { const VALUE: u32 = 86; } -/// Type representing the value 87 for the `Value` trait. -pub struct _87; impl Value for _87 { const VALUE: u32 = 87; } -/// Type representing the value 88 for the `Value` trait. -pub struct _88; impl Value for _88 { const VALUE: u32 = 88; } -/// Type representing the value 89 for the `Value` trait. -pub struct _89; impl Value for _89 { const VALUE: u32 = 89; } -/// Type representing the value 90 for the `Value` trait. -pub struct _90; impl Value for _90 { const VALUE: u32 = 90; } -/// Type representing the value 91 for the `Value` trait. -pub struct _91; impl Value for _91 { const VALUE: u32 = 91; } -/// Type representing the value 92 for the `Value` trait. -pub struct _92; impl Value for _92 { const VALUE: u32 = 92; } -/// Type representing the value 93 for the `Value` trait. -pub struct _93; impl Value for _93 { const VALUE: u32 = 93; } -/// Type representing the value 94 for the `Value` trait. -pub struct _94; impl Value for _94 { const VALUE: u32 = 94; } -/// Type representing the value 95 for the `Value` trait. -pub struct _95; impl Value for _95 { const VALUE: u32 = 95; } -/// Type representing the value 96 for the `Value` trait. -pub struct _96; impl Value for _96 { const VALUE: u32 = 96; } -/// Type representing the value 97 for the `Value` trait. -pub struct _97; impl Value for _97 { const VALUE: u32 = 97; } -/// Type representing the value 98 for the `Value` trait. -pub struct _98; impl Value for _98 { const VALUE: u32 = 98; } -/// Type representing the value 99 for the `Value` trait. -pub struct _99; impl Value for _99 { const VALUE: u32 = 99; } -/// Type representing the value 100 for the `Value` trait. -pub struct _100; impl Value for _100 { const VALUE: u32 = 100; } -/// Type representing the value 112 for the `Value` trait. -pub struct _112; impl Value for _112 { const VALUE: u32 = 112; } -/// Type representing the value 128 for the `Value` trait. -pub struct _128; impl Value for _128 { const VALUE: u32 = 128; } -/// Type representing the value 160 for the `Value` trait. -pub struct _160; impl Value for _160 { const VALUE: u32 = 160; } -/// Type representing the value 192 for the `Value` trait. -pub struct _192; impl Value for _192 { const VALUE: u32 = 192; } -/// Type representing the value 224 for the `Value` trait. -pub struct _224; impl Value for _224 { const VALUE: u32 = 224; } -/// Type representing the value 256 for the `Value` trait. -pub struct _256; impl Value for _256 { const VALUE: u32 = 256; } -/// Type representing the value 384 for the `Value` trait. -pub struct _384; impl Value for _384 { const VALUE: u32 = 384; } -/// Type representing the value 512 for the `Value` trait. -pub struct _512; impl Value for _512 { const VALUE: u32 = 512; } - diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/uint.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/uint.rs deleted file mode 100644 index ef1adc4a..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/uint.rs +++ /dev/null @@ -1,100 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! An unsigned fixed-size integer. - -pub use primitive_types::{U256, U512}; - -#[cfg(test)] -mod tests { - use super::*; - use codec::{Encode, Decode}; - use sp_serializer as ser; - - macro_rules! test { - ($name: ident, $test_name: ident) => { - #[test] - fn $test_name() { - let tests = vec![ - ($name::from(0), "0x0"), - ($name::from(1), "0x1"), - ($name::from(2), "0x2"), - ($name::from(10), "0xa"), - ($name::from(15), "0xf"), - ($name::from(15), "0xf"), - ($name::from(16), "0x10"), - ($name::from(1_000), "0x3e8"), - ($name::from(100_000), "0x186a0"), - ($name::from(u64::max_value()), "0xffffffffffffffff"), - ($name::from(u64::max_value()) + $name::from(1), "0x10000000000000000"), - ]; - - for (number, expected) in tests { - assert_eq!(format!("{:?}", expected), ser::to_string_pretty(&number)); - assert_eq!(number, ser::from_str(&format!("{:?}", expected)).unwrap()); - } - - // Invalid examples - assert!(ser::from_str::<$name>("\"0x\"").unwrap_err().is_data()); - assert!(ser::from_str::<$name>("\"0xg\"").unwrap_err().is_data()); - assert!(ser::from_str::<$name>("\"\"").unwrap_err().is_data()); - assert!(ser::from_str::<$name>("\"10\"").unwrap_err().is_data()); - assert!(ser::from_str::<$name>("\"0\"").unwrap_err().is_data()); - } - } - } - - test!(U256, test_u256); - - #[test] - fn test_u256_codec() { - let res1 = vec![120, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0]; - let res2 = vec![0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; - - assert_eq!( - U256::from(120).encode(), - res1); - assert_eq!( - U256::max_value().encode(), - res2); - assert_eq!( - U256::decode(&mut &res1[..]), - Ok(U256::from(120))); - assert_eq!( - U256::decode(&mut &res2[..]), - Ok(U256::max_value())); - } - - #[test] - fn test_large_values() { - assert_eq!( - ser::to_string_pretty(&!U256::zero()), - "\"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"" - ); - assert!( - ser::from_str::("\"0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"") - .unwrap_err() - .is_data() - ); - } -} diff --git a/substrate-metadata-versions/sp_core_versions/core-7314a/src/vrf.rs b/substrate-metadata-versions/sp_core_versions/core-7314a/src/vrf.rs deleted file mode 100644 index d392587c..00000000 --- a/substrate-metadata-versions/sp_core_versions/core-7314a/src/vrf.rs +++ /dev/null @@ -1,99 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! VRF-specifc data types and helpers - -use codec::Encode; -use merlin::Transcript; -use schnorrkel::vrf::{VRFOutput, VRFProof}; -/// An enum whose variants represent possible -/// accepted values to construct the VRF transcript -#[derive(Clone, Encode)] -pub enum VRFTranscriptValue<'a> { - /// Value is an array of bytes - Bytes(&'a [u8]), - /// Value is a u64 integer - U64(u64), -} -/// VRF Transcript data -#[derive(Clone, Encode)] -pub struct VRFTranscriptData<'a> { - /// The transcript's label - pub label: &'static [u8], - /// Additional data to be registered into the transcript - pub items: Vec<(&'static str, VRFTranscriptValue<'a>)>, -} -/// VRF signature data -pub struct VRFSignature { - /// The VRFOutput serialized - pub output: VRFOutput, - /// The calculated VRFProof - pub proof: VRFProof, -} - -/// Construct a `Transcript` object from data. -/// -/// Returns `merlin::Transcript` -pub fn make_transcript(data: VRFTranscriptData) -> Transcript { - let mut transcript = Transcript::new(data.label); - for (label, value) in data.items.into_iter() { - match value { - VRFTranscriptValue::Bytes(bytes) => { - transcript.append_message(label.as_bytes(), &bytes); - }, - VRFTranscriptValue::U64(val) => { - transcript.append_u64(label.as_bytes(), val); - } - } - } - transcript -} - - -#[cfg(test)] -mod tests { - use super::*; - use crate::vrf::VRFTranscriptValue; - use rand::RngCore; - use rand_chacha::{ - rand_core::SeedableRng, - ChaChaRng, - }; - - #[test] - fn transcript_creation_matches() { - let mut orig_transcript = Transcript::new(b"My label"); - orig_transcript.append_u64(b"one", 1); - orig_transcript.append_message(b"two", "test".as_bytes()); - - let new_transcript = make_transcript(VRFTranscriptData { - label: b"My label", - items: vec![ - ("one", VRFTranscriptValue::U64(1)), - ("two", VRFTranscriptValue::Bytes("test".as_bytes())), - ], - }); - let test = |t: Transcript| -> [u8; 16] { - let mut b = [0u8; 16]; - t.build_rng() - .finalize(&mut ChaChaRng::from_seed([0u8;32])) - .fill_bytes(&mut b); - b - }; - debug_assert!(test(orig_transcript) == test(new_transcript)); - } -}

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 diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1674683/EXTRINSIC_spec_1055_block_1674683_index_0.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1674683/EXTRINSIC_spec_1055_block_1674683_index_0.bin deleted file mode 100644 index 87c9f80e445f0dcf57d6b45cdcb4e6f896805554..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 TcmdO3VPfD;6l~KeWaI(>3O)ha diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1674683/EXTRINSIC_spec_1055_block_1674683_index_1.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1674683/EXTRINSIC_spec_1055_block_1674683_index_1.bin deleted file mode 100644 index b23ab08c53888cc010f27e2bece9f75171659c2e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9 Qcmb1P;bgdHmd3yZ00+(it^fc4 diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1674683/EXTRINSIC_spec_1055_block_1674683_index_2.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1674683/EXTRINSIC_spec_1055_block_1674683_index_2.bin deleted file mode 100644 index bf51eab782a4c1cb186ebc426ce5c163aff84280..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6 NcmWe&5n*890ssKi05bpp diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1674683/spec_1055_block_1674683_METADATA.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1674683/spec_1055_block_1674683_METADATA.bin deleted file mode 100644 index d9266eb2461bc037fb8436606f4bb5fb5bea28f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137436 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 O!nJjTI-f_s|Nj9MxMPU` diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1677621/EXTRINSIC_spec_1055_block_1677621_index_0.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1677621/EXTRINSIC_spec_1055_block_1677621_index_0.bin deleted file mode 100644 index ede5d3c4d6beffd61b44f165df48c457c79c9709..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 TcmdO3VPfEB=$@fl$jAi%3ef@v diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1677621/EXTRINSIC_spec_1055_block_1677621_index_1.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1677621/EXTRINSIC_spec_1055_block_1677621_index_1.bin deleted file mode 100644 index fb285ea3321c73a6cbb079d2305442c896035f73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9 Qcmb1P;bb_KlE%OV00<%h$N&HU diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1677621/EXTRINSIC_spec_1055_block_1677621_index_2.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1677621/EXTRINSIC_spec_1055_block_1677621_index_2.bin deleted file mode 100644 index bf51eab782a4c1cb186ebc426ce5c163aff84280..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6 NcmWe&5n*890ssKi05bpp diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1677621/EXTRINSIC_spec_1055_block_1677621_index_3.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1677621/EXTRINSIC_spec_1055_block_1677621_index_3.bin deleted file mode 100644 index f138e7dc1b2e439464197b3e6c535f0a6dbcb531..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 301 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 O!nJjTI-f_s|Nj9MxMPU` diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_0.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_0.bin deleted file mode 100644 index fe8767a6faf4912df2c78f046c1746636cf2df6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 TcmdO3VPfD`xL0OY$jAi%4IKht diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_1.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_1.bin deleted file mode 100644 index bf51eab782a4c1cb186ebc426ce5c163aff84280..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6 NcmWe&5n*890ssKi05bpp diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_10.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_10.bin deleted file mode 100644 index df61c4b2e375aa823d524e5b4357ca6d94c544b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 179 zcmX@e#KO(c`a_bTr$b1gb3^(8-58Zw%zbz6C&kR!ch6hx-=0rRH=d=dNf)JBrgPL( z=w}v~=o?yC=oy-s>KPeW>KPfC>z5=K=o=dt8yn|jK;#Yd3{B1S4E0P65pvtO85k@X z7#LbshB8j(V~oqxI<>%Qs^z6U=S7Pz#qV16<$3wW;65LbSqx_1{`% X+wzC+O0%*QX8L~h>uL69>*fLgiKasN diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_11.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_11.bin deleted file mode 100644 index 54f0066a04c8bf1fd305d81375589367e14598d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 232 zcmbQr%)-sk`a_bTr$b0#LGh$%vVSj&t*~nq+qF}7XOKPTORE_wz0H$ubu1KWS}Rad zqMun{qHkzure|beq-SVqre|rUUy@v)Z){*}Y?hM&kv0I!80s0B;+8WtM98Hi!1S4z z=vn9?$!z0hV8~%$VA#{ntMsIG?vL&j0S^NbA38ffG%EHh4>i&jEE8-V%sg`>^A=2!?2t@tMIYZG=T&z;q?At&r>MWm=}uc z1bB2WX>c?zF*Y?WGBPePIW{gaH#aYIV{k7sFf%hVwhI6NYXATMD$JJ4{oqk%|Kn6z z8uW;PMgbO7_Pru(2R6n+7#ur#6$V3H87y8rY3=N8tdA&0zo`2s(iMWPC9~J(&CH*Q E3gBHm=l}o! diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_14.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_14.bin deleted file mode 100644 index f95c3bda11cda5b951e0257e7b07d26beeec1d8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 150 zcmV;H0BQeC0t5>Hh4>i&jEE8-KsQ%k_OpVBD`3>l{K2nMRuVsq<+i1;L4sjD3^m@k z1bB2WX>c?zGc_(UG%+qQGB_?WH8L-BV{k7sFflMOwhI6NApigX;z)=7V;G6zD6gxw z64N0A#9fwbRxDchG-TlxKFsq&;G z=w}v~=o=d7fuNC@eo1nHzOjL^v2jTOM8?Ei&)ihc%v{gV!Wbc&k%G`?sAp)5q;VTJ z1A{CB1H*}Te>a_fzhLR_H4_=wew7_bi!!OKUVHV)#J+r|4|V4>r8TFzKHb&6;h?0# b%x@o;i~9Z%;?d)hj|_fk|L^9}UF}=|sfS7^ diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_16.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_16.bin deleted file mode 100644 index e674b495136b0b55c1c1eecdb84ed593686ec54c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148 zcmV;F0Biq60t5>Hh4>i&jEE8-U3`zB5=r8>eU^X<&xs`=^?e`;C#I>`Mlaz&9avk5 z1aNFGX>c?zF*Y|YH!&_XE-^PWFLYyYFEcPRGc&de000sI002nK-B}jV!IP_4RnLQ0 zBjL`n>}7$OeKHv*d7*>1fFPe@45(`ISYYqj5ZZsI-mv*6_f)j(Zuk)s!?t8H&w>h< C#XIQ$ diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_2.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_2.bin deleted file mode 100644 index ed9329db1abc0733dabd71b6bb5329ddc1281228..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 258 zcmey%%)-sk`a_bTr$b0#(UI%#?iQ=;USFP@oLiMrs+sswc;Pd%Q-5A;6#65!-b^GT zML)B^MBl_r&qUAMLeIiNza+Up-`K#|*sP=gEM;hEq-SVmp=W4dpl5`TO-X>r0tJCc z&k!M#lL3=4G&R#R)H6cTg&}8*(6^17fx(J_fuZJhj)my4_^^0nt`B*+SR`Ow>?XBf>7Wonp|4pt8lCHh4>i&jEE8-?5P~5P~k>ZPolWGtc?zF*7tSGB7zVI4~|UHZOEza4$13Gcz-`3jhEG0001fA8iBFK^JJg^IB6b zkE2lazSbHNgS7Me^9?^1Jv$9c!Yq^5WHz|M!&QRyr`*&E+aHTm(IuFFUCLZc-t&tJ Ddp0~h diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_4.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_4.bin deleted file mode 100644 index c1fba641734849e0e3525e7b4345216a4304e9a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148 zcmV;F0Biq60t5>Hh4>i&jEE8-6B$ic?zHZ(3WGB++WH7++eFLYyYFEcPRGc&de004Xd002xk#AN*6UJbn5OVjy{ zp*)_gbrIP{B@-yV`6(q?pmdht_87%8IAPoz)!o}f8!QAZ&*Y&xS&e{i?X=s^Oo|F; CbUcm# diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_5.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_5.bin deleted file mode 100644 index 46c49c5b90c3eb1c15a26e2d8677a373ca178013..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 177 zcmdnV#KO(c`a_bTr$b0#kK4tCx8n=61#4z~{oVZT@q2FXtyWcmUK?Vf{vKR-DT5;? zLqD^?MBl_r&qUAA$XL(RT)!l_K;PKF*x0C~04!%{X{2XpW}#Hh4>i&jEE8-P{yni_FR`i>!aj`&FiIqH9D*&HM!(BLl@f%c1*8; z1axpOX>c?zGcGbSG%hkTFfK7QI4^W#a4$13Gcz-`3jhEP0002strMziA5)zQGznNN zZQk5JiA~WmUnT-kZ?g-vP%C`^8ZJn%pkYV<|N2|fzY@7Sf4*@T6rE*kSyPCTM8}H? D*6TNM diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_7.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_7.bin deleted file mode 100644 index 1703c3ba4e21716022b8bd43c03bbc55ea51909a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 201 zcmb1SX5nUN{UOQF(;=h~$sDnA$AXVNFX5E&D5J#$k%3llvPQ-owj3PPKqo}sY`LTVc~ z1H%jk28J(h!X1p;sxIUoPU8RlYxQ~Kr?2v2KOKCxbK@PuH&KsFdNv-NUKH)3y1ONt b<*2USip>d?&(@YLd(8KEn)2i8O$}TC|4vV( diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_8.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_8.bin deleted file mode 100644 index 5cb40270f83f9ccd387ba4514df471348089eba6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 241 zcmdnV%)-sk`a_bTr$b1=rT8(&?nO5HW!hFI{_K74mB%k|g|+M7ttnc&)q)uxa|vXm z=w}v~=$n}7ndq5Y=vi3kmn0YH8ygs#7?u=(r3@{N^bE}`^b8FQ^o$U)6MBHMX8J~n z28LE9X%<$7CI(ifCZ?%YR!E9+G9X46=oy-t=^5&o8X^qX#?8R6fPsNQ#bJr`+n-sV zzRWkVomR96qDDT3zFbesL{Ee M8)kbmz^jD|0Ph4*5C8xG diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_9.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1702023/EXTRINSIC_spec_1055_block_1702023_index_9.bin deleted file mode 100644 index bae5aee39e2a03b4191547dde4cd8abdc3c32e89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 151 zcmV;I0BHYF0t5>Hh4>i&jEE8-x|Tqh0!)T)g%{jlpfj$*fNMP$%8;(o9?9jJ4=9bE z1blceX>c?zF*rCbF*Y?WGBGhOF*Y|ZbYpNYGcYqVGqwu=0Gt2-077_g9I*hk0or0I zh`*?9e>NDJ(wEFe1PdyEx5&?7X=aa^i{~BaS8T@YPaX&zJ#h0%#f3VkfaH*7)lf4_ FfeI+&Im!S4 diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1702023/spec_1055_block_1702023_METADATA.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1702023/spec_1055_block_1702023_METADATA.bin deleted file mode 100644 index d9266eb2461bc037fb8436606f4bb5fb5bea28f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137436 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 O!nJjTI-f_s|Nj9MxMPU` diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1714495/EXTRINSIC_spec_1055_block_1714495_index_0.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1714495/EXTRINSIC_spec_1055_block_1714495_index_0.bin deleted file mode 100644 index 3e663d9552ae3d1dd201b11ac9f6e3112580f738..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 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 O!nJjTI-f_s|Nj9MxMPU` diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1717926/EXTRINSIC_spec_1055_block_1717926_index_0.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1717926/EXTRINSIC_spec_1055_block_1717926_index_0.bin deleted file mode 100644 index 629b8b408b9466e83fe6370b04b713be6c77e69a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 TcmdO3VPfD`IOt?k$jAi%3xfg` diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1717926/EXTRINSIC_spec_1055_block_1717926_index_1.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1717926/EXTRINSIC_spec_1055_block_1717926_index_1.bin deleted file mode 100644 index 2c62d84a9a14a6ac0c750a9276c285402426bfd8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9 Qcmb1P;biE#mBGLT00_VW00000 diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1717926/EXTRINSIC_spec_1055_block_1717926_index_2.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1717926/EXTRINSIC_spec_1055_block_1717926_index_2.bin deleted file mode 100644 index bf51eab782a4c1cb186ebc426ce5c163aff84280..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6 NcmWe&5n*890ssKi05bpp diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1717926/EXTRINSIC_spec_1055_block_1717926_index_3.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1717926/EXTRINSIC_spec_1055_block_1717926_index_3.bin deleted file mode 100644 index 01c3e202e901c73f0d46518a67e90db50097cacd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145 zcmV;C0B-*|0))Xx`Qlvs3jp@A;Og4qnHp;>%(-+0a_$f#)}RC2;aLD�=3t>_{={ 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 O!nJjTI-f_s|Nj9MxMPU` diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1718223/EXTRINSIC_spec_1055_block_1718223_index_0.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1718223/EXTRINSIC_spec_1055_block_1718223_index_0.bin deleted file mode 100644 index 82cc68d88577d9f2efb32774bd52a8790f2214e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 TcmdO3VPfF^pb%$M$jAi%4fz6K diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1718223/EXTRINSIC_spec_1055_block_1718223_index_1.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1718223/EXTRINSIC_spec_1055_block_1718223_index_1.bin deleted file mode 100644 index bf51eab782a4c1cb186ebc426ce5c163aff84280..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6 NcmWe&5n*890ssKi05bpp diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1718223/EXTRINSIC_spec_1055_block_1718223_index_2.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1718223/EXTRINSIC_spec_1055_block_1718223_index_2.bin deleted file mode 100644 index aafdc6d9d4c1bab9c2811c51e8a760f01f27d995..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1721 zcmca9)#9^xot07fc1Qc!pKczQv?}M}g(tTkROE&Foaefe{MF^Zk}ry7s@9 zanFB$%z^jQ@2!`A*yL_oxvVJOPBXgF$UHv$ny?6CAyc1Xea6}gujLkPJM?kyX1A(c zH{MHjY-NxD!X7pO4<-f%4z-uYg^wR?KivIP>!e)YGR389OC_#G@Gsw-tI9p^a<~*w z4a2sj^B8Yk4sGMM_{6vWRjT_UzX$UTFgHN)w4!nnb+PWMY)Eg1wbOywX(Sm8KD|G@W>* P8N@5iBwlG2u}ZlB>`}X` diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1718223/EXTRINSIC_spec_1055_block_1718223_index_3.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1718223/EXTRINSIC_spec_1055_block_1718223_index_3.bin deleted file mode 100644 index 69329fd7673572f87808b3876d1e7a99a7e36bdf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 107 zcmV-x0F?is0fe~6C9W;}p`J#TDDI)+QaZ<5OM;uU3MbIqTypBE@+AS#8nP;&4p(tF zr>Rv^Kpb`*iu;YWA;W1DiV(+UDWq}IwNVx#Dp0Ll$|ZTCRUVkxy?3*zh^vqsIO=x{ N9!i9@0CWHb0}8^WFS`H$ diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1718223/spec_1055_block_1718223_METADATA.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1718223/spec_1055_block_1718223_METADATA.bin deleted file mode 100644 index d9266eb2461bc037fb8436606f4bb5fb5bea28f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137436 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 O!nJjTI-f_s|Nj9MxMPU` diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1731904/EXTRINSIC_spec_1055_block_1731904_index_0.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1731904/EXTRINSIC_spec_1055_block_1731904_index_0.bin deleted file mode 100644 index ef2ce9775959b5ef1b03a4c09b751ff196bc8262..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 TcmdO3VPfDeGl_95WaI(>3nc;l diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1731904/EXTRINSIC_spec_1055_block_1731904_index_1.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1731904/EXTRINSIC_spec_1055_block_1731904_index_1.bin deleted file mode 100644 index 95c6312684b5ac27d5db8e26e6637df6981defb7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9 Qcmb1P;bi!f63xH`00_we8WJQ+fzE#?6mNfz$$IVU%?wwpTEsnwtbS` zYul}pPZ?Awy_p)Y{1V4;*0Z}N+!Kqx=cb`E`SU?VVF9iKIsVJee*1VtN4qt97fZ&A b6ZdZRn=*xDs? diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1731904/spec_1055_block_1731904_METADATA.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1731904/spec_1055_block_1731904_METADATA.bin deleted file mode 100644 index d9266eb2461bc037fb8436606f4bb5fb5bea28f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137436 zcmeFaJB(cUeeYT2E!}Oyya2tRu{6*Ij(w?h^=$KqW77sr(Ofp!Jz`^;53`#yZ)`8kKh0Ie*F)MN%!}@dU5?|JSh&E;olqcOWWJS z>0r`q{?3(+>(|3ytG#c;PlKJ|4SrZ1^or+;S^3CvchbGt_=9HSH}SvLFS3ojBHNkn z?`K_KP}XPW(Ls089}Y4;W!>zsJDT*jr~6(02oJ3;=hs%APe%R0xW9cz8)-DoP5=DQ zT8-BCvW?-SyPp;D=W%8`wZSILwmlt9v~;Ao$nKEIl&LdOUP8jI#DY_i&tb2PJI(bPPIxfSR;F z@s}6!i@ud+V`gvXwWZeY0?*k~4vWvWivD0XI~)zSi}ASV<=J`x9vo$z;(4(>ofMmf z6P>*MuqzZX5H=#nUJS9rOm7He!n4Cs@w7jjjsv2V_&Rty@=@g!fgFE)mU{p~Rxc&L2DB)13 zvsFx<6~zFiG|^aDdsJ}DV<5mjK%_uj3t(}Nhn^PO6IdAQGc+#7-#B5d4zw|gjjL_^ zO*4aEggJbWakkfeS^%|4F*@iE*c8)`8NIt(WYD`YOemx{ECxL-74|7Cv~}h{t3O_8 zf*||DXJcRjm%F^Z-`CNJxb}gcjigt$_qqcRC4;>dX^P3HyZuDt9u)e$KR(bNe=dk` zcgKbH72n$_Cfj>9xnN(}vB81$gM@kGp3~{m?*6o3Z%n7v9vv20=d2Uya0c7mDKqwW zvS&rcryhIVKg#}YI-W47hVk>aBkbslL0Tp+**tc7an^D7fL#wcM1dm!ZUBdO(rq@g z!I1x(^mqCW=j>UZLpFPNtvjAPLQ3@yipPh$ zBgnDQc<1<+tH?fRAvokO-RZjOX- z^AC&B7T=2LE@i#`_^|6o-<>#!^h!Ah=Vf4-9t!6)_HG|&Wj0oRaa0_1M^9SwoBkon zkk&rr_XJEFa!SL&WzY>bfgb>E93--^s>0e%L{o1&@W+~Z({TjK% z+r`!rV&Gs46%0!A*E`by<;|jScv?;mLea`wYydbpa-RFup2Q z`et$TmgxB=XQrX-$n0k=KfI7%c_KuLub+QX9F4Q^_RZGw>`mcJ<;|VZ@F2arXz#*v zclys;7yaLJOe;OjUWCKNhfx_=m_Za?%rrn8#2io1C&Skz4*F2}{CL{m?n9n)MHos&YV%bvltr~Y-`zF#~G zwnOVu_^{do50crEnQNXw}>Mwle$Z;em-(KidCNKP{i5iN zH-@VNEq`3hAx$-LeZs({Gmci%nz)s47$TVcy;onv#LsPGsDtcoM>!Ifb?%=s|6P+H zvh;*uTNDFvNk&Gq8*Kb%R7*HcF+z&(?+c?lcaS`#xIukk=|e;R&LbBsVd_p6@MG=% zaIoyidne*}3#qy8v}8jAg(Rlp$x8kX;OM=8_=!M_KJpt3`(KOE@KLd2YGCWH4CK%n z;O*L*|BatZvV#Ozpef$)@j#vlj|>380+^0=L8s0mD0Fx*fVA!mLB;I};^>Y2{$caf zUs~7voqJ&LsNdahHm-vweb;8uzEe)&9H#cN~b$89%pnNn{qRVyw7LXUYEucVPR@0@-K+r z4r`YNv1}MK-0z{8Nf+D8WlEjD-Q6mh_TNkGmBZooo@rD~EbYI%n&}Ds4}Neb&=MLw zRAzJJi%U}k*{DAO63xc91f+KS>S(pMm}&6zg`3+8G7$D>hU=E&-#dG zYRj1WXD3H~$)tVk^@9$&(;u-ZUm7rm-y-f!27m#)14#M5D__rq+petmD}HuC2{NSv zM(8^|Vg3pj##)0PK;AA-+3lk6fDaO4NJxkie*+{n*gK9jYvh>S-&mXaf#yO2hQE(Wu8dYG^ShH3Bj(f#zo5#R81u`ks$ zsDTUG0XsdMvZw7ldxJ$5&$|bQ`^93pIpAU2hXF}gM}3g@22dG0HUb0?;@M_qZOO>n z-WwwLW!7~E@X2mZth75iav#s(bc8gA%#pTx+Jmp*@-~WFCcbp}$zb>l`G$SQ?uR?$ z{MvmO^e01z*1MTr4tQK*M1Ezx*p=3rNb}GC%q-+fU(L#yz-=4=u*bo8GMd8XhJ(EE ztL*K9!veZkvocABJNSBnfg7|lF;BTlU^OT)X3n{rDu=!Ex*o#{LJrytY`&Z!a5BSN zKr;4q8e232;2T-z@%`nMN1JyZ++W{#^!U!k>Vx~6>nmTnw{m}Db8Y4Rmp1Np^2RT- z2Vf;@3GV&8V16N7zlntaAmk z%B7|aG7z3Y_=a`!fy9;{3x;US353DdWtwlKY&i@Xi>m|p9`y6y(3cumFGpL&Tce#; zV-Bco6lj4X(8%??ti8Qopg+RTgSnaQ^apy^Ec%7O$=GUV9RsL??SKt?Sd1<^f5H{u zQ@O`fBDK2@hILI>Fp2PNhNHxs84e*C-K9vly>xpe zgMm%=VRS4RP)Sqx{bmrxdA8oya_l*AmeFvli;e3J7w0x&6Iex0Ibxv?2Gs4 z&m_yWm$Oz=&cB5!DgTANBKU%`y>K2$B^?LGF4rDc zHdAj-^Iu1R*+t_88bZQ(R^^p0=VtS{*Pws93u?Ec>e;eeUaK3WJ{lU}W6QGP>*q$K#4c(xiKnN0H=Fd6At+gE) zL6r!9;tmmzSRN5pX%j$dgFh8Op|UsyvchDEuV=+csN8XR?z_S}mcY|~_Sm29EtV*> zVL;jg(`SQ;!49^Lmb1=1Nd91Yfa|3{?7<*^Vsx6EFX&w2gMKt|tq1tVgzlZyfn?xd z!h5Z&wUH{v{k`Aw13%yQ4PfbNMsXdcWE^*b+F3#Qw~J>ofPLcv5C7NeOC=SR237O5 zNDr@tVHi8S5nN0nwVn&743`zCK0*25%ct1mO!K$HDLl+&vgAxL81wts;#z)yyJ&|a z>30QmI2=83jo40%RYcdR%Mt=dTkxuqMdVqL@45!D1Ob}*5Z!#eA^L@Oi1{6%0L@0b z1zZ&m8Rw08#Bd*p*^D1rSuk(MjppwNhr^#Ht`Fttj9-{ayx)cQm|uPYLDF)+-2QO* z1c_h6&@F@8~2YJx5P@E?F<~hJd>*ykoUrK0SMU;60isJtKk=O_vTknzi)gY%p+}T zFb4hS&LQP$;nhG{4 zG~1Sgk83lZwL4)e{+av}9_B(*us!WGN5$ocZNcJ-{OE+;%2 z7-(lYFm+bjluO|9@K7k=ayog}9B%(wNV6AEBZB(nu;%>Es3=aO;%{be@GH_%Wb6oX z66hMhE>ZCkzT-&ouqvbI>~Oy;6E6yG9}3t_2Z_#u5{#V)SV~cLNN5e$t%h7*x?&@k)l+Bf1^ea(E z(C|CiOQfiulxoz?Y?mHT&A zvZedW+25{gWOtX|;*YFjJ8duI{qd%JKy7r5NQm~+_e~ySpPGv(P@#kxiWe?{*W|K$ zO?nRAupwGk-dJkNg{PGS)!KsH=FbW++{T84oXzfph!4=BQC7v&10lPYCTIua{K6Wx zw9+7Is>z{Tv;n?)pbBnzHRirYQ05395R9gWmr+Rv3QOYIQD8PGB3YW{^KsqlZfx7K z*%%MXqZGmcL3LjAYZWUs;%EoMEHHfsk%P`Q7r~_E%&Kw?TmYRYE;?@6*vi>c zM|2$~u+YCY8YMM=8x`9HF^p0E$IWEcrpS|?bxITsig+Waf)N$8%uZbP8wD|De6T^1 z_&kKi<5`1ZTLlRv2JYfHE)uXh%d3GF;UI$#<}9o4ENJe(bB>!wm{z>y5;$D z+D6BX3IZK6zuBa~j;%i&)eV5xrD$bP{x1y#DE-KlIIHbN4gOpI-XEU@nvLv8~0 zr(6Ynxs>&!Y1QV4|6!KF#gzPqHHr_&l2@=(*HP3)#Xjaeh#b_@0H_?J_p%O#Hzs5; z2t50J>=+&`9c}X7@e9ZKjK$#TBwkaD@Cl;6>suntij?ga&+Xq}y5x;Dkwtyl>kU$g zG6`T=%f$6?a$9afZ`6He=3RIHS(o^Ga1&N$5jHDaQz6jh9aO0lvg-jTPDwsSt0-HKx_{N_fr`8`t{*p69U}~=td?FsfXBx zqU)Z_1a0h*_@sD6F&IvF_XKf(XSQm|&wVmnc1qT!M+j0S@%)!6{)$-Ti;IEm|rEF9#Q4oWPeS z2r0Y41`pbG*m~Zm8JL!S5!QR|+_Sym%P=bOx=k_GlX%q?{TMBPlODMGjpTC+6PqKy z8>l3$6TV||%ILYfZ?4K3&k_Q69tEF5;$%p&V2bCm-SjqG(9#)So_)1D8`3kPX3|;6 z;Ua-|u|H?LF#WjC#DrhO#}=D7-Gh@*FT3wCazP^4aME^XN50ujXQj!lLkN4jU?q+3 znznH^KVuyoWq0D7Q#>#FE#4E)fC3ZWa`~2cSN;PYATaUr9Hs8Bn6XgKT^yTadl{tq z4T#A(IMhn;%+63!@qD{DbYKU1h!&vbzzUU2{@HSqC^>*6w+R0ww`sl>39UlOzX=I{ zk)^LI@q~42Azv=pz*me-IWtg77mWU;iT_qMOZ^{ZfAv?NPXZLrSavj=l752_tIdf- znIJs!#t&-WUx&C9_RH^?YMAd$4)*^GafH2LFOQ&UUYK7Y@!%N=LZ#s`9|*Md(QHCa z$l-xf*_$bVVl9!P@=W}7jnu~z2Af;L+m%#pOCk!&F2NHbs&NqeMd=}yC}jq%^8t$Q4(e!Yl6?tTDl7=!WZfM}B8lU{?%FD<&xUrO(*Wpk_%a26ZQ__Tf^Z3gEiS_&mRv(? zeL(nTKsM!eUm@vurp9M+9$vN~?%E0+t%7^8dBS(CWu+)!G~7eq?;ny~KEgXt{*hJC zY_9tLZA>{{yAlq=;vcsfvxxaqLrkz*FhvhM?4ni*>B(Ub;ae7i>HT2;7mXn+x|-K! zqOj)pO#l6Ve6F&zMk|EAUui0ggv%=1$q4Ryenm)k8t;)$R{4DH;^P4!f0CkpA&cAo zSdsC+O17#Q-7>82TeVFpov2n|t@f;tVm|Y6E_xDGqfxWw2_E$_|3z{my74UBm6P+? zgL%bu#2D>I+1qkioe7Wflx7t!6{WHA4Q{uq0 zVsw+0JoG3YXQW|RkUxlrY5s1==zOd>z3v92+(4Y#Gm3eO&ZQkke}@vl^IP`9c*&Q? zc3NKx5IMf&5a-KrT@CNy^Ym9+%anEvEng|F=SoO0vjW_8&faZ-Bv?F7 z4e7;s+!UgRX8bU@au>^dI66YQO!kyEM~ct}2tWUR=4hq^A+9C5GUm?G@ipm{yzx3J zbfqE>Fg%e?Cc5Jl*``_N%K^PMHOS@o?j{0iviHS^d;0M!@@?D;vFHO&9fD0ucPhXK&H z+ws8|Wp_#l8p|77^BSDKPx|wa{2zj@0fyokt$(o7AwrD+D)&HwgYhJg7jHtJ%!0`{ z-w5&c69*%0sL?_*3eUV?Ecl-p(YPeYWF2f%B`_rNEXD(yhidUxph}Tr4RuZT6&5Fe z4bNE)q#4*hyaX2-p$573@MQTWgV`=cdY~LAaoaIDtH>NwQ=R=b!Sf>|)HZn)I5<@^ z(NzwAHn!v$j_T-7N5#EnhL;YX46%fmrUXL?YC9a0k;oRrdfM}VooO8avQ46p=L^W$ zQ6kC?nm(sr-IAADMb&@>G8sOT30}Q%e(^R?DSD0O=W5Kc_6M#_?LdtFtGIgtyfR?RaKBYbk}pzQ z2F`e2$wKxg<($XYL++-spm)0?OVbuP1q945Ag_ypOtspwmLDl)qql5|gL$+Bg`bQ6 zgFAYEWDmf6EhV6mOmhHB&oe460(A;Pc{`yrZsqz^CFwk*JYuYQ*yaXPQ0?guZ)3;| z$Oc|0F;MHLlG1869Oft^WpRZJV0uLWjWjq~r?_M=D^|LTLK&-2FP;5>oJ z>I~$|BW;I}?LavIJh&*OAJtjv4jMk0w23_ium9gqi>c*C;tr4G{GNoa<+G%!w7@$d zX5?y)DI`{E3*Aef#rAJ_%9UwkaEkM|v{_hq+gENhEXHFq?2$w+p`cU_5jxNs;e&S> zR(;R6s38I%;3tlBa1`8&38SLMU}-#hKKcMsbicFi35Tn4lkO1TzJ5LJecZ`6*w=Vn z>qyVBI?yDY2|2Wuv1kV*3}t@pGm4(D9gK~XRj!5D-b@nuX>nE^qD31I9{ug+^2$T9 zS4~7NhWVcmo@o9~W!5S;`1;Co7&ac-8j8;Fh|irvNL+l5yTqTB+)g`H;u@>U8{HC% zpdSz?q_ewkTnqR8z|8QZf4)fJC=n%MpCUvFp1|6|4%2~G z_w^R?UxDf@ivNq@LW@Wk2kL)8p$2A!$nA@?AxQ>&EP3NA$FYs)Lm=k29N7~1O>~`# zY%?P6bFIb&f@bTEBucp=!@PrxfRy5p9X0$tV2xLCb4eeFBE#XN`YWH5vHl zIkfx@Hs-;`v>#K|9d8msStZno45abL_=RO*n5b7(hBydmxqZ_^k7P%lz(rz0jFoY? zK*?`u9AEZBsx#!1X$|s!qOkN45<=*xxAPFih$NtHg5r z*x(!@op55T)zu>`Jg@w&E=~(lTEA3f%R>zc3f|#g5`XZ?wJNI%r6&g}GETnj{%Cu8 zfFR+4apunBUAamJ`es3%74olf-}%BZ8!Kq{kvpxb57a1TMrAQ28&5cDGMPm_YOo~( zWy@MMt<@1zO7934yBTi6{$^vMDcce67YRg`+L}rR&qHuaGAFD>hZ%8rp7-}JZ`mNG zgy~Rq>aGh#WOGHx5F%<%AG?1-=9WoH*;dtdM4)2H1Mm;*7S}(*1LCS}aDZ6A98}+o zl^kCTDzo`OI%|oQ8e*&t*jnQ>#qiyBz~(w&7mzY4K^9;Q0b~*w4p>S~;<;4b2r!PE ztUba(E-F(e40)8~;BHHK_R-qyTgUG}F1(vl=Nqi7msofW&sl8?S$4{5lUDI^t39@^ ztF{~N7tQSCA4;Decz{mR%p zWsG^@{rZ=o9Zr?(Z@#$w(%fG+5jkq4BXg?6!7j+@`!C9vfm-)UVl- zCg7zix}Ag*$D}YFyxeA8oaF&$Wp*`xlbKx`__znXb7c2N&&|t3w>`IOBj$G1PLM_; zI9853QkLaWK+GDqsmE~zce5IWT~L{PJIcB27($z}t^~;~cMIXOELZDkU|*9XPFyVD zrc1BzlngU-*T&(Zom{%l^lHa^Y}13yFioe7lS@)43CH~w+ef4!z*%*`XQwU1iBi&c zkb^Zk${V+0g0}PanIwlFzbMHeBX|uHBEnM1LsABiDmrrI+;8kD1Z}b|TfS`>mEdpQ zIEa~u8_$MGhT|%dG7vJX+V~LmcdlP|iP2fi!rykt9ej)kDRPmJk(<<}6kYjaaLyr! zfRKUJk6JAe_V+`!SGIXVKP4~u!wdPZTQ8roV01G>BKBW_Wp85UtmqcO1|77HOv1p zvngiOS?0S(h0N6rSe2YgE}i)^DG2|PI3xgdE(*d0 zXSlKwkKAsHNfMGo9$6O*bV|);ERTcZlXoF2LdGs6LzJ2`ii)l4OBly`3t}?89z-38 zk4VkT7K_cG+G+ILh-$z`XG=4Jl7cGwl zP1&+_vQA7UAdczlvYbQK>Rls5uHU!OJj+n~M?E5h0V}bR43CqBCGJ~drR+ZKEA*9;Le+?_rJ7x=kDYCZ?1P17|@nH^yoZbb%nqZ60P!- zkX^+1F`N8y=MG%y`t{@6`w9V`qW9}?)*%Vhb!0O%v}5NeK@E({gY5BVSq&x0ZRQ*M zq@+~RPDxM3nDWNmC^8<$^T-?DME{3|)#>nzebqDQmMrZSL_0NwE?Wy}xXLp+#II(F z%-|=kv;84VMfIN*TKpy?cqiHjC!MGz@rtKi&Q|DG;0Q*wi;37j7N1 zFk$hTiGEAlSC%V7nB+73@1o@y#$#|ZL3j(IEDmH4+v(s=9H}9MhsrRQ``vdL^aLWy zk1@1%Sxvco3~L*A@y|ap;b~kyv8aHYW&w&BAUednAghj>m>zGEKq_fAZ~TRn99E4q zPsc8isODBqM)eahKj}$2j$qUquA%;-rYLTzq)`j~{)2rcm5W(^q*Pvg3G3Uk`hzKmL_+?R!+XSq1+LYUQ@yil!hN#MEADzG-2WANf9C zlp%{az^f?C8PmE$RO!=GY3L`HtX|`hJ zzv_60?T1L;DQGemWJayuiAFGIoQ(Z{F_f*QHh&6j=p{Mur#_nCoG4oJgb<~-e<*j9 zd|of847$1a`^{6%EsjaV#>d2N_$@s_^fg&tprf=xcfpbkQi@8+gVMi5az~(wNMZ>D zMB*Z~BQ4Em1(KQ$bpOG<)%#28547INf5L>fseU(vH!*8$DOhql?!xvS#L!s$I2{mqCM8`JFjE*(A}`J+9@&3fg4!@y5O^eF9s872@=r@Ymk9UL zn-yP)db6JBGQl&|enc6t0>ffKJZ8$Y(}qz7Sprd!_>84}+9R=^xg|VXujmz9{CfSk z%8?{7gM;heicHLKDD8-HZFR-x-@n{h6Ws&`G#t^_m%Kw7BGFIePH2ck8t2WHXP?fd zAEx(c&yQfC{lH+T*u%JS;U7a+0Wmn!Ay5e5eX5Vr1Jbg{1}9supm%Jo3`t5lhHTUY z$%CynJ&E&>1k5;%i}zytg6c$NG%u(hDgy|XWi<+zXG@l_FW-Ts6$RDhLwJ&L3AN)U zDnq8A3Pfy+y#;g|{LQp1oGJS}d*RChbSD+J`jKd??&ogC;Ks(k|97d@pV$~_;~74Xx~ zG{*kGUp>dss7#|yC=#T{pi`%oTgW)PN04O*sMR4;LBNg$KdTr>6y?wVY~kkKx4kX8 zBy}1F&C5qNsi~h>W#0HTE9!uvR`IJnmV7bA5+WJK6=`pbrAjJyV{{mb>}bAHE%_~CjKxsoNM<1x=nnjhg6nO;Qb!QRC(cgm)CZ>Ap)bdYw z1}Q$)`^%PQND>wEq)7F8gC&)6sqbKbd#UA zX5;*o7GQqE+T36X4b1K@5VVtnLL*TgO|MB9yHJe?*$;p zIOUbdW*Y3`=S(M}EKWIy4(M{=VHHQC=kx%eP27X_%)+zRfb%ZvV-Yhy#Ur%g9 z*D(YamBB?=KSY<>HjtH2(+o}DMz2?SnU{#QmQ^}f`)XM{2i@<+O2~G+d9G(_ckL-L zswur7H!@e{QfYvcznowT*TR^leUidG508yO1o(s9OXdoPn)$*%w(%NC12BsgJ^Twc zlnb^>o`$5GD%91G#KH*tU5z9t;=?-8gG9t9L_bWRQc{On6gYCJ&|*BGT7BO*z4W%= z66x4dLaCbN*kHnWOme^2Aq|A0Vjwj$o|iWfCU>HF8pcw8DJk@o)F-W1FjRq8 zN=r#Fwmmm5Ui9qClS68!vF=3*y+F(S-8t8O`*n3>bSPT`K#Jh~o9xIyECvS5p6Ms z;~B2RmrE(+b;1~PsBoN4b&x<+CsClVg?J`WD5dpiVLHta)1u=K&gRbTu2t)GXfdP< ziA0Slyy(%zeC}FEO&yc73FoTe%lZFAc6RHqs#ba)D<&J{0h;7DZu`u!A$ziv&(G`K zpI6@H@t`RQ>@3?4(v);|Lh5QfP>v?Qc9kQ%lRT)cJsl~>d;*c_mvwQ07FS2uLp7d| zUk!!KS}G&~S2mWRV~K6&?U(f6!!E(99$gE|`Gtz{Y0M0M&abSf@MpuLA&eS6iGvNC zIIJ=#zqX8xWH#ceOrq8@okqeJZY1T)p`P4`*dKb|vphLs2BSaDHQAx*}fL}Rh^Vou- z_EziL=_S_vc|ApLqsZw&cBH%f9=6xmkmmzT&E}hUAcH_o4Kic=><4gL((h~9p-GVBwiu;GdMZrw(V2cNkTA~&h5Dbs$|bA4#423_A~&`% zA4C@IB3vBJSBtqDYr+2wOZ46V)-fP-uLvj}D|C%LSPgc5#dC<`tu%E(s46ANgK%q< z?G6YTYJ@H4SN}$Z%)L7}7rE;y-6Jt4ow8CoBnCLzKN8D}CV%FHsC%cBKk7Z%^#IWU zrm|Vem44f}VJL=_pGap8ZK_3WdP*D2+rFYVxvj9-cpkm76}T9e(a)+$QTqNyITXwy zdX7ViMck-r?tRv30EESIi370@mP4kkUjG?12UW?w3;B-ag$7!5S}kseFu1*!-$j9y z9@k52Wdq6EPPN{9aBp|Pa|mdD_Ha2KSYjDcP%&{2@L6eK$ZS{eIy7kv(`|Z|ziuMY z%{m~yg_ZOc1DD5wLP>tIAO#oK9nNWCtG#*tv|nI=-!cf+z>?rt@giC`f(L34&u|ah zyuAUn>xwZQ5?o?oW)3)Ayd~P&T5EN7KO}v^03>s0mx5_04c5v2cl!nrfV++6Or-EM z=L8XY${mg8>=w(oc#?Ry?H}5|rp*Q40qGIOR=S3^V@)MwCu&sl;=)RG zWiL!5Dzp4-C&8GN@q)R*j}|Nv##e##1LqF0JW@(yxEBD$B3^t}g>~NWPGHd#h`B|! zX5f<+9n=5)I*Gc|;e8Cu2W@G(p<4i zrT*n|FxStDm4@cFhx{J*avzd-Jsy|}E#wP(L|Zad6^4$&5mYCiR~=-ule%9#TX!im zV{3C{{FcyNHeu9w%sj2C4xy!Qq~S;+CT7aa0Bd3Oendz!rWi!mPkWP$@zm<=^Tzor zLAQMB zCR?WWCRf_-0nJ?;WvDRt`IGGCH1do0hdeQ+`w&C(1(*fWSLQHl#jWKq_>DL0S}}|) z3T1J~G-toKu=vQrb$6{oI!XT9%GY$IAGy}L#-gnI6vC7aJ69gy8DV{Azw{0cI(tmo zvotM#`QkkVuBq4+gRacuSG->_ZfvpbL4MIMlxoaA%8EWma9dlmK}EDGSA&JSRP|P6 zS%*ffbniW&bZ1OopU||^dyD-^zPOs&6P3CKIv!VEGcc}6axc#7zwbuBWPQOm=YEw5 z0uRwdZt6aLXv)<)v2yr!BrCc2;o{`8a`GIF^ZIM zxv=}KETULFRXS}N-qAwQ-W4PX{aM>j&zg6rI$-9%M1o@Pu-m*5KKMJ6ql*`CVNAHl zV1FH-G)2$)OF196>zMy_YXG0>$D{Ha?3gCe7#y(QA0Z@Kcp{fh^Zzknm z|C57Gs8nLD?~KxyEhTsApt)ew>|JMY=E2Bdyd9>P2dE?L?%yH9jLAu`f z@I`MZM9-55+C`hiZ?m5JU4ZTWEP>UDA^XxJ?%Q~{L=d0lBnR`%>igDeNWE46f#wFD z5#-B~J(&ECPNzN;!Cqf*nEVgUn%ozB_Uu02x6}Mu%}KNSSmcK}zX(i#*0QJX-O0oq zFj9YKHk8lPopOCR9JIbKN1}PwjFULUM+PEa$C#%A6DKKZLYU{^0R@-?RPXrd{I$E- zdXp_KE3}NflSTE#*PWJY+{Oz7Ba&m34xiXbD&=o44yq)xGTqHpKf4iX$;D``Ji!uX zqB;lL5!IQBBbhJaR=ZsZV83SZM^=kVA{f^Kl={Fyzelf*NS$%C*r-9*+KMY-tXkR% zBYQR6vo4VjQLPA^sZygvlBDd~Lh(}DKOTx8q@siflfcErAA*9AKwxd&C;=M;%fr3h z1N5Y^E*s9zOVMj4bu3Y@J7Ruh%PnUzQ``8Z&7?F6yKslqr5WW7v};0o>2SyNpQ!P> zOPU9_K=C{>88w{Xu6aOEJBOfFa~$3mIx$H2ZYK?*I?DI54sI~ew?E*b2lIg5_p4V- z;&$?DzPE7Mt9qr?mLwrpQLEL)^mC>u&OxrPwyyd}R^-XKeq0eoc9dwU%sfO%*xtHry~Q{5HY z^Xa(u-Y%Ut16j+XuT-?LVeyIt^Im_H7W#8L$eL)wUeeh99oQR%oX7d2%RMKiW8sJ1 z^dKNf<(mqs1nFtcH`Sf8r1+lelC1d&*`YOjiqBYl&#HU_>ReqTEmvJzwiFj`Hcp&# z?(>c(O5wFU-TH*A0C-t7tlWqL6mJ`?va&o|`FjOMCPO+H&TQ1|0+wsx59J7TPa5D> z`IcIZ8lKHA_Q&;SX1HmE5JGg`84cipjGA`_DK7(n$cYJ3gh;9b-)1hA#9n0l4Z^x@&Pb zi;sx@LSV!jdt87~K8JhPVb-y4lWkw}D{&7f@NHNDbgkHj#Eq6}JAg$Ta1ycAn>MJ} z`DF!$&ByMHZ&4B__;22~w=Y);A}{N{i^|jC3clGj&Y1C98BhvKb?7^*aoXwvaPd`B zqP_Amu%eJX8$8pBCt6n+chb0a`ZrDXA+^E<0#es|+1Uwd)Tj(4{-$5-2XfoV*^o24 zhqkB7cEEB=p2;`XkmDN`Kzh47UU{y{%kF*|zQcsBhVNu{Bnshzaci?cUv6v|t&H;|iX=a$y4r$9y%tL-GdNWtKRICG=XkvqeMwK?zIMIADs)WI-uS;ZI3F$e6zY=WkR zGYDbOr$}T_>F3UEJ=edDf4y@efGxSYL+hb&LF)Bzw5KO4Dun&+2{e~(a|7@bl|xkI zu5~r5u!~c~x~^(kVjGr410_m)J}o9gc$iuqbHRZLvUjP{)!G)qmw?zE5`Ad3QB84e@9jEgIs z(lPyuiT+My1gyByR=+ZS-aMRlEvcBh8r7vu=^IghIjiN)wGVX*29S`Y2tVN7A~^*D z-7=}6!V~V&Y5bw%WfT=0XrE}XYvuCZY8%l-nwo9}%|$~aPVD!uIfu1eA8pI@TI10n zFCcHIn7UKj3%72ID6}n~u~ZF#ohwngSdI6LX@uvi{Mq!ztR0sK2XXzrbC1HpgXuxg zEOjkf>hKa^!}WW$qQkc4@jKh!D!{SuP9&5i+OV~aySvYqI?iCVIA|Pk9pqut!FNiBK+nR!M^U7b))m>s0 zRIV~Zs|o9965X0hoe-DiTH=EXVJX{Cq$&Xob>nG#@uLhsv0n)iO3H8oX?z|xUxWaM zGkP)|lhHBE8$W#Y!^;~#6P(MvJ8{$iU196YY%4(Vq|Qqe!g|8t*bi`ZZVH`}UqxQr zspnx)SjTL~^s^AX4M3hBZEE=6#38}r-x3gK4oUtg`JeZdwIv3otk0J}xnI?f?qB8P z{`nP8&fxg3e}1=;u+inL2(wm6YP050o6{-VwxN2I*S}Qcl%G(EmR2Y$dFuKI>P3Is zsKf|_P^el@N7Y2dq8l&E<2qIG`yiClk~ebsRVc=HT_*;-|M8|?9LFShsN4<2la-;i zjZe91rXxHZjq&`&?kTW}%0_BT>{is$Hl2SIt&=6V>QPGwSB4W;DU~&kMOrqLj1if^ zDMnY-3G0ykvR@=+{o9kjgN5W0pY9 zJkgL+@c+vLZSPEB0TqaTdNI8ZPLJyUOS^6bgONWa z-zecdYf(zHRTPhoaOAYkW;dRQYj4P%At)y-Gp)jbpv)k&pc4$H7>|o^OGb!_1YIpG z&nCR@2L+43Tw*`ic)E<&d{BOriGjq~QNJqfPrpf0V<)W_*~ko(A#wQbj`eFzmHfy8 z?EJ&TrGL(iau3{wImNVo`3f3X9 zu1YMsf=A9u)G;d>Zs#;(^3n!=8*4vXvlSc4i+x!O{1Iiqo59Dy?7@6}p$T`ALR!(B z>IfD#=OqKJ3+A7lRogF-1Y`O+0FGxLiwppK+2$tyB-{H~C}r~of7jfp@&J7rWTW3J8W@ z9S3Yp-i#~s!z!U2#xB2LT?+8U0P18yQz}j#My;vR5o-q2hg7V#B49-(3YsV}*Kv}v zE4}HS?Ko})i}WMm7}y$FyA~4-C+~`BK*9(EYvdn2+U0&Dsm#^Ps?*vOp{gV z^gm{yA(m9X2&Eh?YU^Rtypft}FUL*IXs0!vN$@IezH#+OI0xci28i0x;K9=Vk5M32 z!N!o#kBVF^p6a#UY^!XlW^CGchq0@0>* z+^NC-9n)erJqRorK|=)#UonoU1e`;X?gY`eiGbqK$_o9g!n+OzQSnys`IL{Ej?$D>6V`ei z4~$((fa(^aON)FZR}c7SSQibuPo{jCemcAHK;UVc7F0-kYrGo~;$Z;Yec(8Y5@?;# zNvzC2^RGc%!ByNjHl^*DIVO1H*c$0J-G^|8)Cw%d*6J8$Cx{1w%)^1y&=(!$6?o$( zI?AvP&n=6f@H70b*qhO6q((bJmA=I@Gam?oNSXAXNJst`JEo6b?Ud@q<5d%v3F;^N zx^Da`*@|)%D?6o^2!#)RWTvHT>)Q4ZNsQ8-PN$Yq_XIk>5(PvjDnP@V}Xzh4t zFY_d1;VYs6jbo0R*T&p2p;SeOA6hLSuk}~j7I`q}E<#f^gH>t_8iAhhDz{+ict-K&TqkD|Zt_9S2tGx}8DR z)^J7ux5h!*vW3L)F`iG_)zw=xqlCLFFT|d5|5DIjq~HWQ*!xMb67HK3z_U)Y!F+U- zl-_J7w60}1h$;N?)V(DQ6Ioz*>7z5Tmcuomc>_05r()TL&ST}$woa{%rl~#`z|bn? z6WG!YaZ{FC7tE_M>sdK`FHyd!s4gx!s_1H>tO$g^{sEg8Nt8dBuH)_yd=c_4zjyo@ z&VZJ$ls4|_fo~jtpmdLt@+ozyJ88Ndq1mJ~NBt`zlCsud=0iG=C<91B%XMuuVgfR< zM1F!$vgN8;kH@h_D%x9kyi{K`i(XS>S>I)x%QDJ|)zctpVv9k`$n%_~xiqo$vBzMw z`29YV%E+ASR#Z>Z^_Ul9MVQa&qow+KwHN8t?*@&3t1z|iDL!^(0p^YG0RBZ?H>pfI zw+$+XP{NNnud79&9Q5&y=enH`Hhuz7&Hnq@DVyh-+aCRk{4h-QErDq-em}fuMD1F0 zJhbvj6R(6AR2cxbtwPb>iA65<0Kq0kCV7+ONkK#y%pNO{z4nFvPyj!EC@Z! z2*GxD=>jrv0O1$Rc+67bog2KAl*i#qB%{?0@{o<@rnTqjd;t2Sw0pS=Dmc+GN{5+Q zsKx)7@!3|M4kndh1@ML?1#GVKnQ823w_eP|2+gg!?U)wBs%t4?auWs$6Ls@5HaI>y zIE)^Bj;w&RrRo#Gk-j_`5{>9ocx=aX0~Cof2M%nlOkxWP*CKADP;D7|F$t;>mSp#e zmsL1!^(jGh#KDjbJoD0U^eqn68z$}fLpRMh&S!#A;6b;dR= z#E}Dhe#h*JD1@?z(!WI*ea%!6@&w$i^J!d`?~?ep{E1zbt`wn#ME;ro`*K*~x7zr0 z{Lv(4P}37x{Ucb9m{yG|WFySC1BpN|MJMtC^O~N9#b|eG>1~z;iP&n{KPHclmJ?O~ zo}_^5fzh|-LLff`lg(nOVf$}~OZ794DoF8L=uy4pyr=3{{rE+G)f3nR+U~zQuPWl^ zmAOSy(In!JF$>7J`%i&6NRzVQkLe+aSA_aRq_4N!Ll5|kcwd+OoGL2BDQ4Q$4@)ym z?}(dAR-Rz40iczWbd|cMfoX5T#*dO4k|LZyqAgSuClryWLHsr;#m(hd@zR?s3yA63WA%Yn ztbTx4LO~TIOxyuARmiw=Hu~+uVdfV%tg!6d@v*L{Tyx1qsQM!Olrp8666kV{P;aH9 zslZsU&#$e7Od+4C(fX#ENS~MmgZtb2}`Y>R9; zQyKic*q)vQ4y(#)O-|fX3^Gu69wLdAw%(W0;kJG@+t)j)sIhR{s0dTAizP!$I`V>i zu@YQrRR;XU?0{(}#wx<~LXlyDtrJU;?kxQiG zzrLY@a{nl*)5!;nGpXWMc8Bg0u?E5TtOjbXkBOeU!DWURF&T7Szze zHS{Vfe`gkzjj6iVj?v1pbZTkmZ_K#yXVQVsH~w#$cKyBUD@4CkxTj9_geK%o(&VO# zcVBec>1n^pKt5YgA8&;KU>AY`5O-|lSJt|?UG^THly-go`~PRNK^y>$?G6+BB`f|#3aZ0wR%Bj zEz#&!;yJnpuD%u-#_gj?vFx2eW}y7v|HtPlK(>NqLAgxxhz7aovgRK! z%iZD!&=a5_l@&;L+2M&k!B!R#+QBC4Embq;kwA5c> z%oBbhcy&b|owA=FWi(%0CDr9QBR?KI8PE+C=<)ZB(Ad#c2s8+iAiWQn%T=Qt3r$8$ z@Pf4E)R!kNgkC-IBkAx2f=MG)NCTky+EXbzv+S48`Yi`3le_3Gv+i}>Mqk7#pw@S+ z2lWYutApk0Xr5&*uW(olQcR+~bv5;WMSI(8-yg=sv~*v_@d4v~8LlbNK+hW_!G|Im z30126(#rF$1Sm2(kiSJkec!+F)#pd;w?_n~{KqR?JwT|4^#n$-ks#_TTqF%0-&sz_5@~=P42rjD+XlzFAs-4M~mJ2O(u9Lb=Sx)?E;N8`;Q?IkS7pyd^4;@>g*BpII06@!d6 z&0PZ>;m!;G@_e3w9uOLC{o1vl=M>j)8H!|zv?*O%&TSr0xX=TM8Wv@2z{7%O_YU$) zcK$ZhUj>coRmVc5wLoN-MOJlYL1;;dzD4Wz%b|P4tFP2T)qa!yNMuQu?q)Q1VRsF!)7gv! zx_0LGy!nk#9(v4Oy~8xvL4Zc54su-3j|!a#aA+U#ryJv3y_Q7`$pt zG}vyrbb^{eg-|NhKwUWsUF{uKwMozhEC*k!N2B2rU}agp#TI-Skoyhb9`Wjt_3goS?el= z*>+OaVapyA=j#SKj`N0T5k~;^(FWDW6NXD=V}s zVHL8k;A3G%QI?T5nLkhactvOkd|^@5Fk$?;MRfW2$8k_ms>2iyA8;qsa8NtYn-{;P zODSv_CA@Gbgn{X5A8w7VOb~K5Wj=%js*R9cr8}r}6tE7TBL1H%vT936*`6#XzFTG; zDaciWXx?}Sf3YQ{;#HuCD-dr!AKU_ESC{9vhtF@EN)$KG{VH3IDU%hG)EZ$@lW3=e z?IM}Wxn-Su_Kh<0#VnM);-!0Dm?BqueCar{rQSf7$o2OoQx9Wxn~!U#e=||%3)X(V znsNMfU>UFJj7<=v5hAV>xuY;2bMAXQv=pyD=%iKXW+C}kyQW(}u6`#@J%hoTx139B zOC60&r{_K^zm78!v1$G{=Yt>8+wt-T+D zgZQMOpuIHC7ygkk$ZtwlP76-`FOYrqp#6~Soi+adUd-MJMLnH+*5Rzo;PH))?Y?c8 z(8HOZXQl0;r`&bc>^Y%QNFJw}ZLmu>`cnYXoDZ_A=$$W}eo53BmAFT^!T{#Ts9M6U zWs#3|DVr-7lsfD=ur`=iQ;`?Q&}2QzObR?E^C50U=4DKV)>;=NoqHF`W!XZER2M6& zseZPm>u0Y_B&PHyNzdBC7On6PD)_^uR%dR!_7Mt>-f%93VDmrxMba7ktK%NkvBNqz{Y+8)M{1$W(+ zd4+i{-ceC%@cLH|y!zPy9Esj@wd}3n*3yl~iN6VUQ#6Em*@wOf#kPWJ04tKd6Gdg! z>)%FoGb7IZmC0FB*xu+f`CDBE(xu)C;VpP^z#zifJN_*ODBlTGw{zjxn;_-f6Kg`MCS;F zv1NWVav>`HPy;8N-`yy-_t2oa`-oX->1Y3%{OoF#pB(M=OIPfQ3lDcjw>xQimOAL>sV+jzvvqf{Z;>`* zUV?5k35kbsw-E(O8c@XPM*jLHcIUBa6nMicWg#+J;u3pmQ@2b|i7)M@ zO@DcT1kV7KM~XcYUns*6OK!*cZ4;#@NgfN`A;#0V2MDuSEI3|1OQh=g_WsoRn8A zuM4RqoHTA#vrY7w86&^ z$)eR|f`0CRF|8+WUi3cZ7qqkS@gq2^b^i@~Jvy5ZPLpF5Af>VWW{%qN8^Y)zBNC`E zZ#*2?^?~Syd}gI{DOw>*jM}+oV)mGHFSxQ<-F!AeoP;op#3ezmi$Ck z<*#A>4q=uKah(`825L%I07QZz;bdI{6>^REO~*Lms<0dLh9V;EPxVv`V;hb+xE z&bfGWD>SlI-vIlW8e`ph1e|B?bDZgW9I$|1z;yTT-d$(xNSq*>ing3-V z_=IlNj}-X0ZtY+`Ciz9N5B>GlLU2iT-s+f(hlWLOX%AbX7`BXu@Abc|2MDfs$k|FZ zM~(SER__k$I@s|L5M7q!Sa)*Z1Pw-dz#(I)AA)4O@?PK)OkZ;OS1ZeZeWBJi;Gy5~ zsZPDBd}^*7cl^ zs8J>sR8R0UgnU=e2y=v${4^%vm3CBl<9)bAZMpiDFRTXInEZ9T>Z*SaXQgN@dx;#T zOwu#@v!Dtt>X=!SXZ@ULvA%KaJ+LPR!|yU?2E}kCud*2v>EYlM7a|m7mv}e>JN?W_ zt4=t3e{HyXFJkJww8AvB`^xV-0^5NlV4i_3w|s|cAuoo#ebl)6JX^OrbQE|oSc}xs z@9Gr+2lmHdZC1b@%KCn3kX#c0LtaV6X$cAd9nOd0c6cEiSxEcLaa`*dxU$+FB7NIC zTLcg#$Ewe#01^ocaPD1?MsxT`A?(>Ln(nGutp>Xt2XWzWSt`IIR|oj)PTI)1g16k7 zEI2w7c4Ba2(%WD>lU-$0_5BeYpFyb~l!wNd-CxMQM66!D*N4iVRo5UprJ+6bLRW%{@n(%4pbfK=TX}tY7X_#Z%`i<^qR>s%gAk zR^yutr|x|TJx85n&7!B4i!4LA**T4rtWTydv~>>t`0_%;Bw|e|^I0)-OO2g+o|P$6fe4y6mhy0Nv0VW;ax6%}7k z#a z-5odW7H-bLV*SooDWinp~w%R$Oo=zu_}S-d~-(^a}HPiioX)a%`sif7S!H!Viz4 zhrxcLa6~D6;LCEjaA~%-XHtmQK zuwHrGdUH(T=so2X+KXcHP)fYl7){hcq68(fdGEpT{iXM7^OeO;>G^T~@Lu=1s;}&Y z6$+o#<&R2&>O#vGL(3m2v#O2B+iSyTw?oP8$F+Bi*xlwYZB2;JD!qd7mfwibdDuPD z8MVG@rm&%9Gg95VO9mFK;l!&#Y~mQi|=K2)FY>xkZ<_td7e5!0mK zKYdbveRkf(@iY2A`-pQFUBuKU1`4$=E_^>*=N&06o( zaTL?Vt9SOg7}a)q;Wu*f;>)a^k!HO+2K`^<$~A5 z&1V+Iy$9qM`*>=b;K*;sTOA=>-5W{%Vn{%PvWuQ7V>ej4X9xNbdL@*8{USu}=u+_# z8l16Y@~iiZD125%`sK+ZIrhF_tdNyA7NyX=w4ss`5?KRIkvvVdt%#W4&R$dyNn^vV zMvKHqZ7+-?YcUq9%MsEwv_gx@E_gXQj|d!t>k4OZloA>MPCg(t$eDE9?bPHs*% z8Wf=vT}rQy*jD&-A!WW=QcAOt{`O2*DP%~5`%@Kn$kP_n4TD`_;?hdil|Pr4H8fn5 zT_5V}4?|K|t*W6Ovbw3L%2!j~;3;z~Ssp0~%FV`ISxIqVTd|5w{yB}Hml3ztKM&v;LTQ{!gmYLf8WI^rX8JwcWOwm0{yZJF2)&^ zGreEPM9shuw@btelm;MRciK9p;XsWiha^xZL1tAj`Ckh?Vfv~S&})=X(Zz%D3oKW< z>*!*18_Jx<@>h|by6q$>{#H74L%!sD+3vK9M}JaYk3geJA5#P6^Vqhm2k4~wrq~ai zjm{DO^P=69fQ}>9Jl<*Lz9F1wwy>ZKIPaqhinvvmFw<_g&z`ld?f}E+)P2otXMBA5 z0t+&ZHm&X?uWqK9h2GS~CTY!s-rQLMrNu377MC8`9UZ-l7v>UP)rTM#R)x?C89AQr z?$TLT#~@R~rbPZIsum0Ijkrd71Xu*v*irulKqx~!=9dXRmy@b4Vv88ua~2Rvxy;rY z9*}G#GS;vW?`z>3IdQFde~%Aq__yR1sg<$hsz7*vHkfXA_JRRai_vM9d)@G*srj*0 z%C#2br_Fxvw33xyBbw}*?^q6`mFU3SB~c=e7wacyQu0bw!%{D?uUnOUNkrDePqzZ^ zc%?mL#9y3k$*hWd=ICWV?Bk}vcSyO1yKm#qX(O@=x6LmVaH4{X-$_ooQ{fPgzwWbo z2|&E)nklydH@nXYDNa(2#T+6-kiW8~fUT9$Ej^D50__W(STA*)IpTs-FcX{v9>mFT z18(nk`-)!B2sMNrjMouI!jyrJ>=d*t{*lRPl+Qz@lSf_3-L_!3<#-Ag6sMk?Q`kG&9(OY`{Uz-Q3I`Z60Z3d zRNNBS#8-hEKkh$o!02#$2XJ`zT>nGt0@CuhfmV7N1dNPK;_teftQa zceLLQK2xKDQfu>F`7_$ZY`;QEbIfrJUMiLxX}y!RwSDxMhfrg9gjqLbve1FLFkH4d zLmy~c4J|Z+-s{~9Sf+O52Y5)?4 zH+xJ%lqn)jCGb?(XQ~WbUCtX{k0`w%USP<=RS0Jx_9aK`jfKwXsQUw+ku?%g*DM;e zSDfJ>G^mdcJ|Qt9or%Qr0m$cG#B49=K?7#ZnY;EY3yB8)D&Uu_n6vvLN2;2~#99*r z^p<2|nH!+Vt8v-{_*v|VEE%;p7?0un#Et0;!OfLeP`_=gk$^GmF2O%?*YaX4aMBpK z5gd99(*N0Ty5A!Mi)1cjyzFULZY(57$gF>;dPgS?U=)%V_*zg(hvas6P!c-g?61bB zmu%(Uave;RFCA;*WM)m~(nhMitVGIuNqP7cj>BbMU9Kjwl!0xOCzy>C`)K;gs^*Xx z4w(Rz?+0BovXzSO;Ib|X@`}|eLCHKYr5TbkLc*P7;(#$9v_(;_n2OZ&&Fc%Dv*g4% zpgLER52w-6cWFCeOe&C*ACHJic_!YIDjHnQZx*czj4i zg){&Aq9`D`f;|M5ZS)USr-`gLDIt1JwX9JQ5PbpzVsRFq^lmE>o_czlY?Db(jkus= z+VowuM+xwF+`4MGl%l37Dt&=6RAPN8c1rADV}Qrzx|IkzL07tD1u4fhrE487X|p6F zHb59j4sMg%pHu}89yZ~_NeW9vT}fAr2=cRV`)$=YPCnqD&z!Fm*M0$asc5@8V3(_v ziv9fkbg;t16BOxjT_H~a4ta|gZcj(FM2jmSENSy2bIH&=wu~)3%o6A#q;^u} zYp>%83ji~cj@TRSp+L@w{9`{x`2|Oef%RbSS`_zvT({5ZyJUWj`CyZlff8(N~iANy~{_OZdtRSKCQ?KnR#Qc9rL zV%3q3F}JZyyF?OMCJq}kOkZpp4+4Ik1y_#sy^)u-%d{Z_XEC&}aD^o2?CO*u(n9Ur z(An7fkJ*@5U^ti|Hn2YSN^l_!R>NpHy;6*Wq6|YC0J!*uSw`bGibC7cHd+^2khX+1UVOlBg*j#I z;_S<_!_`V!hEpmqjyW$e0%ZQZ=nE3dq&ou{GWo-hkr7FJ74m#eJ5dtM64k*`4f%Cq z&q*AyiAm$R-QNXwbzr`h5W8e_>oBG%w)(qyZ07l3$2QR|NbAcLA4nn&uGz>~nq68soKK_h_^)RM&r@dV)J zm)4ON`wzh87Ey;db;zSpVuf6&MehsFRnbJ#-AvG!=uAV0oEH`?bXP!3(L5*x+pUO= zgtes?j%&ABdPmoQ0msxe+MBSXaWnjTF8oVa>Bb7X8Wqz60?asF$2Dvu#?-j5F{D)u zE&2ksJlMIhar0IML;WLOXqGV8Jz>ayY*$~cM<8bdc?(Q={&^M#%f^y=Q~XS3|d{p@BI zaWCA!Nk*Fee*K&LhHGK4)87RglI?^7pX1R}d$t87K?zkC8vkG#xw35Zw=P{&a~sEo zjv!5Kl9PMhxI*k<)Fli8wO#)ydb>a1?ovIA1ThsQ+QDo-SX|nw!9h9)FCIU!;BzYB zAw7r2*x_gmQ0yb@|3j>8U#oE+@fcjKa8Q=9J?d}qWOobAG;dtWZg{`3n;4-RJXm%g zvw(vIS~wiF{~h(!&eIfHEx13RJs3NPd(J->%~-8}a|HII`;tlnX8Xp&9XNi`qC7@V zitX+06X&VYH@nNMyAW=|FYWalT*2FFwoldYHQCEi(DheJM!+J^X)#*X3Q4-xb(h0G zlFup>x1?+y3O9h-e^ZDKS1zWNqa4gLj6$}glX7Ab`LB{SCNn#($2$Kx1L1;RQ@f;^ zAA9>l-jP5Kc6cn6g z@g8=s^YZ|W&B$e%6iU5+^oz!M^1ez^fsp6v?9&{L^khTS^8zc^M&ccWRFhGXZIuyY( zi%=2Iu|u3g|0ao9KoGJ<9JKfxs5bb-*yt=Wnfr6yBP#qU>-i-s;U@+q#JAgowECzkPXn?JMtn zl`wPm=K4KjLxRJbQ`+fsRfG$J>#aX|$wATaG6p#$BqAh7{eAxUEDKmY~-a`z%);4kwSL?W#|AC|n<@0|wV}`YNlxrL41{pbSU4y{gf|Eur9l`B+HlGdqM7Le_()==>d`)ufhjdDN)8 z+KZ_YD48T+3V4!_K0hKYT|vVjs2nQS&oA6nb-zO=G==fUIq#FT^~owt`ZRvz73dh}-cb$#`}u5|Ku zj<0tev0SdX-KI_TV#a?K8d)?8&fyTyV-YNIr5Sa9Q~EHVd<#;-6^r)c9a2+nrK7>X zO1Dq<>5v-hZ7#jtKO(D-81>LZxM|y_Ur3;%j1+yYx-;DriI@lbfFz0o4dCmdcA=I;+Vd0NMly*G|0+H5RZj-=t6 z5EYeCh!!gW)bv3^IYI_`V@};J5xHZy(ZNofjE?e4%l+PCQ!g4b6a0Veoj;76=Y8jQ zbK?UY@Bjwj0SdqX6CHitb(XJ5hdIzRL+p|(hIA;AAy+bEDA-wYXT`OayUfn6MH(&~ zKt&En;lhOq7cNxX0WMUyFmMJ=g>g`!!Uwo;k-|j^6)psv3l}c#^ZosK-shc}C6|)o z#EFAg+?jdb=g;r?{r~qUQ+yzwX$grG98{-ZP*cS2s)@OxOcri0Qcr?dn)N$A6vkbeY8VfTehQAkZ7Ik468?M z7GI_$IXRma#)WxhZ8Dvui(;!N8zvuXm)TqhF{U1yYm~P1t`@;2?Mh!YCyk9=p>Dhf zs}i;+kr=t#B>YHjyxVte03BJ!7Snb{xo17NDDMr6&naHH;l)5evKrkTdwNIqk8V0! zq|nR_*`3|LAWh~Wz9+m?_M?{Ce@$Q7mJ8ULJ1=oviPdY`yD$(dBU2hS7#e;W8$x$u zsYc6zRxq!5)n4$rvr#3w$c)x{TNP7ICp-eOGgTX>IyL7?)g!G)YhJZ$OUjO%5a4)} z0hGV1&55A!M7p*s3E&R)u?X+d-j)Pt2}2U>s|SMu1`hUML3Nv_^3iaM5&3=q+EsV=zt^p#5s zISBXUr_?XpWM#!{sDJp3N4*~zAx|$hOXpE2F{Cw)nw6K!wI#-iea#d+w%@ZX1T2@k zXg5wfEh(2ZpZ4SNgP!etI=XlZakb4Yl)Gz}X$~(jVw67Wa^-^^B(#4#Ub>srAgUn%g{Pxz) z-e}hUIeBi03wJmK3#bftajeD{=2iFmK7KaNHvE-ZTd=TQ_`)%S`Wxg;&rvgrdu{!i z+IDr-5Oq{f;hpDAOqagz9Kkh`?%;1IW-jr;ZAmK)rCdhiCx&a~x)4Xt5ppV&XVVn) zUJ7;G7F#i^rP6^MQz0V!33JNGmIiizccpVek9Jpno+>a6yjj_UE9+ zc)dHD1hoduy0YtL<~x0(@*<6Q-hel}W5WR)P9tBz1c;s+R&Sk=I^4!aDhHt@8y=cFI~p0WRmAy???lXDtVCR_*@4J$1u%@+J_N@F}rs0l;xdFhcLXH{4Yy zd%+U$2p~})X_du3(=4=f& z_TbyDaY*BpD*=#-lk~qa+>MAKiL*#}1M~)m&L5mBUs?7%OO6N}1E*&$fh-)dwTQL3 z_83RC^_c$VzH)n=5zSzJxFdI2XXOp1uknX#_yT8U{(jC**$>%5FAHNA4bAsvj{gb~ z&MI&ri@Qrg$!{r+U*k&e&VJ-cQ*0KxiotZ=H6$k?%*sLjBwgu7Vxo4N=o2;r}W ziA11om*eDc_i*5gQ0rHXTniI0RmyWO(+qRc=?Jyd5P^EWX~+8fU36A79PSA}>7spS^;&btfG!PfWM_Gly1+m#(^LIB<;)Ddo zcVf0Pr~4FkQGg`2U_ba`@~|ylJ-#G>ro|_L=i*%HU3-W+XJup#pwp-BavpgSAd;VU zXG{a^A0?aVfCGRDNAfsF{nN^o(N(HqNZ4~eP=M=H{|p^EZbenblKFR}xZJ$72|?|4 zO7$*wT+7m2&Ja=ZS8{Lk+>wLDN<0E2;hZb36u`>J@CdK(<&6ONx&9pd?9{x&w>f=d z`|b`Nlk}x5PEbr`kZU#M6YBU>D;kD)A9I(@b5fO{BHg|%%Y(FS65!2Ku*cHI(op-9 zgR%LLk%1lmZ^gbmEn^It6lAC1WK9>%Tx`VAFkC_(PGJCOhdcQAUz6-MKGOleF$i3X z_b*y76~V9FhWyHX=;-Tc1I}as94y?Z&A6k7`Miyby#koHu;ct^2Bt@rAS=+m336ynBU{#@JUK0h>O6Pdd^4~%rp zjp*#&v{ogXg0+6$D2?W%3aQL>w*L zq{VAk8J9FO2q`;-10%bD5v6|`9~y9Am<5hK5;C!>Ys>PLx_)iD)?RE|_aLC5X*vG`4muCYec zf?%ZGWX-#Sz^pJg2hr`%WRYP{na;&im!p`UAXZ@Fww^yl9h)LRx^{Q8v$YQsm@vB>mi}H^N4nKC+?UgEH z2?WLZYT12AKp^(M5gZzgR5bA=FIVC(8-;vG)d5O-5Y8Cvo0Fgzi5pPsv41^mn6|+UzWeiK14p~~p<9NQZHhPf3CApPQW6Uvyk;^y}a4qB2W2F8p=zFu7 z6`WIdcNF@skNn6%=X*@+%_BR#r-)pd8TCARs+mDhn=DQ6hn3)$&<@71Eb<=oX7|95 zNShBlOI0ZQ;||QCix}UdV5T`|8r?wa0YfPPHlHezTs8|LD~%Pu;1EAidn>NFugr-w zoTRdj#F}60w}e@$-0c<=%l7{C98gY71JyvD z^@bFHK<5_ox+e$YDFN*o?*Vn0n4XH~UK+k}y|rn33-yOLiMh!-sv)DrmV;|Do^#ua zNRM{HIrUfzm4U5r%u;LYMjWTfqy_+m1?$>C7^>YMA08UHZ%d}4J3;>t!?;w7wx``$ zd*IpM?ys%ys)Iu~xY<&uB-lb{(`L|M>%Gp7h^bZ!$BD@EmWt&yMbXT@YOQhdD?8iE z#@vtH1k#t>U%2EJCI<0IMaOQ*Rhmg!VWswPA1JRyjwpqWv>~zp?z7^G4Ht~Tw2N|p zR+VOP=vivkmj#BiyM=EJP6q5lESBaz*Ct-rgTJ z*rr#el_z+grdXVupX#iS2=d$`SA0D8sCve38tJFswd!Y_3(S9oQCHMI)w}N%=c;zT zR*Qm6j=I||o|ssj&Ac*geGR2IIsTC;g@!+`7t&$^9so5%b9p8jYC}iPqneqs%Yk{< zwn^_X=MRZ~ZXdbAtoPDeRJn+n<%(!|8P^C6aaX{Y4)XJIIGf?)bmK&t+=Of2@Z^#o z))t5Jc3u!CD+0aNmX`G@BeY)I-nVUp7D-@Ywokc$Q-vGvZ;Lle>kLC@`m{p*cmSqY z^ELfa=4+Ohya~ds!uWuKmg&)`3U)1PY!*s}&-yU3A|(`k&-ZrV*dy-GDO!cp1+_dz zGj+07V5Ij`g>O;dly&Ke89XO9ESwVY#KR#iSwp+to8*FB)73?Uenel!26}!D;E69G zeLOk`q8#Pnh_5uuoWW&}5d`*dkul$a_Tzz+Ilj(k7X6vRgqzcs*>%Y=c@$S!7$~Go z>LlAllgXr%x8j8fm8bjSNk1FX}(~=7uqc?z(uJaQj^B{i@K}rIefpOjey(dBa@-K z6Th-t>hGSsG`1VljC_lp04L>}9|4K0O6Y&aD7bLQ@^dm#&Y~E}y}a&PDvtLj)PPok zZgb#ngyevOH!aQ)a8gRCjNpff#9UIW@ZK6R+BZ=9k6?TUYv{ z$K-`RIE6+z+=@(;X5pqsHr1Q9P1}x@5dI^3ES|6ywQc>=hz{NCq0064Jt+=vX-qHT zXa<1dLoNF>Zq`L1HE<`}#N&}qC$ruMM##yloWdjr9=6B{R8ZjC_*tA*L!*Mbq%~GK zGtU^r>V3ceGGSQNFLF7cdP_W9gYmkY^KG@3`s@k%SG!8Rs>K~UGHH+>lY^lEu4BF( zY>Sh?;A~OWaVsBCTS(LJCQIVOZFA+cfQTX!`)U56e`RfxZVsCp@w5|UlA3T$ZKYq{ z_J&VT8hEUYz=r9BxVwfXo#t)Qh#7U;`07Q|o1^!^FUr|mO*5e&0xfoJe@#79iJY6L zu%1ff^@`}%GTvq)&RxN|QcijGwkK;HR=PmR}xA0nlFo8ef zt}57oo-j*WMrSmyHWGwsoSn?P<;E2vXQE818n&5vv-G=;BeBFpm2HK>(p>L=z_)PZ zka*F5dmJzPebXh1<*B+IGyY!;w~O7g=ye5ISsL1tkrAxgTJ-`3!}yzp&d_0GB0%1r zn$Qr3HOn!a1yh_JYe+5QWsDX-OIb+0tdI~U9v558Ap8Og2OYT3-_Qh1!9r_L;T4p& zXbqUzWJM=IckE)JVV{;HrOm`Wg2XkhfSk{Y)RRmTB;fb7xF!l?o&w@Z%iJ-+t487e z($S;SJa6Eki@&*6$j-T+t@g(q{}f_Yw=sd-(&^kFX^|+fF@wD>g1W-6nE}Ji3ebZ4 z^v)mvrd}4rkEj}fe)CSmaXtxsetna~1{$n`0ehT`NjQc__}A|}+}TlV5p~zHVmM4K zVPJu)0oseQBL*w2B9;;22kGRA$lGvz#Y8B1fE|Kb8Dj+w*qIaWO;Udxln&O}e7H{2 zepQ3}X_!6`9-9)w;>@Cfsc%xv4$#^hnwqm)(DMa4Lx3=bWRc4uQkL#!7->H!uh9*B zD$Z%jfReAPIHfQcoe5a&k$!fBpDG=|%x;&+DHG;P#r4Ivt@lFtg{Gvye}H_w>jzv@ zixA*l1c5ApZFK+z#3(3gPYV{$H^skCv0JsJkJhgpQ_Jcz7TGmz^E|dHh+RR%111)}AS?2-nhc z(56VfWo%Ob&L4xgEd5{v#=&{XnmKY)r|krJtF@^^nZ)Q_s<1wKU8T#BEFFA!@*ReC zu>VlW#_P?UcFb1t<7R6|UFlF$QAlC{ji;)I^&t&&bGByYxcMW(0q}wxR-@kie!*KjsJI@8L;=!)Zwm->JDg}?bpJ~EcpG^O=O>xcY3 zbbR@mpffjZty_`hc`#XRCd?i`epihqP{Cl7qgQ2kURaTwU6Cfq?Xs8o{^C`7hC!ne zd)_2_qZDkKQ;Fp3Uoan>&{A35(o_+xnvn@N-B&O7=Z0ywk_dc{H)U@JLjERU_d34d z3J;9hnSV25aT;4<=y3LTkY-k7)*Rf3KHsie<*DO=L1zC!Vx#vOD9M@wpXW(^K9yn9 zZWks`w<_9$zK;7I9R#E5-sbMT{Rb#YaClv-Coiv92Y1~$GxToPxdMZ#?BqY=B0b3h z3A&(Tc~%v^aPOVK$36poaU3Ec6C=36aSr3`ao2Bz*-PqvzO z74vhLD(Fn^RWSJhwJlC41?} zaSI_F-9Pi+j%oN;FYP>6=*A~;DbD9)0?!YWC` zR#@R4>{0p;?yOd6+W2*h2JmsNtTBd~8-X%|vSk2w#`Ms^#J+LP{6GW%yO4C`e_qBI zh}5nOHe-l419nn17rptDe}+AD37^uG*8Ha7NRe}+*x6OWfIL8Q?$)5CvR*80fJ|oj z*zi|y|L^P$Kz<`(=M3ySZqE=^=S2gqV8L~E&zV|l?cky9kBW$#9zn!*h2B!cVcn8* z?#Z+KO)D-d3Y8gUmURXXUyoF_$z$>HLp4@Mavcz-1gY^Cl1Eg<4U{-zq*(dH;(h?2 zKmj)hj350;R=m{k$GVH2eT<*dzpvI zt5$^0)j3&BUTBOOFy$6!g(6(=XC33qxJ)Uq@6J;{h@VFxUvUNpq_ZpYW)#rNJbLNI z$_wXZXseHgomat8DXw{*3+kWc()YE}sltpKv|x<-KLUH>2v(EjNLt}^R1(AM!>PfWHlqNwB88iLZ;PW^zxrE@*XD55z7c5EF_EKTo^Xn(j$L3k8aFZE5(0 zM_gBg{0s@%y@x_QjA#IU8$SM3{&$(#=moA8JZ)2%h(n^wn$Jbrdx;sgT9=}#-tk5m z7(m8uNhrOmyx}+}Lt}DEtspC#w{59@yCew|vc9IaQ(p3HvVs=s{?t9r+}ZAcYejEc zOBZ_rCygO@h${1(%NMWqj%Ld=pUG7kX8PS9{r_qR5zB&ui`{$cCN1)-?IOSGi+qGb zd%Jlz_Is#7ZUfezb-{{%Up622>EHqoA~n_nQwFXegVfrDgeVgM;v(0WxaIc`MA~rWj$tL$@XG3?gkINg0Gj?CdtN%It zDWr3Q3nB1QB6Ti{UL0oyzY*=@q%g@6+=_Ygt$(#T$M2K~G|`Yvzf&Tlef%p_A|!rH zi7={)(;64qp|htvY-YZgTE&D)b$~`u=@DoVVXzeKp(`inv?S!@zir|8+bPk0yM@*T z%!qr#t)jku1ewKcEMY6JujF6jM)DLXbq6VR*(OILuB$wxtDSlc+nYOzL+o~xd~!}6 z7r`D{p|ybhx_UlrJ$}#RylM4C|8pfCbEv3}G9Obf{`YPjVuizB$}y&Z%EO#A&+79) zPs0avfOYoG&XaO`bgX0Vwplco!}8kNJ@h-)IAJkJOmwwwT|+WWhnH#{YWg0J6xG|m zYgO;Adu{f)#c}`V5#<@2T@E+Q3vyo`fxhiAIi-pLD_@P>Qx{eamV@fLX~}m@XryP| zzL(ciEFj97g$!WPR^buy@7Mdle@ktmVthXs1O>`Oa+xHn{LDY_K}T zw+tPxG>f^WrEnisS-y8#j(e#p&#sotDbN)v`RMp^aqooHVy2Xuj(`(~*#WJ!Z8_S4 zh?*;PW2LK<7~qIaImPYB{1S)$oLbz>Hy0v8 z=*ULc@f~x^=*beLwu5)$+t_(JNggZLHnDW1wwJvBJ%2x&^;pjgr3=iduMVw$0;xyM zGP$)^hHq5<6q3*I6@-IYxwRWaOLH>yWeT^GHB8DzjrIHQjJfph3L`q<_7AbgDyz&}-Bhp%%>k9P^cdu<%lVs~p_v)H|O+^B0 z#IrIBCDJ>qB`a(k*y~&iBq4W)NB7;UY z#Em!T#jDFxZYY;UthK|lJnV}aLFs;tmq?o_ zT7~?Hmb-_WHFDF+Xf2zf-J;EJ54lT)N4b;<w(q%_nZ}^OhFydz}T`oTK5# zQr6%s^p(S}ZZStt6(LC!XI?wyb9maY2Hmp64=X2op77%Hk<-Bgdpk5KQ7FUwqn7w! znUnfxM7*~5R}?3K{bY|=bfHE-_NE|%wZ!s>NUWdKQ#E18bwu>a8XiQT;N8{Xt06+JU{QEV0S)R!1mS=tTDpi?Ftxx%Eg5>frWtf*K7rc8~& zh8ohfW3dehv~g!;8Ig59<#uCr+s6&my|%lIdCC%g`*Up?9Ic1Mf!60giR-#gE5kS` zt!HW6r>_Ms6ZTz2GrJAiwA=;i%;!0502=-06l}<7jsZz302!DHBLrnMN(M1cTA_lX zen`=tHm*}sdi+5vclz@*nz(w2TJ(A)yaOtxc%z*zQuPjp1$kqAiJyf8H!QJ~VRbOg z)T_C&THR>P2?`cr>Q387GxHCL8wp?Fif53F){^nj^$&V@_r}~E!WMTv%YP~qxkH$b zdrdq5b&C7Px7HI=0#=D8wjCwyG?0+A=W34MZ6qyH1azQ^!OJ*p5P$s6c~tKad$$zZ`pNSFVwOUD(Eh<`nCP_*SLCY zd+*3eNZ32(l)iPhQsSC>>Ea1WBvxtVJ-y@Et8bBoVS}Q)lwqUmS#WeJg2uQ*6%ARL{FqE@J8P~P!oO-zPkg7-- zm}{f+GiUpQ!C-qwq)n3M+c5X7jq~Trsz!5V_4CdC_8Yrv59j6^W;~|%Xc858{N+TF zIN+zC@;U7WP3zET{3Bi{?$b6?0Kf-BQ+OHIS zuUDi+;2pirw_$!s#phF3Z;6Nzq}hD)NoU9Jo&272I;q$Z3c}M4jJZ3O=;?R+m&xNq zL9QSJiyQ4wq$X}>u8}kxQq268pNC0zAW@x1Kv2aaGgAV2&wMO%MnE!aMo&4C=gjyS zolBkOioJCD`z`tC3y`ukRi&8!8#|IeFn;Txh-2{&E~AB^h224%@Hx5w;GQ~6kGqqF`Mp}?f5%C7@j5ra#63|RjZeouP2V@w z@1KPxfADl3Su`E^q$QFL+HVfQEDJEiGCem{B?qCpIaC87l176|hnL3~S7(%c8oz`l zmmabfY>zOvIy?;<5$cM;qR(s@E@m#DC&7UXaA8nwo0x;bFN0WpqPL) z6={Zj6Vqecdp*4);VZ+DyjsIY=PGMNj-r%dQ{gZ^pn){J|eCAPxXgbwnbfVNKPB~ zy?R_`rAVP@=8hRixn(eT?exaHmjwp?}T7tG#fTWTPgV zNX=MturEb#Luu1^!z2Q`*%;9rGgeN{$UZGh6u@g2G@dE&Pjw($D`9Dy>wn21KV`v+ z=0^*}Sm-EctCrjx<;LgPnObSqB#Yy*aosh&%g&wr$xw9gXTdrsh$0Mx}j_wf6nC(G*{c(A8FnH)Q_E2U17c+uS+D~ z<#LRaJ>`3AZ*>Bl5OrML#yV8~Rz~Zp9K{I|n%CuhJyI01`x+i|4OX`X^zKtpCt6jK zMy$)aGRwyp*L{<1{FjNh#Ik9KJI6D|L|)B@sSG`-O;ceO-? z0JR@ybKI^z9q%~NfxcaMoQ7=?F(Ih zxM3+|lO*wDTQheP@_Wnqs?&304*`WLXfo<-4(6*K1B)$GhcU3Jv#MFad0&Dql6;it zKcm#&8hE(dDft=n*V#|>@AdCi+YM;)Np7W)fqK$s?8 z=SVPEAo)7XwDgaH0dOa_YI2H|GAJ;9au}A81VbBZyyE;r1v))C$9l1$iAo@Z)?$-l z5(?*t0`r@7zJG~K9(Kzavi=c`axRxI0C@;VzJ9TM z9cRsVcc>YNRDp;$%r9dzM}!1>lt!fIf6@PR*L7~00yuNMt(kmpQ)Cjw&2wkwfBr1* z294T_|9H@gQg}CsGn!?QQb0S`gqP-j`AqM%0Mgr+=ifWj+W|kl^5VR#vV_-H=uI{p zo&USp@nIsc1k6yvKtwsbg?fBpa=_EcwEq6w%8g~JcuOO#9g;vFY<|OS>o-1+#=W*a zKWj6zu8j<8m{CJzJlM_f4R|p(-@n*@ap}(LrEANpmv6lM(uyCgqtMB&FZsrvzyl&CzW&(9(irTl9V1GZ zwe^I=h}vtk@<%M|g=|dqqV7c=_HSemdUXD~3D_~Lt(-Zm{mwiAQ+Cn9Cm%0mMePd# ztI+|#QWW9^l|+xu-_OY{%59u7R!{MDXS((QE)m~(S&Ze$M>2zKu*M)d3a=?YFYMv~ zs)Nu+V5x8J%y(iQ$BlXQj)FB}^Vfd{(_vEbaHS-IGv-$U-kazJEJieI%onqPGtKh? ztu9fsWioZNV~JWSzQBaHY$<=g&`f%GWP_Rw4qts!_#E%-Z=2eoZ>8>y5h`!=2Oq)0#YLPaDCO>2Q~me8DrOfXs&i(2eZDZ1}+c+fHBe> zT!OW5t#T*fQy^4t57mZRSj)iQWzX*%z@00WTlPBtpR|HHI%zBx?%nt7E6%9pdwje9 zkPB8kLd9Bw_2EDSSIN|s3`S;`;nU-XvTs`xg-8bKp`sa%u@L7HT~8I=a<#)!`^tu#Kw|@35PtT4p;gnXrk=1OSSJWMZ$BYTdwC)B^SwxaSu;H-3?! zQlN};RrnjBSVnB8DO}p`{7vn_2+DG7%cG?A36#PL*^90$Wm=@ZZ8eZ7g3>Tkg+KTx zm5;kS{F>+Y-hI3j-2=^(u^Zou&w%sWN=%tZL;4arRPs%Gy)BLmP9QWy6zIVMuJ4l*5WtQ>D#?w9JEUh}2^xhV^4n-z0+ zxc7$o2zjEK>Ezl&{X;)+IFk% zR&&WC6t`xG$N%R*C3nDZc$;*a+>$FP`WEGonJGEK&LsDXWh#0UGj&-U;^Jd!pp(kx zN6^4NJ)v%O71RWBS6fK}a7Op;mDBxAr;pkF;tZ^^M5xn z$ZwC<`>yR@{dA@&yOB07<`)#({7y~o+7y+VJV;z>wP3@Ze{m)GL@1<1Oc+W`yn0?fWfVQ^gBczN{SCj6& zsiKYDAlp8I8r!M;(nNl#F=8)_utXQO9TMxeh4h5bM{AGK zEZlk4j$AP4XC#wU|5tqba|7KsKQObSD7bTjjkPUWQbHAVhS`rC+Yar*>QNOkG)tLdJ}Vc%q1S{nYU<=lJ~5`Zf~p0d+e;ft2N%)CgY$tsFx_ zJJF8*HKXp#{Fnvy_fyd~90U62au<`&rZ0F^V^VwPHQ|P&i$s-Mkw)7#&F(f+>q7qI zvGn61*xPNq=vi>;K1XP}>ZBL+6GI=R5q*rKB@Q)(Gv(2CkM%iM{AX@rCDW{Wd!)Q4 zQFg>NfvH5kdbqNHxr6r z`S_4JyL*(|Yk%gtqV#n%Ggv&D;3EmzvZ}rN*JGM&u#e5$Wmn+O0hqPWzuBK_V^e+_ z9;VS2sRH+VrF^#e&m6#Kp2o*&`5JOT6{s~T21mSUl37K=O3Uf4=gDunOxK%2q~dn3 z+QC{=SIy}^-Xp@9h$&=|nRRF0l3MG9Ir{@Y({s&XR?aP76v5_Lt46swPxjQ4NChr< zbBc@9(gu#6i0pxmTWUcCF+P|1Pmf#HLS9#U{d(WBBAkZ8fTljo$OEm0hT7n)I4QVB z(*?L_INGr5E#fN-1_oSv6{LvA@qs(H`2}*~M#Zgt5(wNKOD6OFwgrEP1u}*R7760| zB~ROg%Ak10s^~)MtG1uv?(N~8XTq&c^@s+j1|X9tsm}edHCc~;-2FlcJmHooV1>-- zl8eh-E9mA}dAr`Bf{?D0*qP+}&yrTsQ7(S2%}^nmx}qzb#=4XOFidV6~xMyP3&ej&$Q06wRg z!3(KVIvl@quXvkOCmv#s(@4O|G-0*iC7P*;3p|Qv%YhY+K<<9wS_}YbT`s(cEL#y6 z!e&g?-LImVG^RTTBuQN#kXYBqU}(W14ux=I6d(rEh@U?SjPIC3m5Sxa;0Z2pWWsX| z-`G{=p=nNAG8~Pb{l%%SSrNU(yDOiqEPygs***Zirb`aSf04-))8gpmGQg35jEU(O z_W)T(H*VuR&b$`f-lV~bUBmf4CspnWEO*}~@KnQ`IRhxG!T)D)J|4K3)ZEpe+B20A zBUNckXK4CS8&?CZa1??;2=HLzj(0f*YfMvG!3;f0hM3<3%5D{UikqVji`^}wyIox8 zU(Rg1=^XC|pq=@Jg??cB#926_wzFJs{>&_`I2-Y#)=b(R#uZW`CvcwKg!WaI(q<5b z7az&r{l6HQ&his>lfDbHX$s18Rg<@;+U?U)0e;0EYVOwcpgLg8fFFm8GsnLbJlb$; z;(<$dv&5{zpqOI1wX*GM9ZWRsFh}c(gKBX;_@7QEeUX~-gtyi0T6I8vQ&pfeI&!`* zt~0(kBGa+BPK-LRv%*YQm4%|sPdg(*kI}awFY(wQ_-1cfa|_fLU7Ti3wYxxOool8V zote)Xx7KS0=Cqj7%skcf8*^f;kF&O7gidm|wgTs5p_A`{REV)fOFcw#MTYLUBhx4P-7-q?OHxY+qUAmB9c0^_|x??_sr$g<_Hw zr}4G+by{v(-p)ha=&>WAYObaz`7>Qi z!~9w=&VNr&w-TexRVe18pGfmg`=C18DC4HX!A*5f^YBH3UOQ~($z<~p<$1CU0B4>MuhDG-_1UcZ&qHqFsX)abX>WhX9qKB_tx zF4ce+s$2gNzdOnkP_h~EdirXVeUzeI7V)81_F=uWv6b04IVya9SEWt9_C2-oZBCZ_!ukXV%q_Jru*$4; zI=AUEoVoRVi!i`xhL21Qh`eDTy}`t;VxMo0Th?Md>N^Jy>L&|)qcUxt`yO5Ytp`wV z&T=x{RWU#owXq)MbnnlcYMRaTwnV{d5GvAXNyaz)E^k|0sVvl_4v1I|#{*AX6|3jwPuC?66Yx{%>D1wb zCiq{+Yb)mTa1MR;CHjV!f{303Meo}TD3t;}n2>P}U)GC^Ir*|X;wV9E_s31Ew_6?; zt~$8VbBpEtqJm*OwQ+Igd%G_^_vyAatM_YX^EgG-hbgLLAO!7*cs>S)sH5r@BW5Ut zL9&6?09UQi?rnJL@=!TnsQHtV_P_i;|L<%&=@HB#v8i@8k^la-<*{XEn|yibow|>+ z{7e~6L@SzDpB}j zB`Uwq8jtMz;#%3P0+cpb$+pFA6)mmD;v&9XcY#@i1A{W^K=7HViZ9nV{|L~5GWL4r z+o{$2mw~Ag z3K)gs-;0UJ$!pHtA_%Ah^d+35`mL(QI`*yqH8Yd_s9WIJwR~z8;n|0Uv_9{|uHs4* zAs;uEFlsIodY?YkyZ?PwHBj2xfiqR(7oIR`t}a|!ThBylk(jtH!9^mBnCh8et-9lA zEP^1T7Qq=8boH_))I{=(&(WNXhUf9r{qj^>eh^QdYF4S&1t4;pLn%Ap;Vpr zDT*U*T5_co2kQW>5w{x}&AC{NhX~et>xCEOYRpX!JK*Bw(f$U_5jH^yiZpxQRoO*c z<0*L(Mx3YBww%2*csJ#Q*?S*Ey`O|n&Qf#(@cs!|zx4OsE8`5RakS?g!z(!{uY`Z; z`*47X!0JE`=ZxDT>x6sO+idJ{-#Z1m0VOm%y4l;Qimm42tDOGDc(Sn0e7@Riojap5 zY@c24oMHW3RRE_V+AKhKL@B%|wP#Agy+b<<*1u_pZ((jrUD6f>irm`?o>iS{2-sYtP9^?Q|)U-{heA&Du_Fku_^>a@zY`y z$U=JT`i$l(2n8A77hO1hwqk7NQnD{>r&(M=etdlx3n8NO#A3-0I!`}-mIYH{dF(zF z|HdfGVxrQTOaVM0SL}k0G37o#y8Me5>jn{VPe(lW{Z!V>$fe#eC^=rVLybq9<1`t1 z^mx3r1ZI>bF1y#wM!cK3L#+Q-n2u35D#WqrrP;!rEr}i%9Dj;UaLoC!?iLo^yXS*-V zAagOgN#3dOIxAmCdGg3H3Z3^lh z5$_O!vML)cQAFK1q+)B{{Ek>NE24(KnR(Ah;&6_SsXmV%0UvXB2?!(E-;ZcYVj}V~3XUD+T8LI4wHUIhYH6%|@QhV=_#r zPu*T0El)Hr=-zUEn)bPCk5^qI9Mki*h?QJ6-;$k#OAd9-Xc@Jg2UuKMI7A#?bTATn zmmde;3B@KZ2zN0Pc8XsQ{wDS;t9a)!%;qxpqv>rymE)^`Jo=T1QwUb1U`G`Kps7|Gmu&L{gr13a z-(ei185$DcOh(+yq|)r4+vhAmxqka_Ee+R0+Hlla~IMifcgI=*dDKjndecO3FLy7L@YH z43pTOmpB_H>~C+<$yASxlY)?B?X;x)T-Zx8*5p7K+Wcr z$ppD&hyPwnTGOxUxbuttwQb_vLSAh%rHAB0Kt_~b&bZb;En%%?Kes|B4puWrt}>mc z#QK7*K(PhuV+p|llcgAATHC_MAk&zqGfrc^6D>W?_lFR6s)b|JK|<-^9s;8U$|u8b zP;QZ5UHzt(OF$MZs+E-3Z0s@KM7Qa;G}5l!U_Q6mfMVsIi)lh+Ec5=!Ss=EgiX>u1 zNd{NusR4Z|NnuGBji=Q-Fbmc2D+!DuGwTLm#C2Hun40qnug_nUO@s%rn z4ymzux}X=)XY8w8pzDSrs0t;LxW+O|l{r)Ed51%K%NrhqeiyPOF|nmx|J|6<)L~a3 zmb}inNKfn0y29G2$yJEdD&$?x$;C;?nYc?dcJa91LyFE#3z&rX$%J@Uul%*=Buoe) zDLSsy(TnAkBBIhGlM-a!wB2r4)zcCZw+koisECfjG=wR_;g1iZ&>UzCgUWV{65Ekp zna{$liKw!zVE2J(+=zOpeJ%E(X_YZ;IG6i9!dVc4ZO0dTTc!@gN4)gFTH1{WnjGA6@dL zY@MQ0K8b)1mV%QcQ|nH>sZNTUC__tbn#)4k71AkGKV607S}N&d=A?L%xT`JTZrRZ# z2mo)8>yhxM4Q{^^URtC#v8N+v>*}Om8O;=io66?k*0?SkflhGHC8KeGk5lzo1n-9j zED{54QY0k{H%pPbKD)&CjDoe*-D>!B3G7W5c25vzW-gA4v(IO|q1D(9EsT_7sPVGR zlX-jKwXMp}pYENI?6@;tRXH7>B?ZR%EL|9LKFqBAP3hY0ryN>#t$1}XG2;Mmr%+%J zkg(Fxp4=#WMQY}zIclJamu{@QQ1vM>1Ta4*S*GYF@+I@qxPfAY#x|H->v$pyvZjwB zT?13epg*K0SFUNpdfo4BDpIl94kDkLE^6%XaY};UTY9dQePdps^aoM$GdH+w{;n_% zpT#>h|1qjo3zhv-!mYEJG^(W56u5S@t}&ZxaDeVNkETD}T1s7vI)aVON1TN2;6mh@ z1GdBRh|ai<_r+;rO`)jiEA}y3hTr-m#tEvNqUm6Vq@yX;(ISp0E;LSEio}Yk;f;l# zD;UXxhFfcQxoX}nsg*wv>$wV#3=BF&i}*OzpZ`1ojX%^0mGwDM$7!^zzzlwI14Fr_ z?@lzMoL zV#E%}yfQqs7?*M-mvgvu8rAt*RXWY5l)82B*y)^#`;vTDt7oL*#THk;P*(nm68btf zzqb>$e_1o+$tj)8EDLCCd{d-Nf-ZW2bv3itBkRyD5`UtHDUFl@*y%{O9<+e4q?7ctzwaPEN zp$c|3UBUySbG#lWEvC@>o`+2WATqDF@k}df7nGNnbv05d>X+Y{c)57oCI`qI7dlSM z8ON>lQ_xn2U&inUjVS6<)A{EhKRIX++r{_*VaE!D4*K5rCw8D0)5Boau3{WUp9{+h zuz7M*4^wyrCyyVBV~dPd65dd}OuU%w8re}@&sxW4nP3SX(|gxfWa0f98a0dP3~;g_ zZSNPhrh;Myxj4UKo#aVtZ0*(f4}FGdijBtT=@UKt!0b+fqf#ZOCswf6h^uImxQv~v z^ly-+vOy*T2}(Yc^0NS?(pU7od{q`+SI+{OOQ!?DZYuAg_e`ioWj*>Xb)or3FaH?N zy?8sGyha9Qor&k!FI8@gbtV59kqH=S++U3#r{`dV3+Ui!Q@UO0Ip_h}X7=bY{W^2@ zNBx(#t)+qLX7v@k5$lkeRCfqMXSDe*fz@Va&9UkucxzCCb2MW>=BD?#%oMnfFY2D| z4pHvBoVQTAw+v`zej2wXM(X7tVC21HS+n1E9^bxftwP7Eq~@fJsH}ZpRn?X8#Pvw1 z4ejMfQ=JQQevz+_;B9bVKj702R+z~F${M?_^G?uwPQYEIwwz3>XSgG2@rehtRxa{M zdGS%3dB1GR8r%p~e9YU7KMmcpgBzv!5ohIx*7RRgp!i?zOdoQ*FP8&J783o89);Zz z%KdNTz%Mw&R6Bu1BCD;t4yV=ch*%W}YGW{_8| zzT)qMmOoZSY37RmBulrhy0gB~-V+y|gb}c3E@IQf`w!65mBXI%?R^@DY^0bgmhUSv zk1c-u4o{dpLN$kNBUo0I{eR+8R0aLDGu#-_A=0Y1UfYOmx*~RomTcEVu6v?|d8{46 zW@2R-rJf$L-?Vk3KFJ-DF_9+{G3M5ALpnoDY%Tuw?$Zy`>3+UhOsJ-Zy;h&`bT1XX zxIbqT&ByB15!Px;Qt;^BBfi)bk1WDVx{cRAHNE8*H@7w0aD62j?VJuM-PpLW!rd>6 z-#GUFzS<`IrwWuu6kBs8AkWKi7Qa&F9_iq<*&4Z;qtfVNqdm&f!SQ4<1$a_b;>G6G z7aox?!VvM!?V#r#&NBc~I#Y~KR5VL_B70SE3OSn*9x!peNSe%D?j-`TPA(ZuT}Pe4 z|K%UhbxaosU}>iewMR~{v>U)sHa)(Mrq^G&1rT;O@9kX)XYra`5vMQ9#^&}rH30Ds ze=*!1ju_W|d0}^rsu~`7N!@xD?9Z0&1*Hz)c2o|JXxI^F*FbeDwG O!nJjTI-f_s|Nj9MxMPU` diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1732321/EXTRINSIC_spec_1055_block_1732321_index_0.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1732321/EXTRINSIC_spec_1055_block_1732321_index_0.bin deleted file mode 100644 index aa5f40e6a39df57429d5f44caae5ad91d3462c63..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 TcmdO3VPfFEVAAYZ$jAi%4qgI& diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1732321/EXTRINSIC_spec_1055_block_1732321_index_1.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1732321/EXTRINSIC_spec_1055_block_1732321_index_1.bin deleted file mode 100644 index 1d256c7bfb60bb52333d38d8bb40f72226599a6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9 Qcmb1P;bf@Voyouj00;L0(f|Me diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1732321/EXTRINSIC_spec_1055_block_1732321_index_2.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1732321/EXTRINSIC_spec_1055_block_1732321_index_2.bin deleted file mode 100644 index bf51eab782a4c1cb186ebc426ce5c163aff84280..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6 NcmWe&5n*890ssKi05bpp diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1732321/EXTRINSIC_spec_1055_block_1732321_index_3.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1732321/EXTRINSIC_spec_1055_block_1732321_index_3.bin deleted file mode 100644 index b4c377848e3b2e9d63a0245a393fc9aaa8d1fed1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148 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 O!nJjTI-f_s|Nj9MxMPU` diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1768321/EXTRINSIC_spec_1055_block_1768321_index_0.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1768321/EXTRINSIC_spec_1055_block_1768321_index_0.bin deleted file mode 100644 index 5f81a94140cf52cd37bc4e604bb84584b82995e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 TcmdO3VPfEZAavQUkdX@j55@w? diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1768321/EXTRINSIC_spec_1055_block_1768321_index_1.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1768321/EXTRINSIC_spec_1055_block_1768321_index_1.bin deleted file mode 100644 index e5233416c126b24a5f97d60206b164cade7a88c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9 Qcmb1P;bi#rHk*M901HI|h5!Hn diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1768321/EXTRINSIC_spec_1055_block_1768321_index_2.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1768321/EXTRINSIC_spec_1055_block_1768321_index_2.bin deleted file mode 100644 index bf51eab782a4c1cb186ebc426ce5c163aff84280..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6 NcmWe&5n*890ssKi05bpp diff --git a/integration_tests/data/extrinsics/kusama/spec1055_block1768321/spec_1055_block_1768321_METADATA.bin b/integration_tests/data/extrinsics/kusama/spec1055_block1768321/spec_1055_block_1768321_METADATA.bin deleted file mode 100644 index d9266eb2461bc037fb8436606f4bb5fb5bea28f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137436 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 O!nJjTI-f_s|Nj9MxMPU` diff --git a/integration_tests/data/extrinsics/polkadot/spec0_block892/EXTRINSIC_spec_0_block_892_index_0.bin b/integration_tests/data/extrinsics/polkadot/spec0_block892/EXTRINSIC_spec_0_block_892_index_0.bin deleted file mode 100644 index 6f8b948c5e8996d4716d453b3c4f9365d4a9b338..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 TcmdO3VP@bK`28uch>;5b5I_S4 diff --git a/integration_tests/data/extrinsics/polkadot/spec0_block892/EXTRINSIC_spec_0_block_892_index_1.bin b/integration_tests/data/extrinsics/polkadot/spec0_block892/EXTRINSIC_spec_0_block_892_index_1.bin deleted file mode 100644 index 41354e099739feba61a017ec0b3dfb29db182f3f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7 OcmWe(;bM5o%LM=fumK+c diff --git a/integration_tests/data/extrinsics/polkadot/spec0_block892/EXTRINSIC_spec_0_block_892_index_2.bin b/integration_tests/data/extrinsics/polkadot/spec0_block892/EXTRINSIC_spec_0_block_892_index_2.bin deleted file mode 100644 index bf51eab782a4c1cb186ebc426ce5c163aff84280..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6 NcmWe&5n*890ssKi05bpp diff --git a/integration_tests/data/extrinsics/polkadot/spec0_block892/EXTRINSIC_spec_0_block_892_index_3.bin b/integration_tests/data/extrinsics/polkadot/spec0_block892/EXTRINSIC_spec_0_block_892_index_3.bin deleted file mode 100644 index 379754e41a6bf92161b2db87c63784941b105269..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 305 zcmdnV(sIt^R#bL`P}uofULUgp_MUM{xqsF$c3*eG{1^5PJ*pXuM{=uLN`gYqZ})q8 z`+OtMypYZf)uwJ76O)cFl07VyD>B_}9`hQ>d(*b`sBRE%tPD%M`rN`GOYs1+!2!)n zw_bL(GBYqpFbgt!DrBSB&HXorYe-=E0kmasnnv}Vuk!PFsHaAu_QG&HLpaW zJR`q2RUz2JQP;@SOd+>4rzA5Yu{c8^vsfW8H^MdBH!&kE!^10}D#SP_D?1`HD$Fg@ z+&n5ZEVZ4!}Bm<}`H?dM7DODjYzcepJA+ZE(U1*Sxl|n{I pNkOrdzCPS;y@LFl?8KD(61}|ClJfkbZ2jWIv=Y6HlH43kE&w&ab^!nY diff --git a/integration_tests/data/extrinsics/polkadot/spec0_block892/spec_0_block_892_METADATA.bin b/integration_tests/data/extrinsics/polkadot/spec0_block892/spec_0_block_892_METADATA.bin deleted file mode 100644 index 93561ad85e11e08a7e2d33e521f75d45731c0b1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148734 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 A-2eap diff --git a/integration_tests/data/extrinsics/westend/spec1_block1191/spec_1_block_1191_METADATA.bin b/integration_tests/data/extrinsics/westend/spec1_block1191/spec_1_block_1191_METADATA.bin deleted file mode 100644 index 7414ee244a9e8a9dde30e280545e5ad30528ccab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80253 zcmeFaJ&;^knfIB=CU4a2Xd^^~-dIh9CgM(ySh9Lb7YQ^ILTI!qsY<9`q>@mTx;4;j zWvcR)Do0tF_2x%QHOoe{fq{X6fq{X6fq{X6F$M+(1_lNjfq{X6F&lw_fiV%wMqps< z@BcjKoO^Fp>Z|EtVBR5`?#j%2&&P9~@2_)EOuK*HJH2%@nHC4l@ZT$ER(E$tv*EPa z{LuOB%a_Bajo#PeU&Fo86@J(l_KIgKS^3CXciO$$_^-{z2l2nwud?m^BHNn{23gk^ zl=Yc;e9)ctN5hQ2vTk9{|f^mlJ)BaOz1*(X2IYP7ze zZI7niK~}_{Cz(0X7yZZkjCI=oV7UL<4C6hu zpL|Iyw=(?UY?@6+j|&DLuRLd(Yqe=^7sIsP)i}YR7(SlvXYKwldvr7{Cd==4uCv#* zvs>NCezW=EOB|hj-kcpgD#mB{s9zfIz3lv2-^lKC53|vp11cNZ`xAB=zSw7&Vv=7> z&=YDfqt4;XTgC2`*`=!uAo%yqEIl&GdOWlkMp^rydpOCu!xFY1n}7}=peF54{pIES zv~Q)^nA_V)ZK?HVz;phT!{W0?MSu7>I~($ zuPYQW5H=#nUJkLtOm7He!n4D1@os-Kn*>BF@pW>4G@3SFV_a~s0>LqF$2n@aypnYX zlaY~2{N47G?HAo%G0sn~^&b}#W?u0>?(SXLzRCgpYv!NhORqQR`ny1C(rkQHM{XbP z7rUczPu#;k8ut)ju4=MxW&T3eD-K7K{