diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0b48a56ec..69492170c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,9 +18,14 @@ jobs: - pallet-fee-market - pallet-bridge-grandpa - pallet-bridge-messages + - pallet-bridge-parachains + - bp-crab + - bp-crab-parachain + - bp-darwinia + - bp-kusama - bp-pangolin - - bp-pangoro - bp-pangolin-parachain + - bp-pangoro - bp-rococo - bp-darwinia-core steps: diff --git a/Cargo.lock b/Cargo.lock index 348e420b8..e57c9951b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,48 +27,13 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "aead" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" -dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "aes" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" -dependencies = [ - "cfg-if 1.0.0", - "cipher", - "cpufeatures 0.2.1", - "opaque-debug 0.3.0", -] - -[[package]] -name = "aes-gcm" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "subtle", -] - [[package]] name = "ahash" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.3", + "getrandom 0.2.7", "once_cell", "version_check", ] @@ -93,25 +58,19 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.49" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a03e93e97a28fbc9f42fbc5ba0886a3c67eb637b476dbee711f80a6ffe8223d" +checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" [[package]] name = "approx" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "072df7202e63b127ab55acfe16ce97013d5b97bf160489336d3f1840fd78e99e" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" dependencies = [ "num-traits", ] -[[package]] -name = "array_tool" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f8cb5d814eb646a863c4f24978cff2880c4be96ad8cde2c0f0678732902e271" - [[package]] name = "arrayref" version = "0.3.6" @@ -139,242 +98,38 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" -[[package]] -name = "asn1_der" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22d1f4b888c298a027c99dc9048015fac177587de20fc30232a057dfbe24a21" - [[package]] name = "assert_matches" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" -[[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 0.4.4", - "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-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", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers", - "kv-log-macro", - "log", - "memchr", - "num_cpus", - "once_cell", - "pin-project-lite 0.2.7", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - -[[package]] -name = "async-std-resolver" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed4e2c3da14d8ad45acb1e3191db7a918e9505b6f155b218e70a7c9a1a48c638" -dependencies = [ - "async-std", - "async-trait", - "futures-io", - "futures-util", - "pin-utils", - "trust-dns-resolver", -] - -[[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.52" +version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3" +checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716" dependencies = [ "proc-macro2", "quote", "syn", ] -[[package]] -name = "asynchronous-codec" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb4401f0a3622dad2e0763fa79e0eb328bc70fb7dccfdd645341f00d671247d6" -dependencies = [ - "bytes", - "futures-sink", - "futures-util", - "memchr", - "pin-project-lite 0.2.7", -] - -[[package]] -name = "asynchronous-codec" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0de5164e5edbf51c45fb8c2d9664ae1c095cce1b265ecf7569093c0d66ef690" -dependencies = [ - "bytes", - "futures-sink", - "futures-util", - "memchr", - "pin-project-lite 0.2.7", -] - -[[package]] -name = "atomic" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c" -dependencies = [ - "autocfg", -] - -[[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 = "backoff" -version = "0.2.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721c249ab59cbc483ad4294c9ee2671835c1e43e9ffc277e6b4ecfef733cfdc5" -dependencies = [ - "instant", - "rand 0.7.3", -] +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.63" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "321629d8ba6513061f26707241fa9bc89524ff1cd7a915a97ef0c62c666ce1b6" +checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61" dependencies = [ "addr2line", "cc", - "cfg-if 1.0.0", + "cfg-if", "libc", "miniz_oxide", "object", @@ -382,10 +137,10 @@ dependencies = [ ] [[package]] -name = "base-x" -version = "0.2.8" +name = "base16ct" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" [[package]] name = "base58" @@ -399,21 +154,6 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" -[[package]] -name = "beef" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bed554bd50246729a1ec158d08aa3235d1b69d94ad120ebe187e28894787e736" -dependencies = [ - "serde", -] - -[[package]] -name = "bimap" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50ae17cabbc8a38a1e3e4c1a6a664e9a09672dc14d0896fa8d865d3a5a446b07" - [[package]] name = "bitflags" version = "1.3.2" @@ -432,17 +172,6 @@ dependencies = [ "wyz", ] -[[package]] -name = "blake2" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4e37d16930f5459780f5621038b6382b9bb37c19016f39fb6b5808d831f174" -dependencies = [ - "crypto-mac 0.8.0", - "digest 0.9.0", - "opaque-debug 0.3.0", -] - [[package]] name = "blake2" version = "0.10.4" @@ -462,50 +191,13 @@ dependencies = [ "constant_time_eq", ] -[[package]] -name = "blake2b_simd" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" -dependencies = [ - "arrayref", - "arrayvec 0.5.2", - "constant_time_eq", -] - -[[package]] -name = "blake2s_simd" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e461a7034e85b211a4acb57ee2e6730b32912b06c08cc242243c39fc21ae6a2" -dependencies = [ - "arrayref", - "arrayvec 0.5.2", - "constant_time_eq", -] - -[[package]] -name = "blake3" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b64485778c4f16a6a5a9d335e80d449ac6c70cdd6a06d2af18a6f6f775a125b3" -dependencies = [ - "arrayref", - "arrayvec 0.5.2", - "cc", - "cfg-if 0.1.10", - "constant_time_eq", - "crypto-mac 0.8.0", - "digest 0.9.0", -] - [[package]] name = "block-buffer" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" dependencies = [ - "block-padding 0.1.5", + "block-padding", "byte-tools", "byteorder", "generic-array 0.12.4", @@ -517,17 +209,16 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding 0.2.1", - "generic-array 0.14.4", + "generic-array 0.14.5", ] [[package]] name = "block-buffer" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" dependencies = [ - "generic-array 0.14.4", + "generic-array 0.14.5", ] [[package]] @@ -540,23 +231,45 @@ dependencies = [ ] [[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" +name = "bp-crab" +version = "0.1.0" +dependencies = [ + "bp-darwinia-core", + "bp-messages", + "bp-runtime", + "frame-support", + "sp-api", + "sp-runtime", + "sp-std", + "sp-version", +] [[package]] -name = "blocking" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046e47d4b2d391b1f6f8b407b1deb8dee56c1852ccd868becf2710f601b5f427" +name = "bp-crab-parachain" +version = "0.1.0" dependencies = [ - "async-channel", - "async-task", - "atomic-waker", - "fastrand", - "futures-lite", - "once_cell", + "bp-darwinia-core", + "bp-messages", + "bp-runtime", + "frame-support", + "sp-api", + "sp-runtime", + "sp-std", + "sp-version", +] + +[[package]] +name = "bp-darwinia" +version = "0.1.0" +dependencies = [ + "bp-darwinia-core", + "bp-messages", + "bp-runtime", + "frame-support", + "sp-api", + "sp-runtime", + "sp-std", + "sp-version", ] [[package]] @@ -764,20 +477,6 @@ dependencies = [ "sp-std", ] -[[package]] -name = "bp-wococo" -version = "0.1.0" -dependencies = [ - "bp-messages", - "bp-polkadot-core", - "bp-rococo", - "bp-runtime", - "parity-scale-codec", - "sp-api", - "sp-runtime", - "sp-std", -] - [[package]] name = "bridge-runtime-common" version = "0.1.0" @@ -803,26 +502,19 @@ dependencies = [ "sp-std", "sp-trie", "sp-version", - "static_assertions", ] [[package]] -name = "bs58" -version = "0.4.0" +name = "bumpalo" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" [[package]] -name = "bumpalo" -version = "3.8.0" +name = "byte-slice-cast" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" - -[[package]] -name = "byte-slice-cast" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d30c751592b77c499e7bce34d99d67c2c11bdc0574e9a488ddade14150a4698" +checksum = "87c5fdd0166095e1d463fc6cc01aa8ce547ad77a4e84d42eb6762b084e28067e" [[package]] name = "byte-tools" @@ -842,32 +534,11 @@ 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 = "castaway" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed247d1586918e46f2bbe0f13b06498db8dab5a8c1093f156652e9f2e0a73fc3" - [[package]] name = "cc" -version = "1.0.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" -dependencies = [ - "jobserver", -] - -[[package]] -name = "cfg-if" -version = "0.1.10" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" [[package]] name = "cfg-if" @@ -875,31 +546,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chacha20" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee7ad89dc1128635074c268ee661f90c3f7e83d9fd12910608c36b47d6c3412" -dependencies = [ - "cfg-if 1.0.0", - "cipher", - "cpufeatures 0.1.5", - "zeroize", -] - -[[package]] -name = "chacha20poly1305" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1580317203210c517b6d44794abfbe600698276db18127e37ad3e69bf5e848e5" -dependencies = [ - "aead", - "chacha20", - "cipher", - "poly1305", - "zeroize", -] - [[package]] name = "chrono" version = "0.4.19" @@ -909,38 +555,14 @@ dependencies = [ "libc", "num-integer", "num-traits", - "time 0.1.44", "winapi", ] [[package]] -name = "cid" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff0e3bc0b6446b3f9663c1a6aba6ef06c5aeaa1bc92bd18077be337198ab9768" -dependencies = [ - "multibase", - "multihash 0.13.2", - "unsigned-varint 0.5.1", -] - -[[package]] -name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "concurrent-queue" -version = "1.2.2" +name = "const-oid" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" -dependencies = [ - "cache-padded", -] +checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" [[package]] name = "constant_time_eq" @@ -948,112 +570,40 @@ 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 = "core-foundation" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - -[[package]] -name = "cpufeatures" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" -dependencies = [ - "libc", -] - [[package]] name = "cpufeatures" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" dependencies = [ "libc", ] [[package]] -name = "crc32fast" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3825b1e8580894917dc4468cb634a1b4e9745fddc854edad72d9c04644c0319f" -dependencies = [ - "cfg-if 1.0.0", -] - -[[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" +name = "crunchy" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils", - "lazy_static", - "memoffset", - "scopeguard", -] +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] -name = "crossbeam-utils" -version = "0.8.5" +name = "crypto-bigint" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" dependencies = [ - "cfg-if 1.0.0", - "lazy_static", + "generic-array 0.14.5", + "rand_core 0.6.3", + "subtle", + "zeroize", ] -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "crypto-common" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" dependencies = [ - "generic-array 0.14.4", + "generic-array 0.14.5", "typenum", ] @@ -1063,7 +613,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ - "generic-array 0.14.4", + "generic-array 0.14.5", "subtle", ] @@ -1073,71 +623,10 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" dependencies = [ - "generic-array 0.14.4", + "generic-array 0.14.5", "subtle", ] -[[package]] -name = "ctor" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "ctr" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" -dependencies = [ - "cipher", -] - -[[package]] -name = "cuckoofilter" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b810a8449931679f64cd7eef1bbd0fa315801b6d5d9cdc1ace2804d6529eee18" -dependencies = [ - "byteorder", - "fnv", - "rand 0.7.3", -] - -[[package]] -name = "curl" -version = "0.4.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc6d233563261f8db6ffb83bbaad5a73837a6e6b28868e926337ebbdece0be3" -dependencies = [ - "curl-sys", - "libc", - "openssl-probe", - "openssl-sys", - "schannel", - "socket2 0.4.4", - "winapi", -] - -[[package]] -name = "curl-sys" -version = "0.4.51+curl-7.80.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d130987e6a6a34fe0889e1083022fa48cd90e6709a84be3fb8dd95801de5af20" -dependencies = [ - "cc", - "libc", - "libnghttp2-sys", - "libz-sys", - "openssl-sys", - "pkg-config", - "vcpkg", - "winapi", -] - [[package]] name = "curve25519-dalek" version = "2.1.3" @@ -1165,29 +654,12 @@ dependencies = [ ] [[package]] -name = "data-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" - -[[package]] -name = "data-encoding-macro" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86927b7cd2fe88fa698b87404b287ab98d1a0063a34071d92e575b72d3029aca" -dependencies = [ - "data-encoding", - "data-encoding-macro-internal", -] - -[[package]] -name = "data-encoding-macro-internal" -version = "0.1.10" +name = "der" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5bbed42daaa95e780b60a50546aa345b8413a1e46f9a40a12907d3598f038db" +checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" dependencies = [ - "data-encoding", - "syn", + "const-oid", ] [[package]] @@ -1196,10 +668,8 @@ version = "0.99.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ - "convert_case", "proc-macro2", "quote", - "rustc_version 0.4.0", "syn", ] @@ -1218,7 +688,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.4", + "generic-array 0.14.5", ] [[package]] @@ -1227,39 +697,17 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ - "block-buffer 0.10.0", + "block-buffer 0.10.2", "crypto-common", "subtle", ] -[[package]] -name = "dns-parser" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" -dependencies = [ - "byteorder", - "quick-error", -] - -[[package]] -name = "doc-comment" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" - [[package]] name = "downcast-rs" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" -[[package]] -name = "dtoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" - [[package]] name = "dyn-clonable" version = "0.9.0" @@ -1283,15 +731,27 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.4" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "140206b78fb2bc3edbcfc9b5ccbd0b30699cfe8d348b8b31b330e47df5291a5a" + +[[package]] +name = "ecdsa" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" +checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" +dependencies = [ + "der", + "elliptic-curve", + "rfc6979", + "signature", +] [[package]] name = "ed25519" -version = "1.3.0" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74e1069e39f1454367eb2de793ed062fac4c35c2934b76a81d90dd9abcd28816" +checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" dependencies = [ "signature", ] @@ -1306,7 +766,7 @@ dependencies = [ "ed25519", "rand 0.7.3", "serde", - "sha2 0.9.8", + "sha2 0.9.9", "zeroize", ] @@ -1317,50 +777,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] -name = "encoding_rs" -version = "0.8.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a74ea89a0a1b98f6332de42c95baff457ada66d1cb4030f9ff151b2041a1c746" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "enum-as-inner" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595" -dependencies = [ - "heck", - "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" +name = "elliptic-curve" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" +checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" dependencies = [ - "atty", - "humantime 2.1.0", - "log", - "regex", - "termcolor", + "base16ct", + "crypto-bigint", + "der", + "ff", + "generic-array 0.14.5", + "group", + "rand_core 0.6.3", + "sec1", + "subtle", + "zeroize", ] [[package]] @@ -1396,12 +827,6 @@ dependencies = [ "uint", ] -[[package]] -name = "event-listener" -version = "2.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" - [[package]] name = "fake-simd" version = "0.1.2" @@ -1409,45 +834,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] -name = "fastrand" -version = "1.5.0" +name = "ff" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b394ed3d285a429378d3b384b9eb1285267e7df4b166df24b7a6939a04dc392e" +checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" dependencies = [ - "instant", + "rand_core 0.6.3", + "subtle", ] [[package]] name = "finality-grandpa" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9def033d8505edf199f6a5d07aa7e6d2d6185b164293b77f0efd108f4f3e11d" +checksum = "b22349c6a11563a202d95772a68e0fcf56119e74ea8a2a19cf2301460fcd0df5" dependencies = [ "either", - "futures 0.3.21", + "futures", "futures-timer", "log", "num-traits", "parity-scale-codec", - "parking_lot 0.11.2", + "parking_lot", "scale-info", ] -[[package]] -name = "finality-relay" -version = "0.1.0" -dependencies = [ - "async-std", - "async-trait", - "backoff", - "bp-header-chain", - "futures 0.3.21", - "log", - "num-traits", - "parking_lot 0.11.2", - "relay-utils", -] - [[package]] name = "fixed-hash" version = "0.7.0" @@ -1460,53 +871,10 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "fixedbitset" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "398ea4fabe40b9b0d885340a2a991a44c8a645624075ad966d21f88688e2b69e" - -[[package]] -name = "flate2" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" -dependencies = [ - "cfg-if 1.0.0", - "crc32fast", - "libc", - "libz-sys", - "miniz_oxide", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "fork-tree" -version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "parity-scale-codec", -] - -[[package]] -name = "form_urlencoded" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding 2.1.0", -] - [[package]] name = "frame-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "frame-support", "frame-system", @@ -1531,7 +899,7 @@ version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df6bb8542ef006ef0de09a5c4420787d79823c0ed7924225822362fd2bf2ff2d" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "parity-scale-codec", "scale-info", "serde", @@ -1540,12 +908,13 @@ dependencies = [ [[package]] name = "frame-support" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "bitflags", "frame-metadata", "frame-support-procedural", "impl-trait-for-tuples", + "k256", "log", "once_cell", "parity-scale-codec", @@ -1569,7 +938,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "Inflector", "frame-support-procedural-tools", @@ -1581,10 +950,10 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "frame-support-procedural-tools-derive", - "proc-macro-crate 1.1.3", + "proc-macro-crate", "proc-macro2", "quote", "syn", @@ -1593,7 +962,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "proc-macro2", "quote", @@ -1603,7 +972,7 @@ dependencies = [ [[package]] name = "frame-system" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "frame-support", "log", @@ -1623,12 +992,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" -[[package]] -name = "futures" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" - [[package]] name = "futures" version = "0.3.21" @@ -1679,42 +1042,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" [[package]] -name = "futures-lite" -version = "1.12.0" +name = "futures-macro" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite 0.2.7", - "waker-fn", -] - -[[package]] -name = "futures-macro" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" dependencies = [ "proc-macro2", "quote", "syn", ] -[[package]] -name = "futures-rustls" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a1387e07917c711fb4ee4f48ea0adb04a3c9739e53ef85bf43ae1edc2937a8b" -dependencies = [ - "futures-io", - "rustls 0.19.1", - "webpki 0.21.4", -] - [[package]] name = "futures-sink" version = "0.3.21" @@ -1739,7 +1076,6 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ - "futures 0.1.31", "futures-channel", "futures-core", "futures-io", @@ -1747,7 +1083,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.7", + "pin-project-lite", "pin-utils", "slab", ] @@ -1763,9 +1099,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" dependencies = [ "typenum", "version_check", @@ -1777,7 +1113,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "js-sys", "libc", "wasi 0.9.0+wasi-snapshot-preview1", @@ -1786,23 +1122,13 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", - "wasi 0.10.0+wasi-snapshot-preview1", -] - -[[package]] -name = "ghash" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" -dependencies = [ - "opaque-debug 0.3.0", - "polyval", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] @@ -1812,16 +1138,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" [[package]] -name = "gloo-timers" -version = "0.2.1" +name = "group" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f" +checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", - "web-sys", + "ff", + "rand_core 0.6.3", + "subtle", ] [[package]] @@ -1850,22 +1174,13 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c21d40587b92fa6a6c6e3c1bdbf87d75511db5672f9c93175574b3a00df1758" +checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" 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" @@ -1887,12 +1202,6 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" -[[package]] -name = "hex_fmt" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" - [[package]] name = "hmac" version = "0.8.1" @@ -1920,2950 +1229,932 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" dependencies = [ "digest 0.9.0", - "generic-array 0.14.4", + "generic-array 0.14.5", "hmac 0.8.1", ] [[package]] -name = "hostname" -version = "0.3.1" +name = "impl-codec" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "libc", - "match_cfg", - "winapi", + "parity-scale-codec", ] [[package]] -name = "http" -version = "0.2.5" +name = "impl-rlp" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" dependencies = [ - "bytes", - "fnv", - "itoa 0.4.8", + "rlp", ] [[package]] -name = "http-body" -version = "0.4.4" +name = "impl-serde" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" +checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" dependencies = [ - "bytes", - "http", - "pin-project-lite 0.2.7", + "serde", ] [[package]] -name = "httparse" -version = "1.5.1" +name = "impl-trait-for-tuples" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "httpdate" -version = "1.0.2" +name = "integer-sqrt" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" +dependencies = [ + "num-traits", +] [[package]] -name = "humantime" -version = "1.3.0" +name = "itoa" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -dependencies = [ - "quick-error", -] +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] -name = "humantime" -version = "2.1.0" +name = "itoa" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" [[package]] -name = "hyper" -version = "0.14.16" +name = "js-sys" +version = "0.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7ec3e62bdc98a2f0393a5048e4c30ef659440ea6e0e572965103e72bd836f55" +checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http", - "http-body", - "httparse", - "httpdate", - "itoa 0.4.8", - "pin-project-lite 0.2.7", - "socket2 0.4.4", - "tokio", - "tower-service", - "tracing", - "want", + "wasm-bindgen", ] [[package]] -name = "idna" -version = "0.1.5" +name = "k256" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", + "cfg-if", + "ecdsa", + "elliptic-curve", + "sec1", ] [[package]] -name = "idna" -version = "0.2.3" +name = "keccak" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] +checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838" [[package]] -name = "if-addrs" -version = "0.6.7" +name = "lazy_static" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2273e421f7c4f0fc99e1934fe4776f59d8df2972f4199d703fc0da9f2a9f73de" -dependencies = [ - "if-addrs-sys", - "libc", - "winapi", -] +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] -name = "if-addrs-sys" -version = "0.3.2" +name = "libc" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de74b9dd780476e837e5eb5ab7c88b49ed304126e412030a0adba99c8efe79ea" -dependencies = [ - "cc", - "libc", -] +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] -name = "if-watch" +name = "libm" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8ab7f67bad3240049cb24fb9cb0b4c2c6af4c245840917fbbdededeee91179" -dependencies = [ - "async-io", - "futures 0.3.21", - "futures-lite", - "if-addrs", - "ipnet", - "libc", - "log", - "winapi", -] +checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db" [[package]] -name = "impl-codec" -version = "0.6.0" +name = "libsecp256k1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +checksum = "b0452aac8bab02242429380e9b2f94ea20cea2b37e2c1777a1358799bbe97f37" dependencies = [ - "parity-scale-codec", + "arrayref", + "base64", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.8.5", + "serde", + "sha2 0.9.9", + "typenum", ] [[package]] -name = "impl-rlp" +name = "libsecp256k1-core" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" dependencies = [ - "rlp", + "crunchy", + "digest 0.9.0", + "subtle", ] [[package]] -name = "impl-serde" -version = "0.3.2" +name = "libsecp256k1-gen-ecmult" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" +checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" dependencies = [ - "serde", + "libsecp256k1-core", ] [[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" +name = "libsecp256k1-gen-genmult" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" dependencies = [ - "proc-macro2", - "quote", - "syn", + "libsecp256k1-core", ] [[package]] -name = "indexmap" -version = "1.8.0" +name = "linregress" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +checksum = "d6c601a85f5ecd1aba625247bca0031585fb1c446461b142878a16f8245ddeb8" dependencies = [ - "autocfg", - "hashbrown 0.11.2", + "nalgebra", + "statrs", ] [[package]] -name = "instant" -version = "0.1.12" +name = "lock_api" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ - "cfg-if 1.0.0", + "autocfg", + "scopeguard", ] [[package]] -name = "integer-sqrt" -version = "0.1.5" +name = "log" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ - "num-traits", + "cfg-if", ] [[package]] -name = "ip_network" -version = "0.4.1" +name = "lru" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1" +checksum = "c84e6fe5655adc6ce00787cf7dcaf8dc4f998a0565d23eafc207a8b08ca3349a" +dependencies = [ + "hashbrown 0.11.2", +] [[package]] -name = "ipconfig" -version = "0.2.2" +name = "matchers" +version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" dependencies = [ - "socket2 0.3.19", - "widestring", - "winapi", - "winreg", + "regex-automata", ] [[package]] -name = "ipnet" -version = "2.3.1" +name = "matrixmultiply" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" +checksum = "add85d4dd35074e6fedc608f8c8f513a3548619a9024b751949ef0e8e45a4d84" +dependencies = [ + "rawpointer", +] [[package]] -name = "isahc" -version = "1.6.0" +name = "memchr" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d140e84730d325378912ede32d7cd53ef1542725503b3353e5ec8113c7c6f588" -dependencies = [ - "async-channel", - "castaway", - "crossbeam-utils", - "curl", - "curl-sys", - "encoding_rs", - "event-listener", - "futures-lite", - "http", - "log", - "mime", - "once_cell", - "polling", - "slab", - "sluice", - "tracing", - "tracing-futures", - "url 2.2.2", - "waker-fn", -] +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] -name = "itertools" -version = "0.10.3" +name = "memory-db" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +checksum = "6566c70c1016f525ced45d7b7f97730a2bafb037c788211d0c186ef5b2189f0a" dependencies = [ - "either", + "hash-db", + "hashbrown 0.12.1", + "parity-util-mem", ] [[package]] -name = "itoa" -version = "0.4.8" +name = "memory_units" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" [[package]] -name = "itoa" -version = "1.0.1" +name = "merlin" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "4e261cf0f8b3c42ded9f7d2bb59dea03aa52bc8a1cbc7482f9fc3fd1229d3b42" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.5.1", + "zeroize", +] [[package]] -name = "jobserver" -version = "0.1.24" +name = "miniz_oxide" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" dependencies = [ - "libc", + "adler", ] [[package]] -name = "js-sys" -version = "0.3.55" +name = "nalgebra" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +checksum = "462fffe4002f4f2e1f6a9dcf12cc1a6fc0e15989014efc02a941d3e0f5dc2120" dependencies = [ - "wasm-bindgen", + "approx", + "matrixmultiply", + "nalgebra-macros", + "num-complex", + "num-rational 0.4.1", + "num-traits", + "rand 0.8.5", + "rand_distr", + "simba", + "typenum", ] [[package]] -name = "jsonpath_lib" -version = "0.2.6" +name = "nalgebra-macros" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61352ec23883402b7d30b3313c16cbabefb8907361c4eb669d990cbb87ceee5a" +checksum = "01fcc0b8149b4632adc89ac3b7b31a12fb6099a0317a4eb2ebff574ef7de7218" dependencies = [ - "array_tool", - "env_logger 0.7.1", - "log", - "serde", - "serde_json", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "jsonrpc-client-transports" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b99d4207e2a04fb4581746903c2bb7eb376f88de9c699d0f3e10feeac0cd3a" -dependencies = [ - "derive_more", - "futures 0.3.21", - "jsonrpc-core", - "jsonrpc-pubsub", - "log", - "serde", - "serde_json", - "url 1.7.2", -] - -[[package]] -name = "jsonrpc-core" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" -dependencies = [ - "futures 0.3.21", - "futures-executor", - "futures-util", - "log", - "serde", - "serde_derive", - "serde_json", -] - -[[package]] -name = "jsonrpc-core-client" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b51da17abecbdab3e3d4f26b01c5ec075e88d3abe3ab3b05dc9aa69392764ec0" -dependencies = [ - "futures 0.3.21", - "jsonrpc-client-transports", -] - -[[package]] -name = "jsonrpc-derive" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b939a78fa820cdfcb7ee7484466746a7377760970f6f9c6fe19f9edcc8a38d2" -dependencies = [ - "proc-macro-crate 0.1.5", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "jsonrpc-pubsub" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240f87695e6c6f62fb37f05c02c04953cf68d6408b8c1c89de85c7a0125b1011" -dependencies = [ - "futures 0.3.21", - "jsonrpc-core", - "lazy_static", - "log", - "parking_lot 0.11.2", - "rand 0.7.3", - "serde", -] - -[[package]] -name = "jsonrpsee" -version = "0.8.0" +name = "nodrop" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05fd8cd6c6b1bbd06881d2cf88f1fc83cc36c98f2219090f839115fb4a956cb9" -dependencies = [ - "jsonrpsee-core", - "jsonrpsee-proc-macros", - "jsonrpsee-types", - "jsonrpsee-ws-client", -] +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" [[package]] -name = "jsonrpsee-client-transport" -version = "0.8.0" +name = "num-bigint" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3303cdf246e6ab76e2866fb3d9acb6c76a068b1b28bd923a1b7a8122257ad7b5" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" dependencies = [ - "futures 0.3.21", - "http", - "jsonrpsee-core", - "jsonrpsee-types", - "pin-project 1.0.10", - "rustls-native-certs", - "soketto", - "thiserror", - "tokio", - "tokio-rustls", - "tokio-util", - "tracing", - "webpki-roots 0.22.2", + "autocfg", + "num-integer", + "num-traits", ] [[package]] -name = "jsonrpsee-core" -version = "0.8.0" +name = "num-complex" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f220b5a238dc7992b90f1144fbf6eaa585872c9376afe6fe6863ffead6191bf3" +checksum = "7ae39348c8bc5fbd7f40c727a9925f03517afd2ab27d46702108b6a7e5414c19" dependencies = [ - "anyhow", - "arrayvec 0.7.2", - "async-trait", - "beef", - "futures-channel", - "futures-util", - "hyper", - "jsonrpsee-types", - "rustc-hash", - "serde", - "serde_json", - "soketto", - "thiserror", - "tokio", - "tracing", + "num-traits", ] [[package]] -name = "jsonrpsee-proc-macros" -version = "0.8.0" +name = "num-format" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4299ebf790ea9de1cb72e73ff2ae44c723ef264299e5e2d5ef46a371eb3ac3d8" +checksum = "bafe4179722c2894288ee77a9f044f02811c86af699344c498b0840c698a2465" dependencies = [ - "proc-macro-crate 1.1.3", - "proc-macro2", - "quote", - "syn", + "arrayvec 0.4.12", + "itoa 0.4.8", ] [[package]] -name = "jsonrpsee-types" -version = "0.8.0" +name = "num-integer" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b3f601bbbe45cd63f5407b6f7d7950e08a7d4f82aa699ff41a4a5e9e54df58" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ - "anyhow", - "beef", - "serde", - "serde_json", - "thiserror", - "tracing", + "autocfg", + "num-traits", ] [[package]] -name = "jsonrpsee-ws-client" -version = "0.8.0" +name = "num-rational" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aff425cee7c779e33920913bc695447416078ee6d119f443f3060feffa4e86b5" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" dependencies = [ - "jsonrpsee-client-transport", - "jsonrpsee-core", - "jsonrpsee-types", + "autocfg", + "num-bigint", + "num-integer", + "num-traits", ] [[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" +name = "num-rational" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ - "log", + "autocfg", + "num-integer", + "num-traits", ] [[package]] -name = "kvdb" -version = "0.11.0" +name = "num-traits" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a301d8ecb7989d4a6e2c57a49baca77d353bdbf879909debe3f375fe25d61f86" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ - "parity-util-mem", - "smallvec", + "autocfg", + "libm", ] [[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.120" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad5c14e80759d0939d013e6ca49930e59fc53dd8e5009132f76240c179380c09" - -[[package]] -name = "libm" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" - -[[package]] -name = "libnghttp2-sys" -version = "0.1.7+1.45.0" +name = "num_cpus" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ed28aba195b38d5ff02b9170cbff627e336a20925e43b4945390401c5dc93f" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ - "cc", + "hermit-abi", "libc", ] [[package]] -name = "libp2p" -version = "0.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bec54343492ba5940a6c555e512c6721139835d28c59bc22febece72dfd0d9d" -dependencies = [ - "atomic", - "bytes", - "futures 0.3.21", - "lazy_static", - "libp2p-core", - "libp2p-deflate", - "libp2p-dns", - "libp2p-floodsub", - "libp2p-gossipsub", - "libp2p-identify", - "libp2p-kad", - "libp2p-mdns", - "libp2p-metrics", - "libp2p-mplex", - "libp2p-noise", - "libp2p-ping", - "libp2p-plaintext", - "libp2p-pnet", - "libp2p-relay", - "libp2p-rendezvous", - "libp2p-request-response", - "libp2p-swarm", - "libp2p-swarm-derive", - "libp2p-tcp", - "libp2p-uds", - "libp2p-wasm-ext", - "libp2p-websocket", - "libp2p-yamux", - "multiaddr", - "parking_lot 0.11.2", - "pin-project 1.0.10", - "smallvec", - "wasm-timer", -] - -[[package]] -name = "libp2p-core" -version = "0.30.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86aad7d54df283db817becded03e611137698a6509d4237a96881976a162340c" -dependencies = [ - "asn1_der", - "bs58", - "ed25519-dalek", - "either", - "fnv", - "futures 0.3.21", - "futures-timer", - "instant", - "lazy_static", - "libsecp256k1", - "log", - "multiaddr", - "multihash 0.14.0", - "multistream-select", - "parking_lot 0.11.2", - "pin-project 1.0.10", - "prost", - "prost-build", - "rand 0.8.5", - "ring", - "rw-stream-sink", - "sha2 0.9.8", - "smallvec", - "thiserror", - "unsigned-varint 0.7.1", - "void", - "zeroize", -] - -[[package]] -name = "libp2p-deflate" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51a800adb195f33de63f4b17b63fe64cfc23bf2c6a0d3d0d5321328664e65197" -dependencies = [ - "flate2", - "futures 0.3.21", - "libp2p-core", -] - -[[package]] -name = "libp2p-dns" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb8f89d15cb6e3c5bc22afff7513b11bab7856f2872d3cfba86f7f63a06bc498" -dependencies = [ - "async-std-resolver", - "futures 0.3.21", - "libp2p-core", - "log", - "smallvec", - "trust-dns-resolver", -] - -[[package]] -name = "libp2p-floodsub" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aab3d7210901ea51b7bae2b581aa34521797af8c4ec738c980bda4a06434067f" -dependencies = [ - "cuckoofilter", - "fnv", - "futures 0.3.21", - "libp2p-core", - "libp2p-swarm", - "log", - "prost", - "prost-build", - "rand 0.7.3", - "smallvec", -] - -[[package]] -name = "libp2p-gossipsub" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfeead619eb5dac46e65acc78c535a60aaec803d1428cca6407c3a4fc74d698d" -dependencies = [ - "asynchronous-codec 0.6.0", - "base64", - "byteorder", - "bytes", - "fnv", - "futures 0.3.21", - "hex_fmt", - "libp2p-core", - "libp2p-swarm", - "log", - "prost", - "prost-build", - "rand 0.7.3", - "regex", - "sha2 0.9.8", - "smallvec", - "unsigned-varint 0.7.1", - "wasm-timer", -] - -[[package]] -name = "libp2p-identify" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cca1275574183f288ff8b72d535d5ffa5ea9292ef7829af8b47dcb197c7b0dcd" -dependencies = [ - "futures 0.3.21", - "libp2p-core", - "libp2p-swarm", - "log", - "lru 0.6.6", - "prost", - "prost-build", - "smallvec", - "wasm-timer", -] - -[[package]] -name = "libp2p-kad" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2297dc0ca285f3a09d1368bde02449e539b46f94d32d53233f53f6625bcd3ba" -dependencies = [ - "arrayvec 0.5.2", - "asynchronous-codec 0.6.0", - "bytes", - "either", - "fnv", - "futures 0.3.21", - "libp2p-core", - "libp2p-swarm", - "log", - "prost", - "prost-build", - "rand 0.7.3", - "sha2 0.9.8", - "smallvec", - "uint", - "unsigned-varint 0.7.1", - "void", - "wasm-timer", -] - -[[package]] -name = "libp2p-mdns" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c864b64bdc8a84ff3910a0df88e6535f256191a450870f1e7e10cbf8e64d45" -dependencies = [ - "async-io", - "data-encoding", - "dns-parser", - "futures 0.3.21", - "if-watch", - "lazy_static", - "libp2p-core", - "libp2p-swarm", - "log", - "rand 0.8.5", - "smallvec", - "socket2 0.4.4", - "void", -] - -[[package]] -name = "libp2p-metrics" -version = "0.1.0" +name = "object" +version = "0.28.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4af432fcdd2f8ba4579b846489f8f0812cfd738ced2c0af39df9b1c48bbb6ab2" +checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" dependencies = [ - "libp2p-core", - "libp2p-identify", - "libp2p-kad", - "libp2p-ping", - "libp2p-swarm", - "open-metrics-client", + "memchr", ] [[package]] -name = "libp2p-mplex" -version = "0.30.0" +name = "once_cell" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2cd64ef597f40e14bfce0497f50ecb63dd6d201c61796daeb4227078834fbf" -dependencies = [ - "asynchronous-codec 0.6.0", - "bytes", - "futures 0.3.21", - "libp2p-core", - "log", - "nohash-hasher", - "parking_lot 0.11.2", - "rand 0.7.3", - "smallvec", - "unsigned-varint 0.7.1", -] +checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" [[package]] -name = "libp2p-noise" -version = "0.33.0" +name = "opaque-debug" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8772c7a99088221bb7ca9c5c0574bf55046a7ab4c319f3619b275f28c8fb87a" -dependencies = [ - "bytes", - "curve25519-dalek 3.2.0", - "futures 0.3.21", - "lazy_static", - "libp2p-core", - "log", - "prost", - "prost-build", - "rand 0.8.5", - "sha2 0.9.8", - "snow", - "static_assertions", - "x25519-dalek", - "zeroize", -] +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" [[package]] -name = "libp2p-ping" -version = "0.31.0" +name = "opaque-debug" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80ef7b0ec5cf06530d9eb6cf59ae49d46a2c45663bde31c25a12f682664adbcf" -dependencies = [ - "futures 0.3.21", - "libp2p-core", - "libp2p-swarm", - "log", - "rand 0.7.3", - "void", - "wasm-timer", -] +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] -name = "libp2p-plaintext" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fba1a6ff33e4a274c89a3b1d78b9f34f32af13265cc5c46c16938262d4e945a" +name = "pallet-balances" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ - "asynchronous-codec 0.6.0", - "bytes", - "futures 0.3.21", - "libp2p-core", - "log", - "prost", - "prost-build", - "unsigned-varint 0.7.1", - "void", -] - -[[package]] -name = "libp2p-pnet" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1a458bbda880107b5b36fcb9b5a1ef0c329685da0e203ed692a8ebe64cc92c" -dependencies = [ - "futures 0.3.21", - "log", - "pin-project 1.0.10", - "rand 0.7.3", - "salsa20", - "sha3 0.9.1", -] - -[[package]] -name = "libp2p-relay" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2852b61c90fa8ce3c8fcc2aba76e6cefc20d648f9df29157d6b3a916278ef3e3" -dependencies = [ - "asynchronous-codec 0.6.0", - "bytes", - "futures 0.3.21", - "futures-timer", - "libp2p-core", - "libp2p-swarm", - "log", - "pin-project 1.0.10", - "prost", - "prost-build", - "rand 0.7.3", - "smallvec", - "unsigned-varint 0.7.1", - "void", - "wasm-timer", -] - -[[package]] -name = "libp2p-rendezvous" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14a6d2b9e7677eff61dc3d2854876aaf3976d84a01ef6664b610c77a0c9407c5" -dependencies = [ - "asynchronous-codec 0.6.0", - "bimap", - "futures 0.3.21", - "libp2p-core", - "libp2p-swarm", - "log", - "prost", - "prost-build", - "rand 0.8.5", - "sha2 0.9.8", - "thiserror", - "unsigned-varint 0.7.1", - "void", - "wasm-timer", -] - -[[package]] -name = "libp2p-request-response" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a877a4ced6d46bf84677e1974e8cf61fb434af73b2e96fb48d6cb6223a4634d8" -dependencies = [ - "async-trait", - "bytes", - "futures 0.3.21", - "libp2p-core", - "libp2p-swarm", - "log", - "lru 0.7.3", - "rand 0.7.3", - "smallvec", - "unsigned-varint 0.7.1", - "wasm-timer", -] - -[[package]] -name = "libp2p-swarm" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f5184a508f223bc100a12665517773fb8730e9f36fc09eefb670bf01b107ae9" -dependencies = [ - "either", - "futures 0.3.21", - "libp2p-core", - "log", - "rand 0.7.3", - "smallvec", - "void", - "wasm-timer", -] - -[[package]] -name = "libp2p-swarm-derive" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "072c290f727d39bdc4e9d6d1c847978693d25a673bd757813681e33e5f6c00c2" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "libp2p-tcp" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7399c5b6361ef525d41c11fcf51635724f832baf5819b30d3d873eabb4fbae4b" -dependencies = [ - "async-io", - "futures 0.3.21", - "futures-timer", - "if-watch", - "ipnet", - "libc", - "libp2p-core", - "log", - "socket2 0.4.4", -] - -[[package]] -name = "libp2p-uds" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8b7563e46218165dfd60f64b96f7ce84590d75f53ecbdc74a7dd01450dc5973" -dependencies = [ - "async-std", - "futures 0.3.21", - "libp2p-core", - "log", -] - -[[package]] -name = "libp2p-wasm-ext" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1008a302b73c5020251f9708c653f5ed08368e530e247cc9cd2f109ff30042cf" -dependencies = [ - "futures 0.3.21", - "js-sys", - "libp2p-core", - "parity-send-wrapper", - "wasm-bindgen", - "wasm-bindgen-futures", -] - -[[package]] -name = "libp2p-websocket" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e12df82d1ed64969371a9e65ea92b91064658604cc2576c2757f18ead9a1cf" -dependencies = [ - "either", - "futures 0.3.21", - "futures-rustls", - "libp2p-core", - "log", - "quicksink", - "rw-stream-sink", - "soketto", - "url 2.2.2", - "webpki-roots 0.21.1", -] - -[[package]] -name = "libp2p-yamux" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7362abb8867d7187e7e93df17f460d554c997fc5c8ac57dc1259057f6889af" -dependencies = [ - "futures 0.3.21", - "libp2p-core", - "parking_lot 0.11.2", - "thiserror", - "yamux", -] - -[[package]] -name = "libsecp256k1" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0452aac8bab02242429380e9b2f94ea20cea2b37e2c1777a1358799bbe97f37" -dependencies = [ - "arrayref", - "base64", - "digest 0.9.0", - "hmac-drbg", - "libsecp256k1-core", - "libsecp256k1-gen-ecmult", - "libsecp256k1-gen-genmult", - "rand 0.8.5", - "serde", - "sha2 0.9.8", - "typenum", -] - -[[package]] -name = "libsecp256k1-core" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" -dependencies = [ - "crunchy", - "digest 0.9.0", - "subtle", -] - -[[package]] -name = "libsecp256k1-gen-ecmult" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" -dependencies = [ - "libsecp256k1-core", -] - -[[package]] -name = "libsecp256k1-gen-genmult" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" -dependencies = [ - "libsecp256k1-core", -] - -[[package]] -name = "libz-sys" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "linked-hash-map" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" - -[[package]] -name = "linked_hash_set" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47186c6da4d81ca383c7c47c1bfc80f4b95f4720514d860a5407aaf4233f9588" -dependencies = [ - "linked-hash-map", -] - -[[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.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" -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 = "lru" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ea2d928b485416e8908cff2d97d621db22b27f7b3b6729e438bcf42c671ba91" -dependencies = [ - "hashbrown 0.11.2", -] - -[[package]] -name = "lru" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb87f3080f6d1d69e8c564c0fcfde1d7aa8cc451ce40cae89479111f03bc0eb" -dependencies = [ - "hashbrown 0.11.2", -] - -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "match_cfg" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" - -[[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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add85d4dd35074e6fedc608f8c8f513a3548619a9024b751949ef0e8e45a4d84" -dependencies = [ - "rawpointer", -] - -[[package]] -name = "memchr" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" - -[[package]] -name = "memmap2" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4647a11b578fead29cdbb34d4adef8dd3dc35b876c9c6d5240d83f205abfe96e" -dependencies = [ - "libc", -] - -[[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.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6566c70c1016f525ced45d7b7f97730a2bafb037c788211d0c186ef5b2189f0a" -dependencies = [ - "hash-db", - "hashbrown 0.12.0", - "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 = "messages-relay" -version = "0.1.0" -dependencies = [ - "async-std", - "async-trait", - "bp-messages", - "bp-runtime", - "finality-relay", - "futures 0.3.21", - "hex", - "log", - "num-traits", - "parking_lot 0.11.2", - "relay-utils", - "sp-arithmetic", -] - -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[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 = "mio" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba42135c6a5917b9db9cd7b293e5409e1c6b041e6f9825e92e55a894c63b6f8" -dependencies = [ - "libc", - "log", - "miow", - "ntapi", - "wasi 0.11.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", -] - -[[package]] -name = "multiaddr" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48ee4ea82141951ac6379f964f71b20876d43712bea8faf6dd1a375e08a46499" -dependencies = [ - "arrayref", - "bs58", - "byteorder", - "data-encoding", - "multihash 0.14.0", - "percent-encoding 2.1.0", - "serde", - "static_assertions", - "unsigned-varint 0.7.1", - "url 2.2.2", -] - -[[package]] -name = "multibase" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b78c60039650ff12e140ae867ef5299a58e19dded4d334c849dc7177083667e2" -dependencies = [ - "base-x", - "data-encoding", - "data-encoding-macro", -] - -[[package]] -name = "multihash" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dac63698b887d2d929306ea48b63760431ff8a24fac40ddb22f9c7f49fb7cab" -dependencies = [ - "blake2b_simd", - "blake2s_simd", - "blake3", - "digest 0.9.0", - "generic-array 0.14.4", - "multihash-derive", - "sha2 0.9.8", - "sha3 0.9.1", - "unsigned-varint 0.5.1", -] - -[[package]] -name = "multihash" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "752a61cd890ff691b4411423d23816d5866dd5621e4d1c5687a53b94b5a979d8" -dependencies = [ - "digest 0.9.0", - "generic-array 0.14.4", - "multihash-derive", - "sha2 0.9.8", - "unsigned-varint 0.7.1", -] - -[[package]] -name = "multihash-derive" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "424f6e86263cd5294cbd7f1e95746b95aca0e0d66bff31e5a40d6baa87b4aa99" -dependencies = [ - "proc-macro-crate 1.1.3", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "multimap" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" - -[[package]] -name = "multistream-select" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56a336acba8bc87c8876f6425407dbbe6c417bf478b22015f8fb0994ef3bc0ab" -dependencies = [ - "bytes", - "futures 0.3.21", - "log", - "pin-project 1.0.10", - "smallvec", - "unsigned-varint 0.7.1", -] - -[[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.5", - "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 = "nohash-hasher" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" - -[[package]] -name = "ntapi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" -dependencies = [ - "winapi", -] - -[[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 = "num_threads" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ba99ba6393e2c3734791401b66902d981cb03bf190af674ca69949b6d5fb15" -dependencies = [ - "libc", -] - -[[package]] -name = "object" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" - -[[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 = "open-metrics-client" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7337d80c23c2d8b1349563981bc4fb531220733743ba8115454a67b181173f0d" -dependencies = [ - "dtoa", - "itoa 0.4.8", - "open-metrics-client-derive-text-encode", - "owning_ref", -] - -[[package]] -name = "open-metrics-client-derive-text-encode" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15c83b586f00268c619c1cb3340ec1a6f59dd9ba1d9833a273a68e6d5cd8ffc" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "openssl-probe" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" - -[[package]] -name = "openssl-sys" -version = "0.9.71" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df13d165e607909b363a4757a6f133f8a818a74e9d3a98d09c6128e15fa4c73" -dependencies = [ - "autocfg", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "owning_ref" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff55baddef9e4ad00f88b6c743a2a8062d4c6ade126c2a528644b8e444d52ce" -dependencies = [ - "stable_deref_trait", -] - -[[package]] -name = "pallet-balances" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "log", - "parity-scale-codec", - "scale-info", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "pallet-bridge-dispatch" -version = "0.1.0" -dependencies = [ - "bp-message-dispatch", - "bp-runtime", - "frame-support", - "frame-system", - "log", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "pallet-bridge-grandpa" -version = "0.1.0" -dependencies = [ - "bp-header-chain", - "bp-runtime", - "bp-test-utils", - "finality-grandpa", - "frame-benchmarking", - "frame-support", - "frame-system", - "log", - "num-traits", - "parity-scale-codec", - "scale-info", - "serde", - "sp-core", - "sp-finality-grandpa", - "sp-io", - "sp-runtime", - "sp-std", - "sp-trie", -] - -[[package]] -name = "pallet-bridge-messages" -version = "0.1.0" -dependencies = [ - "bitvec", - "bp-message-dispatch", - "bp-messages", - "bp-runtime", - "frame-benchmarking", - "frame-support", - "frame-system", - "log", - "num-traits", - "pallet-balances", - "parity-scale-codec", - "scale-info", - "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "pallet-bridge-parachains" -version = "0.1.0" -dependencies = [ - "bp-header-chain", - "bp-polkadot-core", - "bp-runtime", - "bp-test-utils", - "frame-support", - "frame-system", - "log", - "pallet-bridge-grandpa", - "parity-scale-codec", - "scale-info", - "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-trie", -] - -[[package]] -name = "pallet-fee-market" -version = "0.1.0" -dependencies = [ - "bitvec", - "bp-messages", - "bp-runtime", - "frame-benchmarking", - "frame-support", - "frame-system", - "pallet-balances", - "pallet-bridge-messages", - "pallet-timestamp", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "pallet-timestamp" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "parity-scale-codec", "scale-info", - "sp-inherents", - "sp-runtime", - "sp-std", - "sp-timestamp", -] - -[[package]] -name = "pallet-transaction-payment" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "serde", - "smallvec", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "pallet-transaction-payment-rpc-runtime-api" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "pallet-transaction-payment", - "parity-scale-codec", - "sp-api", - "sp-runtime", -] - -[[package]] -name = "parity-scale-codec" -version = "3.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8b44461635bbb1a0300f100a841e571e7d919c81c73075ef5d152ffdb521066" -dependencies = [ - "arrayvec 0.7.2", - "bitvec", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive", - "serde", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "3.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c45ed1f39709f5a89338fab50e59816b2e8815f5bb58276e7ddf9afd495f73f8" -dependencies = [ - "proc-macro-crate 1.1.3", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "parity-send-wrapper" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" - -[[package]] -name = "parity-util-mem" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c32561d248d352148124f036cac253a644685a21dc9fea383eb4907d7bd35a8f" -dependencies = [ - "cfg-if 1.0.0", - "ethereum-types", - "hashbrown 0.12.0", - "impl-trait-for-tuples", - "lru 0.7.3", - "parity-util-mem-derive", - "parking_lot 0.12.0", - "primitive-types", - "smallvec", - "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.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.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.5", -] - -[[package]] -name = "parking_lot" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" -dependencies = [ - "lock_api", - "parking_lot_core 0.9.1", -] - -[[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", - "smallvec", - "winapi", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28141e0cc4143da2443301914478dc976a61ffdb3f043058310c70df2fed8954" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "redox_syscall", - "smallvec", - "windows-sys", -] - -[[package]] -name = "paste" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" - -[[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 = "percent-encoding" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" - -[[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 = "petgraph" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a13a2fa9d0b63e5f22328828741e523766fff0ee9e779316902290dff3f824f" -dependencies = [ - "fixedbitset", - "indexmap", -] - -[[package]] -name = "pin-project" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9615c18d31137579e9ff063499264ddc1278e7b1982757ebc111028c4d1dc909" -dependencies = [ - "pin-project-internal 0.4.29", -] - -[[package]] -name = "pin-project" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" -dependencies = [ - "pin-project-internal 1.0.10", -] - -[[package]] -name = "pin-project-internal" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "044964427019eed9d49d9d5bbce6047ef18f37100ea400912a9fa4a3523ab12a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-lite" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" - -[[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.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f" - -[[package]] -name = "polling" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "log", - "wepoll-ffi", - "winapi", -] - -[[package]] -name = "poly1305" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" -dependencies = [ - "cpufeatures 0.2.1", - "opaque-debug 0.3.0", - "universal-hash", -] - -[[package]] -name = "polyval" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" -dependencies = [ - "cfg-if 1.0.0", - "cpufeatures 0.2.1", - "opaque-debug 0.3.0", - "universal-hash", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" - -[[package]] -name = "primitive-types" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" -dependencies = [ - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "scale-info", - "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.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" -dependencies = [ - "thiserror", - "toml", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "prometheus" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f64969ffd5dd8f39bd57a68ac53c163a095ed9d0fb707146da1b27025a3504" -dependencies = [ - "cfg-if 1.0.0", - "fnv", - "lazy_static", - "memchr", - "parking_lot 0.11.2", - "thiserror", -] - -[[package]] -name = "prost" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-build" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62941722fb675d463659e49c4f3fe1fe792ff24fe5bbaa9c08cd3b98a1c354f5" -dependencies = [ - "bytes", - "heck", - "itertools", - "lazy_static", - "log", - "multimap", - "petgraph", - "prost", - "prost-types", - "regex", - "tempfile", - "which", -] - -[[package]] -name = "prost-derive" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "prost-types" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534b7a0e836e3c482d2693070f982e39e7611da9695d4d1f5a4b186b51faef0a" -dependencies = [ - "bytes", - "prost", -] - -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - -[[package]] -name = "quicksink" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77de3c815e5a160b1539c6592796801df2043ae35e123b46d73380cfa57af858" -dependencies = [ - "futures-core", - "futures-sink", - "pin-project-lite 0.1.12", -] - -[[package]] -name = "quote" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[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", - "rand_pcg", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.3", -] - -[[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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "964d548f8e7d12e102ef183a0de7e98180c9f8729f555897a857b96e48122d2f" -dependencies = [ - "num-traits", - "rand 0.8.5", -] - -[[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_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.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.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", + "sp-runtime", + "sp-std", ] [[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +name = "pallet-bridge-dispatch" +version = "0.1.0" dependencies = [ - "regex-syntax", + "bp-message-dispatch", + "bp-runtime", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] -name = "regex-syntax" -version = "0.6.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" - -[[package]] -name = "relay-kusama-client" +name = "pallet-bridge-grandpa" version = "0.1.0" dependencies = [ "bp-header-chain", - "bp-kusama", - "bp-message-dispatch", - "bp-messages", - "bp-polkadot", - "bp-polkadot-core", "bp-runtime", - "bridge-runtime-common", + "bp-test-utils", + "finality-grandpa", + "frame-benchmarking", "frame-support", - "pallet-bridge-dispatch", + "frame-system", + "log", + "num-traits", "parity-scale-codec", - "relay-substrate-client", - "relay-utils", "scale-info", + "serde", "sp-core", + "sp-finality-grandpa", + "sp-io", "sp-runtime", + "sp-std", + "sp-trie", ] [[package]] -name = "relay-polkadot-client" +name = "pallet-bridge-messages" version = "0.1.0" dependencies = [ - "bp-header-chain", - "bp-kusama", + "bitvec", "bp-message-dispatch", "bp-messages", - "bp-polkadot", - "bp-polkadot-core", "bp-runtime", - "bridge-runtime-common", + "frame-benchmarking", "frame-support", - "pallet-bridge-dispatch", + "frame-system", + "log", + "num-traits", + "pallet-balances", "parity-scale-codec", - "relay-substrate-client", - "relay-utils", "scale-info", + "serde", "sp-core", + "sp-io", "sp-runtime", + "sp-std", ] [[package]] -name = "relay-rococo-client" +name = "pallet-bridge-parachains" version = "0.1.0" dependencies = [ "bp-header-chain", - "bp-message-dispatch", - "bp-messages", "bp-polkadot-core", - "bp-rococo", "bp-runtime", - "bp-wococo", - "bridge-runtime-common", + "bp-test-utils", "frame-support", - "pallet-bridge-dispatch", - "pallet-bridge-messages", + "frame-system", + "log", + "pallet-bridge-grandpa", "parity-scale-codec", - "relay-substrate-client", - "relay-utils", "scale-info", + "serde", "sp-core", + "sp-io", "sp-runtime", + "sp-std", + "sp-trie", ] [[package]] -name = "relay-substrate-client" +name = "pallet-fee-market" version = "0.1.0" dependencies = [ - "async-std", - "async-trait", - "bp-header-chain", + "bitvec", "bp-messages", "bp-runtime", - "finality-relay", + "frame-benchmarking", "frame-support", "frame-system", - "futures 0.3.21", - "jsonrpsee", - "log", - "num-traits", "pallet-balances", "pallet-bridge-messages", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc-runtime-api", + "pallet-timestamp", "parity-scale-codec", - "rand 0.7.3", - "relay-utils", - "sc-chain-spec", - "sc-rpc-api", - "sc-transaction-pool-api", - "serde", + "scale-info", "sp-core", - "sp-finality-grandpa", - "sp-rpc", + "sp-io", "sp-runtime", - "sp-storage", - "sp-trie", - "sp-version", - "thiserror", - "tokio", + "sp-std", ] [[package]] -name = "relay-utils" -version = "0.1.0" +name = "pallet-timestamp" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ - "ansi_term", - "anyhow", - "async-std", - "async-trait", - "backoff", - "bp-runtime", - "env_logger 0.8.4", - "futures 0.3.21", - "isahc", - "jsonpath_lib", + "frame-benchmarking", + "frame-support", + "frame-system", "log", - "num-traits", - "serde_json", - "substrate-prometheus-endpoint", - "sysinfo", - "thiserror", - "time 0.3.7", - "tokio", + "parity-scale-codec", + "scale-info", + "sp-inherents", + "sp-runtime", + "sp-std", + "sp-timestamp", ] [[package]] -name = "remove_dir_all" -version = "0.5.3" +name = "pallet-transaction-payment" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "parity-scale-codec" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9182e4a71cae089267ab03e67c99368db7cd877baf50f931e5d6d4b71e195ac0" +dependencies = [ + "arrayvec 0.7.2", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9299338969a3d2f491d65f140b00ddec470858402f888af98e8642fb5e8965cd" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "parity-util-mem" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +checksum = "c32561d248d352148124f036cac253a644685a21dc9fea383eb4907d7bd35a8f" dependencies = [ + "cfg-if", + "ethereum-types", + "hashbrown 0.12.1", + "impl-trait-for-tuples", + "lru", + "parity-util-mem-derive", + "parking_lot", + "primitive-types", + "smallvec", "winapi", ] [[package]] -name = "resolv-conf" -version = "0.7.0" +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.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" + +[[package]] +name = "parking_lot" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ - "hostname", - "quick-error", + "lock_api", + "parking_lot_core", ] [[package]] -name = "ring" -version = "0.16.20" +name = "parking_lot_core" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" dependencies = [ - "cc", + "cfg-if", "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi", + "redox_syscall", + "smallvec", + "windows-sys", ] [[package]] -name = "rlp" -version = "0.5.1" +name = "paste" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "999508abb0ae792aabed2460c45b89106d97fe4adac593bdaef433c2605847b5" +checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" + +[[package]] +name = "pbkdf2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" dependencies = [ - "bytes", - "rustc-hex", + "crypto-mac 0.8.0", ] [[package]] -name = "rustc-demangle" -version = "0.1.21" +name = "pbkdf2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa" +dependencies = [ + "crypto-mac 0.11.1", +] [[package]] -name = "rustc-hash" -version = "1.1.0" +name = "pin-project-lite" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] -name = "rustc-hex" -version = "2.1.0" +name = "pin-utils" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "primitive-types" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" +dependencies = [ + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro2" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] -name = "rustc_version" -version = "0.3.3" +name = "rand" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "semver 0.11.0", + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", ] [[package]] -name = "rustc_version" -version = "0.4.0" +name = "rand" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "semver 1.0.4", + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", ] [[package]] -name = "rustls" -version = "0.19.1" +name = "rand_chacha" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ - "base64", - "log", - "ring", - "sct 0.6.1", - "webpki 0.21.4", + "ppv-lite86", + "rand_core 0.5.1", ] [[package]] -name = "rustls" -version = "0.20.4" +name = "rand_chacha" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fbfeb8d0ddb84706bc597a5574ab8912817c52a397f819e5b614e2265206921" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ - "log", - "ring", - "sct 0.7.0", - "webpki 0.22.0", + "ppv-lite86", + "rand_core 0.6.3", ] [[package]] -name = "rustls-native-certs" -version = "0.6.1" +name = "rand_core" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca9ebdfa27d3fc180e42879037b5338ab1c040c06affd00d8338598e7800943" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "openssl-probe", - "rustls-pemfile", - "schannel", - "security-framework", + "getrandom 0.1.16", ] [[package]] -name = "rustls-pemfile" -version = "0.2.1" +name = "rand_core" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "base64", + "getrandom 0.2.7", ] [[package]] -name = "rw-stream-sink" -version = "0.2.1" +name = "rand_distr" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" dependencies = [ - "futures 0.3.21", - "pin-project 0.4.29", - "static_assertions", + "num-traits", + "rand 0.8.5", ] [[package]] -name = "ryu" -version = "1.0.5" +name = "rand_hc" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] [[package]] -name = "salsa20" -version = "0.9.0" +name = "rand_pcg" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0fbb5f676da676c260ba276a8f43a8dc67cf02d1438423aeb1c677a7212686" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" dependencies = [ - "cipher", + "rand_core 0.5.1", ] [[package]] -name = "sc-allocator" -version = "4.1.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "log", - "sp-core", - "sp-wasm-interface", - "thiserror", -] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] -name = "sc-block-builder" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +name = "redox_syscall" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" dependencies = [ - "parity-scale-codec", - "sc-client-api", - "sp-api", - "sp-block-builder", - "sp-blockchain", - "sp-core", - "sp-inherents", - "sp-runtime", - "sp-state-machine", + "bitflags", ] [[package]] -name = "sc-chain-spec" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +name = "ref-cast" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685d58625b6c2b83e4cc88a27c4bf65adb7b6b16dbdc413e515c9405b47432ab" dependencies = [ - "impl-trait-for-tuples", - "memmap2", - "parity-scale-codec", - "sc-chain-spec-derive", - "sc-network", - "sc-telemetry", - "serde", - "serde_json", - "sp-core", - "sp-runtime", + "ref-cast-impl", ] [[package]] -name = "sc-chain-spec-derive" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +name = "ref-cast-impl" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a043824e29c94169374ac5183ac0ed43f5724dc4556b19568007486bd840fa1f" dependencies = [ - "proc-macro-crate 1.1.3", "proc-macro2", "quote", "syn", ] [[package]] -name = "sc-client-api" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "fnv", - "futures 0.3.21", - "hash-db", - "log", - "parity-scale-codec", - "parking_lot 0.12.0", - "sc-executor", - "sc-transaction-pool-api", - "sc-utils", - "sp-api", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-database", - "sp-externalities", - "sp-keystore", - "sp-runtime", - "sp-state-machine", - "sp-storage", - "sp-trie", - "substrate-prometheus-endpoint", -] - -[[package]] -name = "sc-consensus" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "async-trait", - "futures 0.3.21", - "futures-timer", - "libp2p", - "log", - "parking_lot 0.12.0", - "sc-client-api", - "sc-utils", - "serde", - "sp-api", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-runtime", - "sp-state-machine", - "substrate-prometheus-endpoint", - "thiserror", -] - -[[package]] -name = "sc-executor" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +name = "regex" +version = "1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" dependencies = [ - "lazy_static", - "lru 0.6.6", - "parity-scale-codec", - "parking_lot 0.12.0", - "sc-executor-common", - "sc-executor-wasmi", - "sp-api", - "sp-core", - "sp-core-hashing-proc-macro", - "sp-externalities", - "sp-io", - "sp-panic-handler", - "sp-runtime-interface", - "sp-tasks", - "sp-trie", - "sp-version", - "sp-wasm-interface", - "tracing", - "wasmi", + "aho-corasick", + "memchr", + "regex-syntax", ] [[package]] -name = "sc-executor-common" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "environmental", - "parity-scale-codec", - "sc-allocator", - "sp-core", - "sp-maybe-compressed-blob", - "sp-serializer", - "sp-wasm-interface", - "thiserror", - "wasm-instrument", - "wasmi", + "regex-syntax", ] [[package]] -name = "sc-executor-wasmi" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "log", - "parity-scale-codec", - "sc-allocator", - "sc-executor-common", - "scoped-tls", - "sp-core", - "sp-runtime-interface", - "sp-wasm-interface", - "wasmi", -] +name = "regex-syntax" +version = "0.6.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" [[package]] -name = "sc-network" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +name = "rfc6979" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" dependencies = [ - "async-trait", - "asynchronous-codec 0.5.0", - "bitflags", - "bytes", - "cid", - "either", - "fnv", - "fork-tree", - "futures 0.3.21", - "futures-timer", - "hex", - "ip_network", - "libp2p", - "linked-hash-map", - "linked_hash_set", - "log", - "lru 0.7.3", - "parity-scale-codec", - "parking_lot 0.12.0", - "pin-project 1.0.10", - "prost", - "prost-build", - "rand 0.7.3", - "sc-block-builder", - "sc-client-api", - "sc-consensus", - "sc-peerset", - "sc-utils", - "serde", - "serde_json", - "smallvec", - "sp-arithmetic", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-finality-grandpa", - "sp-runtime", - "substrate-prometheus-endpoint", - "thiserror", - "unsigned-varint 0.6.0", - "void", + "crypto-bigint", + "hmac 0.11.0", "zeroize", ] [[package]] -name = "sc-peerset" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +name = "rlp" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "999508abb0ae792aabed2460c45b89106d97fe4adac593bdaef433c2605847b5" dependencies = [ - "futures 0.3.21", - "libp2p", - "log", - "sc-utils", - "serde_json", - "wasm-timer", + "bytes", + "rustc-hex", ] [[package]] -name = "sc-rpc-api" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "futures 0.3.21", - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", - "jsonrpc-pubsub", - "log", - "parity-scale-codec", - "parking_lot 0.12.0", - "sc-chain-spec", - "sc-transaction-pool-api", - "serde", - "serde_json", - "sp-core", - "sp-rpc", - "sp-runtime", - "sp-tracing", - "sp-version", - "thiserror", -] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" [[package]] -name = "sc-telemetry" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "chrono", - "futures 0.3.21", - "libp2p", - "log", - "parking_lot 0.12.0", - "pin-project 1.0.10", - "rand 0.7.3", - "serde", - "serde_json", - "thiserror", - "wasm-timer", -] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] -name = "sc-transaction-pool-api" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "futures 0.3.21", - "log", - "serde", - "sp-blockchain", - "sp-runtime", - "thiserror", -] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" [[package]] -name = "sc-utils" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "futures 0.3.21", - "futures-timer", - "lazy_static", - "log", - "parking_lot 0.12.0", - "prometheus", -] +name = "ryu" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" [[package]] name = "scale-info" @@ -4872,7 +2163,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c46be926081c9f4dd5dd9b6f1d3e3229f2360bc6502dd8836f84a93b7c75e99a" dependencies = [ "bitvec", - "cfg-if 1.0.0", + "cfg-if", "derive_more", "parity-scale-codec", "scale-info-derive", @@ -4885,22 +2176,12 @@ version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50e334bb10a245e28e5fd755cabcafd96cfcd167c99ae63a46924ca8d8703a3c" dependencies = [ - "proc-macro-crate 1.1.3", + "proc-macro-crate", "proc-macro2", "quote", "syn", ] -[[package]] -name = "schannel" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" -dependencies = [ - "lazy_static", - "winapi", -] - [[package]] name = "schnorrkel" version = "0.9.1" @@ -4919,12 +2200,6 @@ dependencies = [ "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" @@ -4932,23 +2207,15 @@ 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 = "sct" -version = "0.7.0" +name = "sec1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" dependencies = [ - "ring", - "untrusted", + "der", + "generic-array 0.14.5", + "subtle", + "zeroize", ] [[package]] @@ -4978,67 +2245,20 @@ dependencies = [ "zeroize", ] -[[package]] -name = "security-framework" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[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.136" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.136" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" dependencies = [ "proc-macro2", "quote", @@ -5047,29 +2267,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.78" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" dependencies = [ - "indexmap", - "itoa 1.0.1", + "itoa 1.0.2", "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 0.2.1", - "digest 0.9.0", - "opaque-debug 0.3.0", -] - [[package]] name = "sha2" version = "0.8.2" @@ -5084,40 +2290,28 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer 0.9.0", - "cfg-if 1.0.0", - "cpufeatures 0.2.1", + "cfg-if", + "cpufeatures", "digest 0.9.0", "opaque-debug 0.3.0", ] [[package]] name = "sha2" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" +checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" dependencies = [ - "cfg-if 1.0.0", - "cpufeatures 0.2.1", + "cfg-if", + "cpufeatures", "digest 0.10.3", ] -[[package]] -name = "sha3" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "keccak", - "opaque-debug 0.3.0", -] - [[package]] name = "sha3" version = "0.10.1" @@ -5142,6 +2336,10 @@ name = "signature" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +dependencies = [ + "digest 0.9.0", + "rand_core 0.6.3", +] [[package]] name = "simba" @@ -5157,86 +2355,20 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" - -[[package]] -name = "sluice" -version = "0.5.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7400c0eff44aa2fcb5e31a5f24ba9716ed90138769e4977a2ba6014ae63eb5" -dependencies = [ - "async-channel", - "futures-core", - "futures-io", -] +checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" [[package]] name = "smallvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" - -[[package]] -name = "snow" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6142f7c25e94f6fd25a32c3348ec230df9109b463f59c8c7acc4bd34936babb7" -dependencies = [ - "aes-gcm", - "blake2 0.9.2", - "chacha20poly1305", - "rand 0.8.5", - "rand_core 0.6.3", - "ring", - "rustc_version 0.3.3", - "sha2 0.9.8", - "subtle", - "x25519-dalek", -] - -[[package]] -name = "socket2" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "winapi", -] - -[[package]] -name = "socket2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "soketto" -version = "0.7.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" -dependencies = [ - "base64", - "bytes", - "flate2", - "futures 0.3.21", - "httparse", - "log", - "rand 0.8.5", - "sha-1", -] +checksum = "cc88c725d61fc6c3132893370cac4a0200e3fedf5da8331c570664b1987f5ca2" [[package]] name = "sp-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "hash-db", "log", @@ -5253,10 +2385,10 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ - "blake2 0.10.4", - "proc-macro-crate 1.1.3", + "blake2", + "proc-macro-crate", "proc-macro2", "quote", "syn", @@ -5265,7 +2397,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "parity-scale-codec", "scale-info", @@ -5278,7 +2410,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "integer-sqrt", "num-traits", @@ -5290,59 +2422,10 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "sp-block-builder" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "parity-scale-codec", - "sp-api", - "sp-inherents", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "sp-blockchain" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "futures 0.3.21", - "log", - "lru 0.7.3", - "parity-scale-codec", - "parking_lot 0.12.0", - "sp-api", - "sp-consensus", - "sp-database", - "sp-runtime", - "sp-state-machine", - "thiserror", -] - -[[package]] -name = "sp-consensus" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "async-trait", - "futures 0.3.21", - "futures-timer", - "log", - "parity-scale-codec", - "sp-core", - "sp-inherents", - "sp-runtime", - "sp-state-machine", - "sp-std", - "sp-version", - "thiserror", -] - [[package]] name = "sp-core" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "base58", "bitflags", @@ -5350,7 +2433,7 @@ dependencies = [ "byteorder", "dyn-clonable", "ed25519-dalek", - "futures 0.3.21", + "futures", "hash-db", "hash256-std-hasher", "hex", @@ -5362,7 +2445,7 @@ dependencies = [ "num-traits", "parity-scale-codec", "parity-util-mem", - "parking_lot 0.12.0", + "parking_lot", "primitive-types", "rand 0.7.3", "regex", @@ -5388,13 +2471,13 @@ dependencies = [ [[package]] name = "sp-core-hashing" version = "4.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ - "blake2 0.10.4", + "blake2", "byteorder", "digest 0.10.3", - "sha2 0.10.1", - "sha3 0.10.1", + "sha2 0.10.2", + "sha3", "sp-std", "twox-hash", ] @@ -5402,7 +2485,7 @@ dependencies = [ [[package]] name = "sp-core-hashing-proc-macro" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "proc-macro2", "quote", @@ -5410,19 +2493,10 @@ dependencies = [ "syn", ] -[[package]] -name = "sp-database" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "kvdb", - "parking_lot 0.12.0", -] - [[package]] name = "sp-debug-derive" version = "4.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "proc-macro2", "quote", @@ -5432,7 +2506,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.12.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "environmental", "parity-scale-codec", @@ -5443,7 +2517,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "finality-grandpa", "log", @@ -5461,7 +2535,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -5475,14 +2549,14 @@ dependencies = [ [[package]] name = "sp-io" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ - "futures 0.3.21", + "futures", "hash-db", "libsecp256k1", "log", "parity-scale-codec", - "parking_lot 0.12.0", + "parking_lot", "secp256k1", "sp-core", "sp-externalities", @@ -5500,52 +2574,33 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.12.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "async-trait", - "futures 0.3.21", + "futures", "merlin", "parity-scale-codec", - "parking_lot 0.12.0", + "parking_lot", "schnorrkel", "sp-core", "sp-externalities", "thiserror", ] -[[package]] -name = "sp-maybe-compressed-blob" -version = "4.1.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "thiserror", - "zstd", -] - [[package]] name = "sp-panic-handler" version = "4.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "backtrace", "lazy_static", "regex", ] -[[package]] -name = "sp-rpc" -version = "6.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "rustc-hash", - "serde", - "sp-core", -] - [[package]] name = "sp-runtime" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "either", "hash256-std-hasher", @@ -5567,7 +2622,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -5584,28 +2639,19 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "Inflector", - "proc-macro-crate 1.1.3", + "proc-macro-crate", "proc-macro2", "quote", "syn", ] -[[package]] -name = "sp-serializer" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "sp-staking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "parity-scale-codec", "scale-info", @@ -5616,13 +2662,13 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.12.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "hash-db", "log", "num-traits", "parity-scale-codec", - "parking_lot 0.12.0", + "parking_lot", "rand 0.7.3", "smallvec", "sp-core", @@ -5632,19 +2678,18 @@ dependencies = [ "sp-trie", "thiserror", "tracing", - "trie-db", "trie-root", ] [[package]] name = "sp-std" version = "4.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" [[package]] name = "sp-storage" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "impl-serde", "parity-scale-codec", @@ -5654,23 +2699,10 @@ dependencies = [ "sp-std", ] -[[package]] -name = "sp-tasks" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "log", - "sp-core", - "sp-externalities", - "sp-io", - "sp-runtime-interface", - "sp-std", -] - [[package]] name = "sp-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "async-trait", "futures-timer", @@ -5686,7 +2718,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "parity-scale-codec", "sp-std", @@ -5698,7 +2730,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "hash-db", "memory-db", @@ -5714,7 +2746,7 @@ dependencies = [ [[package]] name = "sp-version" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "impl-serde", "parity-scale-codec", @@ -5731,7 +2763,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "parity-scale-codec", "proc-macro2", @@ -5742,7 +2774,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" +source = "git+https://github.com/paritytech/substrate?branch=master#ee3eb8f2448cc1bb978c5d1564febd351c128bb0" dependencies = [ "impl-trait-for-tuples", "log", @@ -5751,19 +2783,14 @@ dependencies = [ "wasmi", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "ss58-registry" -version = "1.12.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8319f44e20b42e5c11b88b1ad4130c35fe2974665a007b08b02322070177136a" +checksum = "77ef98aedad3dc52e10995e7ed15f1279e11d4da35795f5dac7305742d0feb66" dependencies = [ "Inflector", + "num-format", "proc-macro2", "quote", "serde", @@ -5771,12 +2798,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - [[package]] name = "static_assertions" version = "1.1.0" @@ -5805,23 +2826,10 @@ dependencies = [ "hmac 0.11.0", "pbkdf2 0.8.0", "schnorrkel", - "sha2 0.9.8", + "sha2 0.9.9", "zeroize", ] -[[package]] -name = "substrate-prometheus-endpoint" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=master#89fcb3e4f62d221d4e161a437768e77d6265889e" -dependencies = [ - "futures-util", - "hyper", - "log", - "prometheus", - "thiserror", - "tokio", -] - [[package]] name = "subtle" version = "2.4.1" @@ -5830,13 +2838,13 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.88" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd69e719f31e88618baa1eaa6ee2de5c9a1c004f1e9ecdb58e8352a13f20a01" +checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -5851,66 +2859,26 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "sysinfo" -version = "0.15.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de94457a09609f33fec5e7fceaf907488967c6c7c75d64da6a7ce6ffdb8b5abd" -dependencies = [ - "cc", - "cfg-if 1.0.0", - "core-foundation-sys", - "doc-comment", - "libc", - "ntapi", - "once_cell", - "rayon", - "winapi", -] - [[package]] name = "tap" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" -[[package]] -name = "tempfile" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "rand 0.8.5", - "redox_syscall", - "remove_dir_all", - "winapi", -] - -[[package]] -name = "termcolor" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" -dependencies = [ - "winapi-util", -] - [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" dependencies = [ "proc-macro2", "quote", @@ -5926,28 +2894,6 @@ dependencies = [ "once_cell", ] -[[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 = "time" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "004cbc98f30fa233c61a38bc77e96a9106e65c88f2d3bef182ae952027e5753d" -dependencies = [ - "itoa 1.0.1", - "libc", - "num_threads", -] - [[package]] name = "tiny-bip39" version = "0.8.2" @@ -5960,7 +2906,7 @@ dependencies = [ "pbkdf2 0.4.0", "rand 0.7.3", "rustc-hash", - "sha2 0.9.8", + "sha2 0.9.9", "thiserror", "unicode-normalization", "wasm-bindgen", @@ -5978,9 +2924,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ "tinyvec_macros", ] @@ -5989,94 +2935,34 @@ dependencies = [ name = "tinyvec_macros" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - -[[package]] -name = "tokio" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee" -dependencies = [ - "libc", - "mio", - "num_cpus", - "parking_lot 0.12.0", - "pin-project-lite 0.2.7", - "socket2 0.4.4", - "tokio-macros", - "winapi", -] - -[[package]] -name = "tokio-macros" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tokio-rustls" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a27d5f2b839802bd8267fa19b0530f5a08b9c08cd417976be2a65d130fe1c11b" -dependencies = [ - "rustls 0.20.4", - "tokio", - "webpki 0.22.0", -] - -[[package]] -name = "tokio-util" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" -dependencies = [ - "bytes", - "futures-core", - "futures-io", - "futures-sink", - "log", - "pin-project-lite 0.2.7", - "tokio", -] +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "toml" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" dependencies = [ "serde", ] -[[package]] -name = "tower-service" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" - [[package]] name = "tracing" -version = "0.1.32" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1bdf54a7c28a2bbf701e1d2233f6c77f473486b94bee4f9678da5a148dca7f" +checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" dependencies = [ - "cfg-if 1.0.0", - "log", - "pin-project-lite 0.2.7", + "cfg-if", + "pin-project-lite", "tracing-attributes", "tracing-core", ] [[package]] name = "tracing-attributes" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b" +checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" dependencies = [ "proc-macro2", "quote", @@ -6085,29 +2971,19 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.23" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa31669fa42c09c34d94d8165dd2012e8ff3c66aca50f3bb226b68f216f2706c" +checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7" dependencies = [ - "lazy_static", + "once_cell", "valuable", ] -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project 1.0.10", - "tracing", -] - [[package]] name = "tracing-log" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" dependencies = [ "lazy_static", "log", @@ -6116,9 +2992,9 @@ dependencies = [ [[package]] name = "tracing-serde" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" dependencies = [ "serde", "tracing-core", @@ -6153,7 +3029,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d32d034c0d3db64b43c31de38e945f15b40cd4ca6d2dcfc26d4798ce8de4ab83" dependencies = [ "hash-db", - "hashbrown 0.12.0", + "hashbrown 0.12.1", "log", "rustc-hex", "smallvec", @@ -6168,55 +3044,6 @@ dependencies = [ "hash-db", ] -[[package]] -name = "trust-dns-proto" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0d7f5db438199a6e2609debe3f69f808d074e0a2888ee0bccb45fe234d03f4" -dependencies = [ - "async-trait", - "cfg-if 1.0.0", - "data-encoding", - "enum-as-inner", - "futures-channel", - "futures-io", - "futures-util", - "idna 0.2.3", - "ipnet", - "lazy_static", - "log", - "rand 0.8.5", - "smallvec", - "thiserror", - "tinyvec", - "url 2.2.2", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ad17b608a64bd0735e67bde16b0636f8aa8591f831a25d18443ed00a699770" -dependencies = [ - "cfg-if 1.0.0", - "futures-util", - "ipconfig", - "lazy_static", - "log", - "lru-cache", - "parking_lot 0.11.2", - "resolv-conf", - "smallvec", - "thiserror", - "trust-dns-proto", -] - -[[package]] -name = "try-lock" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" - [[package]] name = "tt-call" version = "1.0.8" @@ -6225,11 +3052,11 @@ checksum = "5e66dcbec4290c69dd03c57e76c2469ea5c7ce109c6dd4351c13055cf71ea055" [[package]] name = "twox-hash" -version = "1.6.2" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee73e6e4924fe940354b8d4d98cad5231175d615cd855b758adc658c0aac6a0" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "digest 0.10.3", "rand 0.8.5", "static_assertions", @@ -6237,21 +3064,15 @@ dependencies = [ [[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" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "uint" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6470ab50f482bde894a037a57064480a246dbfdd5960bd65a44824693f08da5f" +checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" dependencies = [ "byteorder", "crunchy", @@ -6260,100 +3081,25 @@ dependencies = [ ] [[package]] -name = "unicode-bidi" -version = "0.3.7" +name = "unicode-ident" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" +checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" [[package]] name = "unicode-normalization" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +checksum = "81dee68f85cab8cf68dec42158baf3a79a1cdc065a8b103025965d6ccb7f6cbd" 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-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "universal-hash" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" -dependencies = [ - "generic-array 0.14.4", - "subtle", -] - -[[package]] -name = "unsigned-varint" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fdeedbf205afadfe39ae559b75c3240f24e257d0ca27e85f85cb82aa19ac35" - -[[package]] -name = "unsigned-varint" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35581ff83d4101e58b582e607120c7f5ffb17e632a980b1f38334d76b36908b2" -dependencies = [ - "asynchronous-codec 0.5.0", - "bytes", - "futures-io", - "futures-util", -] - -[[package]] -name = "unsigned-varint" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86a8dc7f45e4c1b0d30e43038c38f274e77af056aa5f74b93c2cf9eb3c1c836" -dependencies = [ - "asynchronous-codec 0.6.0", - "bytes", - "futures-io", - "futures-util", -] - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "url" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" -dependencies = [ - "idna 0.1.5", - "matches", - "percent-encoding 1.0.1", -] - -[[package]] -name = "url" -version = "2.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" -dependencies = [ - "form_urlencoded", - "idna 0.2.3", - "matches", - "percent-encoding 2.1.0", -] +checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" [[package]] name = "valuable" @@ -6361,49 +3107,11 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" -[[package]] -name = "value-bag" -version = "1.0.0-alpha.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79923f7731dc61ebfba3633098bf3ac533bbd35ccd8c57e7088d9a5eebe0263f" -dependencies = [ - "ctor", - "version_check", -] - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" - -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - -[[package]] -name = "waker-fn" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" - -[[package]] -name = "want" -version = "0.3.0" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -dependencies = [ - "log", - "try-lock", -] +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasi" @@ -6411,12 +3119,6 @@ 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 = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -6425,19 +3127,19 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.78" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" +checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.78" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" +checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" dependencies = [ "bumpalo", "lazy_static", @@ -6448,23 +3150,11 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "wasm-bindgen-macro" -version = "0.2.78" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" +checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6472,9 +3162,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.78" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" +checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" dependencies = [ "proc-macro2", "quote", @@ -6485,33 +3175,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.78" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" - -[[package]] -name = "wasm-instrument" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "962e5b0401bbb6c887f54e69b8c496ea36f704df65db73e81fd5ff8dc3e63a9f" -dependencies = [ - "parity-wasm", -] - -[[package]] -name = "wasm-timer" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" -dependencies = [ - "futures 0.3.21", - "js-sys", - "parking_lot 0.11.2", - "pin-utils", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] +checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" [[package]] name = "wasmi" @@ -6537,80 +3203,6 @@ dependencies = [ "parity-wasm", ] -[[package]] -name = "web-sys" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" -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" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" -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 0.21.4", -] - -[[package]] -name = "webpki-roots" -version = "0.22.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "552ceb903e957524388c4d3475725ff2c8b7960922063af6ce53c9a43da07449" -dependencies = [ - "webpki 0.22.0", -] - -[[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 = "4.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea187a8ef279bc014ec368c27a920da2024d2a711109bfbe3440585d5cf27ad9" -dependencies = [ - "either", - "lazy_static", - "libc", -] - -[[package]] -name = "widestring" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" - [[package]] name = "winapi" version = "0.3.9" @@ -6627,15 +3219,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" @@ -6644,9 +3227,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ "windows_aarch64_msvc", "windows_i686_gnu", @@ -6657,42 +3240,33 @@ dependencies = [ [[package]] name = "windows_aarch64_msvc" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" [[package]] name = "windows_i686_gnu" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" [[package]] name = "windows_i686_msvc" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" [[package]] name = "windows_x86_64_gnu" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" [[package]] name = "windows_x86_64_msvc" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" - -[[package]] -name = "winreg" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" -dependencies = [ - "winapi", -] +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" [[package]] name = "wyz" @@ -6703,77 +3277,23 @@ dependencies = [ "tap", ] -[[package]] -name = "x25519-dalek" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" -dependencies = [ - "curve25519-dalek 3.2.0", - "rand_core 0.5.1", - "zeroize", -] - -[[package]] -name = "yamux" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7d9028f208dd5e63c614be69f115c1b53cacc1111437d4c765185856666c107" -dependencies = [ - "futures 0.3.21", - "log", - "nohash-hasher", - "parking_lot 0.11.2", - "rand 0.8.5", - "static_assertions", -] - [[package]] name = "zeroize" -version = "1.4.3" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619" +checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.2.2" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65f1a51723ec88c66d5d1fe80c841f17f63587d6691901d66be9bec6c3b51f73" +checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" dependencies = [ "proc-macro2", "quote", "syn", "synstructure", ] - -[[package]] -name = "zstd" -version = "0.9.2+zstd.1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2390ea1bf6c038c39674f22d95f0564725fc06034a47129179810b2fc58caa54" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "4.1.3+zstd.1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e99d81b99fb3c2c2c794e3fe56c305c63d5173a16a46b5850b07c935ffc7db79" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "1.6.2+zstd.1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2daf2f248d9ea44454bfcb2516534e8b8ad2fc91bf818a1885495fc42bc8ac9f" -dependencies = [ - "cc", - "libc", -] diff --git a/Cargo.toml b/Cargo.toml index d57157f3a..8f69798e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ resolver = "2" members = [ + "bin/runtime-common", "modules/*", "primitives/*", - "relays/*", ] diff --git a/bin/runtime-common/Cargo.toml b/bin/runtime-common/Cargo.toml index abd84364c..2e46a84ae 100644 --- a/bin/runtime-common/Cargo.toml +++ b/bin/runtime-common/Cargo.toml @@ -12,7 +12,6 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = ed25519-dalek = { version = "1.0", default-features = false, optional = true } hash-db = { version = "0.15.2", default-features = false } scale-info = { version = "2.0.1", default-features = false, features = ["derive"] } -static_assertions = { version = "1.1", optional = true } # Bridge dependencies @@ -67,6 +66,3 @@ runtime-benchmarks = [ "sp-state-machine", "sp-version", ] -integrity-test = [ - "static_assertions", -] diff --git a/bin/runtime-common/src/integrity.rs b/bin/runtime-common/src/integrity.rs deleted file mode 100644 index ab517566a..000000000 --- a/bin/runtime-common/src/integrity.rs +++ /dev/null @@ -1,331 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Integrity tests for chain constants and pallets configuration. -//! -//! Most of the tests in this module assume that the bridge is using standard (see `crate::messages` -//! module for details) configuration. - -use crate::messages::MessageBridge; - -use bp_messages::MessageNonce; -use bp_runtime::{Chain, ChainId}; -use codec::Encode; -use frame_support::{storage::generator::StorageValue, traits::Get}; -use frame_system::limits; - -/// Macro that ensures that the runtime configuration and chain primitives crate are sharing -/// the same types (index, block number, hash, hasher, account id and header). -#[macro_export] -macro_rules! assert_chain_types( - ( runtime: $r:path, this_chain: $this:path ) => { - { - // if one of asserts fail, then either bridge isn't configured properly (or alternatively - non-standard - // configuration is used), or something has broke existing configuration (meaning that all bridged chains - // and relays will stop functioning) - use frame_system::Config as SystemConfig; - use static_assertions::assert_type_eq_all; - - assert_type_eq_all!(<$r as SystemConfig>::Index, bp_runtime::IndexOf<$this>); - assert_type_eq_all!(<$r as SystemConfig>::BlockNumber, bp_runtime::BlockNumberOf<$this>); - assert_type_eq_all!(<$r as SystemConfig>::Hash, bp_runtime::HashOf<$this>); - assert_type_eq_all!(<$r as SystemConfig>::Hashing, bp_runtime::HasherOf<$this>); - assert_type_eq_all!(<$r as SystemConfig>::AccountId, bp_runtime::AccountIdOf<$this>); - assert_type_eq_all!(<$r as SystemConfig>::Header, bp_runtime::HeaderOf<$this>); - } - } -); - -/// Macro that ensures that the bridge configuration and chain primitives crates are sharing -/// the same types (hash, account id, ...). -#[macro_export] -macro_rules! assert_bridge_types( - ( bridge: $bridge:path, this_chain: $this:path, bridged_chain: $bridged:path ) => { - { - // if one of this asserts fail, then all chains, bridged with this chain and bridge relays are now broken - // - // `frame_support::weights::Weight` is used here directly, because all chains we know are using this - // primitive (may be changed in the future) - use $crate::messages::{ - AccountIdOf, BalanceOf, BridgedChain, HashOf, SignatureOf, SignerOf, ThisChain, WeightOf, - }; - use static_assertions::assert_type_eq_all; - - assert_type_eq_all!(HashOf>, bp_runtime::HashOf<$this>); - assert_type_eq_all!(AccountIdOf>, bp_runtime::AccountIdOf<$this>); - assert_type_eq_all!(SignerOf>, bp_runtime::AccountPublicOf<$this>); - assert_type_eq_all!(SignatureOf>, bp_runtime::SignatureOf<$this>); - assert_type_eq_all!(WeightOf>, frame_support::weights::Weight); - assert_type_eq_all!(BalanceOf>, bp_runtime::BalanceOf<$this>); - - assert_type_eq_all!(HashOf>, bp_runtime::HashOf<$bridged>); - assert_type_eq_all!(AccountIdOf>, bp_runtime::AccountIdOf<$bridged>); - assert_type_eq_all!(SignerOf>, bp_runtime::AccountPublicOf<$bridged>); - assert_type_eq_all!(SignatureOf>, bp_runtime::SignatureOf<$bridged>); - assert_type_eq_all!(WeightOf>, frame_support::weights::Weight); - assert_type_eq_all!(BalanceOf>, bp_runtime::BalanceOf<$bridged>); - } - } -); - -/// Macro that ensures that the bridge GRANDPA pallet is configured properly to bridge with given -/// chain. -#[macro_export] -macro_rules! assert_bridge_grandpa_pallet_types( - ( runtime: $r:path, with_bridged_chain_grandpa_instance: $i:path, bridged_chain: $bridged:path ) => { - { - // if one of asserts fail, then either bridge isn't configured properly (or alternatively - non-standard - // configuration is used), or something has broke existing configuration (meaning that all bridged chains - // and relays will stop functioning) - use pallet_bridge_grandpa::Config as GrandpaConfig; - use static_assertions::assert_type_eq_all; - - assert_type_eq_all!(<$r as GrandpaConfig<$i>>::BridgedChain, $bridged); - } - } -); - -/// Macro that ensures that the bridge messages pallet is configured properly to bridge using given -/// configuration. -#[macro_export] -macro_rules! assert_bridge_messages_pallet_types( - ( - runtime: $r:path, - with_bridged_chain_messages_instance: $i:path, - bridge: $bridge:path, - this_chain_account_id_converter: $this_converter:path - ) => { - { - // if one of asserts fail, then either bridge isn't configured properly (or alternatively - non-standard - // configuration is used), or something has broke existing configuration (meaning that all bridged chains - // and relays will stop functioning) - use $crate::messages::{ - source::FromThisChainMessagePayload, - target::FromBridgedChainMessagePayload, - AccountIdOf, BalanceOf, BridgedChain, ThisChain, WeightOf, - }; - use pallet_bridge_messages::Config as MessagesConfig; - use static_assertions::assert_type_eq_all; - - assert_type_eq_all!(<$r as MessagesConfig<$i>>::OutboundPayload, FromThisChainMessagePayload<$bridge>); - assert_type_eq_all!(<$r as MessagesConfig<$i>>::OutboundMessageFee, BalanceOf>); - - assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundPayload, FromBridgedChainMessagePayload<$bridge>); - assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundMessageFee, BalanceOf>); - assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundRelayer, AccountIdOf>); - - assert_type_eq_all!(<$r as MessagesConfig<$i>>::AccountIdConverter, $this_converter); - - assert_type_eq_all!(<$r as MessagesConfig<$i>>::TargetHeaderChain, BridgedChain<$bridge>); - assert_type_eq_all!(<$r as MessagesConfig<$i>>::SourceHeaderChain, BridgedChain<$bridge>); - } - } -); - -/// Macro that combines four other macro calls - `assert_chain_types`, `assert_bridge_types`, -/// `assert_bridge_grandpa_pallet_types` and `assert_bridge_messages_pallet_types`. It may be used -/// at the chain that is implemeting complete standard messages bridge (i.e. with bridge GRANDPA and -/// messages pallets deployed). -#[macro_export] -macro_rules! assert_complete_bridge_types( - ( - runtime: $r:path, - with_bridged_chain_grandpa_instance: $gi:path, - with_bridged_chain_messages_instance: $mi:path, - bridge: $bridge:path, - this_chain: $this:path, - bridged_chain: $bridged:path, - this_chain_account_id_converter: $this_converter:path - ) => { - $crate::assert_chain_types!(runtime: $r, this_chain: $this); - $crate::assert_bridge_types!(bridge: $bridge, this_chain: $this, bridged_chain: $bridged); - $crate::assert_bridge_grandpa_pallet_types!( - runtime: $r, - with_bridged_chain_grandpa_instance: $gi, - bridged_chain: $bridged - ); - $crate::assert_bridge_messages_pallet_types!( - runtime: $r, - with_bridged_chain_messages_instance: $mi, - bridge: $bridge, - this_chain_account_id_converter: $this_converter - ); - } -); - -/// Parameters for asserting chain-related constants. -#[derive(Debug)] -pub struct AssertChainConstants { - /// Block length limits of the chain. - pub block_length: limits::BlockLength, - /// Block weight limits of the chain. - pub block_weights: limits::BlockWeights, -} - -/// Test that our hardcoded, chain-related constants, are matching chain runtime configuration. -/// -/// In particular, this test ensures that: -/// -/// 1) block weight limits are matching; -/// 2) block size limits are matching. -pub fn assert_chain_constants(params: AssertChainConstants) -where - R: frame_system::Config, - C: Chain, -{ - // we don't check runtime version here, because in our case we'll be building relay from one - // repo and runtime will live in another repo, along with outdated relay version. To avoid - // unneeded commits, let's not raise an error in case of version mismatch. - - // if one of following assert fails, it means that we may need to upgrade bridged chain and - // relay to use updated constants. If constants are now smaller than before, it may lead to - // undeliverable messages. - - // `BlockLength` struct is not implementing `PartialEq`, so we compare encoded values here. - assert_eq!( - R::BlockLength::get().encode(), - params.block_length.encode(), - "BlockLength from runtime ({:?}) differ from hardcoded: {:?}", - R::BlockLength::get(), - params.block_length, - ); - // `BlockWeights` struct is not implementing `PartialEq`, so we compare encoded values here - assert_eq!( - R::BlockWeights::get().encode(), - params.block_weights.encode(), - "BlockWeights from runtime ({:?}) differ from hardcoded: {:?}", - R::BlockWeights::get(), - params.block_weights, - ); -} - -/// Test that the constants, used in GRANDPA pallet configuration are valid. -pub fn assert_bridge_grandpa_pallet_constants() -where - R: pallet_bridge_grandpa::Config, - GI: 'static, -{ - assert!( - R::MaxRequests::get() > 0, - "MaxRequests ({}) must be larger than zero", - R::MaxRequests::get(), - ); -} - -/// Parameters for asserting messages pallet constants. -#[derive(Debug)] -pub struct AssertBridgeMessagesPalletConstants { - /// Maximal number of unrewarded relayer entries in a confirmation transaction at the bridged - /// chain. - pub max_unrewarded_relayers_in_bridged_confirmation_tx: MessageNonce, - /// Maximal number of unconfirmed messages in a confirmation transaction at the bridged chain. - pub max_unconfirmed_messages_in_bridged_confirmation_tx: MessageNonce, - /// Identifier of the bridged chain. - pub bridged_chain_id: ChainId, -} - -/// Test that the constants, used in messages pallet configuration are valid. -pub fn assert_bridge_messages_pallet_constants(params: AssertBridgeMessagesPalletConstants) -where - R: pallet_bridge_messages::Config, - MI: 'static, -{ - assert!( - R::MaxMessagesToPruneAtOnce::get() > 0, - "MaxMessagesToPruneAtOnce ({}) must be larger than zero", - R::MaxMessagesToPruneAtOnce::get(), - ); - assert!( - R::MaxUnrewardedRelayerEntriesAtInboundLane::get() <= params.max_unrewarded_relayers_in_bridged_confirmation_tx, - "MaxUnrewardedRelayerEntriesAtInboundLane ({}) must be <= than the hardcoded value for bridged chain: {}", - R::MaxUnrewardedRelayerEntriesAtInboundLane::get(), - params.max_unrewarded_relayers_in_bridged_confirmation_tx, - ); - assert!( - R::MaxUnconfirmedMessagesAtInboundLane::get() <= params.max_unconfirmed_messages_in_bridged_confirmation_tx, - "MaxUnrewardedRelayerEntriesAtInboundLane ({}) must be <= than the hardcoded value for bridged chain: {}", - R::MaxUnconfirmedMessagesAtInboundLane::get(), - params.max_unconfirmed_messages_in_bridged_confirmation_tx, - ); - assert_eq!(R::BridgedChainId::get(), params.bridged_chain_id); -} - -/// Parameters for asserting bridge pallet names. -#[derive(Debug)] -pub struct AssertBridgePalletNames<'a> { - /// Name of the messages pallet, deployed at the bridged chain and used to bridge with this - /// chain. - pub with_this_chain_messages_pallet_name: &'a str, - /// Name of the GRANDPA pallet, deployed at this chain and used to bridge with the bridged - /// chain. - pub with_bridged_chain_grandpa_pallet_name: &'a str, - /// Name of the messages pallet, deployed at this chain and used to bridge with the bridged - /// chain. - pub with_bridged_chain_messages_pallet_name: &'a str, -} - -/// Tests that bridge pallet names used in `construct_runtime!()` macro call are matching constants -/// from chain primitives crates. -pub fn assert_bridge_pallet_names(params: AssertBridgePalletNames) -where - B: MessageBridge, - R: pallet_bridge_grandpa::Config + pallet_bridge_messages::Config, - GI: 'static, - MI: 'static, -{ - assert_eq!(B::BRIDGED_MESSAGES_PALLET_NAME, params.with_this_chain_messages_pallet_name); - assert_eq!( - pallet_bridge_grandpa::PalletOwner::::storage_value_final_key().to_vec(), - bp_runtime::storage_value_key(params.with_bridged_chain_grandpa_pallet_name, "PalletOwner",).0, - ); - assert_eq!( - pallet_bridge_messages::PalletOwner::::storage_value_final_key().to_vec(), - bp_runtime::storage_value_key( - params.with_bridged_chain_messages_pallet_name, - "PalletOwner", - ) - .0, - ); -} - -/// Parameters for asserting complete standard messages bridge. -#[derive(Debug)] -pub struct AssertCompleteBridgeConstants<'a> { - /// Parameters to assert this chain constants. - pub this_chain_constants: AssertChainConstants, - /// Parameters to assert messages pallet constants. - pub messages_pallet_constants: AssertBridgeMessagesPalletConstants, - /// Parameters to assert pallet names constants. - pub pallet_names: AssertBridgePalletNames<'a>, -} - -/// All bridge-related constants tests for the complete standard messages bridge (i.e. with bridge -/// GRANDPA and messages pallets deployed). -pub fn assert_complete_bridge_constants(params: AssertCompleteBridgeConstants) -where - R: frame_system::Config - + pallet_bridge_grandpa::Config - + pallet_bridge_messages::Config, - GI: 'static, - MI: 'static, - B: MessageBridge, - This: Chain, -{ - assert_chain_constants::(params.this_chain_constants); - assert_bridge_grandpa_pallet_constants::(); - assert_bridge_messages_pallet_constants::(params.messages_pallet_constants); - assert_bridge_pallet_names::(params.pallet_names); -} diff --git a/bin/runtime-common/src/lib.rs b/bin/runtime-common/src/lib.rs index c7fb98aba..ae7efb4a4 100644 --- a/bin/runtime-common/src/lib.rs +++ b/bin/runtime-common/src/lib.rs @@ -19,8 +19,4 @@ #![cfg_attr(not(feature = "std"), no_std)] pub mod messages; -pub mod messages_api; pub mod messages_benchmarking; - -#[cfg(feature = "integrity-test")] -pub mod integrity; diff --git a/bin/runtime-common/src/messages.rs b/bin/runtime-common/src/messages.rs index 51704c6f5..6be8fc6e8 100644 --- a/bin/runtime-common/src/messages.rs +++ b/bin/runtime-common/src/messages.rs @@ -33,7 +33,7 @@ use bp_runtime::{ use codec::{Decode, DecodeLimit, Encode}; use frame_support::{ traits::{Currency, ExistenceRequirement}, - weights::{Weight, WeightToFeePolynomial}, + weights::{Weight, WeightToFee}, RuntimeDebug, }; use hash_db::Hasher; @@ -595,7 +595,8 @@ pub mod target { message_id, message.data.payload.map_err(drop), |dispatch_origin, dispatch_weight| { - let unadjusted_weight_fee = ThisRuntime::WeightToFee::calc(&dispatch_weight); + let unadjusted_weight_fee = + ThisRuntime::WeightToFee::weight_to_fee(&dispatch_weight); let fee_multiplier = pallet_transaction_payment::Pallet::::next_fee_multiplier(); let adjusted_weight_fee = diff --git a/bin/runtime-common/src/messages_api.rs b/bin/runtime-common/src/messages_api.rs deleted file mode 100644 index b09a88e62..000000000 --- a/bin/runtime-common/src/messages_api.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Helpers for implementing various message-related runtime API mthods. - -use crate::messages::{source::FromThisChainMessagePayload, MessageBridge}; - -use bp_messages::{LaneId, MessageDetails, MessageNonce}; -use codec::Decode; -use sp_std::vec::Vec; - -/// Implementation of the `To*OutboundLaneApi::message_details`. -pub fn outbound_message_details( - lane: LaneId, - begin: MessageNonce, - end: MessageNonce, -) -> Vec> -where - Runtime: pallet_bridge_messages::Config, - MessagesPalletInstance: 'static, - BridgeConfig: MessageBridge, -{ - (begin..=end) - .filter_map(|nonce| { - let message_data = - pallet_bridge_messages::Pallet::::outbound_message_data(lane, nonce)?; - let decoded_payload = - FromThisChainMessagePayload::::decode(&mut &message_data.payload[..]).ok()?; - Some(MessageDetails { - nonce, - dispatch_weight: decoded_payload.weight, - size: message_data.payload.len() as _, - delivery_and_dispatch_fee: message_data.fee, - dispatch_fee_payment: decoded_payload.dispatch_fee_payment, - }) - }) - .collect() -} diff --git a/modules/fee-market/src/lib.rs b/modules/fee-market/src/lib.rs index 310570917..1364621d4 100644 --- a/modules/fee-market/src/lib.rs +++ b/modules/fee-market/src/lib.rs @@ -38,7 +38,7 @@ use frame_support::{ ensure, pallet_prelude::*, traits::{Currency, Get, LockIdentifier, LockableCurrency, WithdrawReasons}, - transactional, PalletId, + PalletId, }; use frame_system::{ensure_signed, pallet_prelude::*}; use sp_runtime::{ @@ -209,7 +209,6 @@ pub mod pallet { /// the default value is MinimumRelayFee in runtime. (Update market needed) /// Note: One account can enroll only once. #[pallet::weight(>::WeightInfo::enroll_and_lock_collateral())] - #[transactional] pub fn enroll_and_lock_collateral( origin: OriginFor, lock_collateral: BalanceOf, @@ -255,7 +254,6 @@ pub mod pallet { /// Update locked collateral for enrolled relayer, only supporting lock more. (Update market /// needed) #[pallet::weight(>::WeightInfo::update_locked_collateral())] - #[transactional] pub fn update_locked_collateral( origin: OriginFor, new_collateral: BalanceOf, @@ -308,7 +306,6 @@ pub mod pallet { /// Update relay fee for enrolled relayer. (Update market needed) #[pallet::weight(>::WeightInfo::update_relay_fee())] - #[transactional] pub fn update_relay_fee(origin: OriginFor, new_fee: BalanceOf) -> DispatchResult { let who = ensure_signed(origin)?; ensure!(Self::is_enrolled(&who), >::NotEnrolled); @@ -329,7 +326,6 @@ pub mod pallet { /// Cancel enrolled relayer(Update market needed) #[pallet::weight(>::WeightInfo::cancel_enrollment())] - #[transactional] pub fn cancel_enrollment(origin: OriginFor) -> DispatchResult { let who = ensure_signed(origin)?; ensure!(Self::is_enrolled(&who), >::NotEnrolled); @@ -357,7 +353,6 @@ pub mod pallet { } #[pallet::weight(>::WeightInfo::set_slash_protect())] - #[transactional] pub fn set_slash_protect( origin: OriginFor, slash_protect: BalanceOf, @@ -369,7 +364,6 @@ pub mod pallet { } #[pallet::weight(>::WeightInfo::set_assigned_relayers_number())] - #[transactional] pub fn set_assigned_relayers_number(origin: OriginFor, number: u32) -> DispatchResult { ensure_root(origin)?; diff --git a/modules/fee-market/src/s2s/payment.rs b/modules/fee-market/src/s2s/payment.rs index 6155e109f..efc375c04 100644 --- a/modules/fee-market/src/s2s/payment.rs +++ b/modules/fee-market/src/s2s/payment.rs @@ -112,7 +112,7 @@ where // Pay treasury_sum reward do_reward::( relayer_fund_account, - &T::TreasuryPalletId::get().into_account(), + &T::TreasuryPalletId::get().into_account_truncating(), treasury_sum, ); } diff --git a/modules/fee-market/src/tests.rs b/modules/fee-market/src/tests.rs index a9f55b666..c46d9d4e7 100644 --- a/modules/fee-market/src/tests.rs +++ b/modules/fee-market/src/tests.rs @@ -311,7 +311,8 @@ impl MessageDeliveryAndDispatchPayment frame_support::storage::unhashed::put(&key, &true); } - let treasury_account: AccountId = ::TreasuryPalletId::get().into_account(); + let treasury_account: AccountId = + ::TreasuryPalletId::get().into_account_truncating(); let treasury_key = (b":relayer-reward:", &treasury_account, treasury_sum).encode(); frame_support::storage::unhashed::put(&treasury_key, &true); } @@ -778,7 +779,7 @@ fn test_callback_no_order_created_when_fee_market_not_ready() { Messages::send_message(Origin::signed(1), TEST_LANE_ID, REGULAR_PAYLOAD, 200), DispatchError::Module(ModuleError { index: 4, - error: 2, + error: [2, 0, 0, 0], message: Some("MessageRejectedByLaneVerifier") }) ); @@ -840,7 +841,7 @@ fn test_payment_cal_reward_normally_single_message() { // 2. message relayer -> id: 100, reward = 40% * 30 * 80% = 9.6 ~ 10 // 3. confirm relayer -> id: 5, reward = 40% * 30 * 20% = 2.4 ~ 2 // 4. treasury reward -> reward = 100 - 30 = 70 - let t: AccountId = ::TreasuryPalletId::get().into_account(); + let t: AccountId = ::TreasuryPalletId::get().into_account_truncating(); assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(t, 70)); assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(1, 18)); assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(5, 2)); @@ -896,7 +897,7 @@ fn test_payment_cal_reward_normally_multi_message() { }, )); - let t: AccountId = ::TreasuryPalletId::get().into_account(); + let t: AccountId = ::TreasuryPalletId::get().into_account_truncating(); assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(t, 140)); assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(1, 4)); assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(5, 36)); @@ -951,7 +952,7 @@ fn test_payment_cal_reward_with_duplicated_delivery_proof() { }, )); - let t: AccountId = ::TreasuryPalletId::get().into_account(); + let t: AccountId = ::TreasuryPalletId::get().into_account_truncating(); assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(t, 70)); assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(1, 18)); assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(5, 2)); @@ -1205,7 +1206,7 @@ fn test_fee_verification_when_send_message() { Messages::send_message(Origin::signed(1), TEST_LANE_ID, REGULAR_PAYLOAD, 200), DispatchError::Module(ModuleError { index: 4, - error: 2, + error: [2, 0, 0, 0], message: Some("MessageRejectedByLaneVerifier") }) ); @@ -1216,7 +1217,7 @@ fn test_fee_verification_when_send_message() { Messages::send_message(Origin::signed(1), TEST_LANE_ID, REGULAR_PAYLOAD, 49), DispatchError::Module(ModuleError { index: 4, - error: 2, + error: [2, 0, 0, 0], message: Some("MessageRejectedByLaneVerifier") }) ); diff --git a/modules/grandpa/Cargo.toml b/modules/grandpa/Cargo.toml index eac80375d..335a86343 100644 --- a/modules/grandpa/Cargo.toml +++ b/modules/grandpa/Cargo.toml @@ -9,7 +9,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0" [dependencies] codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } -finality-grandpa = { version = "0.15.0", default-features = false } +finality-grandpa = { version = "0.16.0", default-features = false } log = { version = "0.4.14", default-features = false } num-traits = { version = "0.2", default-features = false } scale-info = { version = "2.0.1", default-features = false, features = ["derive"] } diff --git a/primitives/chain-crab-parachain/Cargo.toml b/primitives/chain-crab-parachain/Cargo.toml new file mode 100644 index 000000000..4c42b887b --- /dev/null +++ b/primitives/chain-crab-parachain/Cargo.toml @@ -0,0 +1,34 @@ +[package] +authors = ["Darwinia Network "] +description = "Primitives of Crab Parachain runtime." +edition = "2021" +license = "GPL-3.0" +name = "bp-crab-parachain" +version = "0.1.0" + +[dependencies] +# darwinia-network +bp-darwinia-core = { default-features = false, path = "../darwinia-core" } +# paritytech +bp-messages = { default-features = false, path = "../messages" } +bp-runtime = { default-features = false, path = "../runtime" } +frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-version = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } + +[features] +default = ["std"] +std = [ + # darwinia-network + "bp-darwinia-core/std", + # paritytech + "bp-messages/std", + "bp-runtime/std", + "frame-support/std", + "sp-api/std", + "sp-runtime/std", + "sp-std/std", + "sp-version/std", +] diff --git a/primitives/chain-crab-parachain/src/lib.rs b/primitives/chain-crab-parachain/src/lib.rs new file mode 100644 index 000000000..2d4705058 --- /dev/null +++ b/primitives/chain-crab-parachain/src/lib.rs @@ -0,0 +1,32 @@ +// This file is part of Darwinia. +// +// Copyright (C) 2018-2022 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia 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. +// +// Darwinia 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 Darwinia. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] + +mod copy_paste_from_darwinia { + // --- darwinia-network --- + use bp_darwinia_core::*; + + pub const EXISTENTIAL_DEPOSIT: Balance = 0; +} +pub use copy_paste_from_darwinia::*; + +pub use bp_darwinia_core::*; + +/// CrabParachain Chain. +pub type CrabParachain = DarwiniaLike; diff --git a/primitives/chain-crab/Cargo.toml b/primitives/chain-crab/Cargo.toml new file mode 100644 index 000000000..b77e3d900 --- /dev/null +++ b/primitives/chain-crab/Cargo.toml @@ -0,0 +1,34 @@ +[package] +authors = ["Darwinia Network "] +description = "Primitives of Crab runtime." +edition = "2021" +license = "GPL-3.0" +name = "bp-crab" +version = "0.1.0" + +[dependencies] +# darwinia-network +bp-darwinia-core = { default-features = false, path = "../darwinia-core" } +# paritytech +bp-messages = { default-features = false, path = "../messages" } +bp-runtime = { default-features = false, path = "../runtime" } +frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-version = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } + +[features] +default = ["std"] +std = [ + # darwinia-network + "bp-darwinia-core/std", + # paritytech + "bp-messages/std", + "bp-runtime/std", + "frame-support/std", + "sp-api/std", + "sp-runtime/std", + "sp-std/std", + "sp-version/std", +] diff --git a/primitives/chain-crab/src/lib.rs b/primitives/chain-crab/src/lib.rs new file mode 100644 index 000000000..c575a3964 --- /dev/null +++ b/primitives/chain-crab/src/lib.rs @@ -0,0 +1,34 @@ +// This file is part of Darwinia. +// +// Copyright (C) 2018-2022 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia 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. +// +// Darwinia 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 Darwinia. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] + +mod copy_paste_from_darwinia { + // --- darwinia-network --- + use bp_darwinia_core::*; + + pub const EXISTENTIAL_DEPOSIT: Balance = 0; + + pub const SESSION_LENGTH: BlockNumber = 1 * HOURS; +} +pub use copy_paste_from_darwinia::*; + +pub use bp_darwinia_core::*; + +/// Crab Chain. +pub type Crab = DarwiniaLike; diff --git a/primitives/chain-darwinia/Cargo.toml b/primitives/chain-darwinia/Cargo.toml new file mode 100644 index 000000000..ba03a604d --- /dev/null +++ b/primitives/chain-darwinia/Cargo.toml @@ -0,0 +1,34 @@ +[package] +authors = ["Darwinia Network "] +description = "Primitives of Darwinia runtime." +edition = "2021" +license = "GPL-3.0" +name = "bp-darwinia" +version = "0.1.0" + +[dependencies] +# darwinia-network +bp-darwinia-core = { default-features = false, path = "../darwinia-core" } +# paritytech +bp-messages = { default-features = false, path = "../messages" } +bp-runtime = { default-features = false, path = "../runtime" } +frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-version = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } + +[features] +default = ["std"] +std = [ + # darwinia-network + "bp-darwinia-core/std", + # paritytech + "bp-messages/std", + "bp-runtime/std", + "frame-support/std", + "sp-api/std", + "sp-runtime/std", + "sp-std/std", + "sp-version/std", +] diff --git a/primitives/chain-darwinia/src/lib.rs b/primitives/chain-darwinia/src/lib.rs new file mode 100644 index 000000000..2ce266556 --- /dev/null +++ b/primitives/chain-darwinia/src/lib.rs @@ -0,0 +1,34 @@ +// This file is part of Darwinia. +// +// Copyright (C) 2018-2022 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia 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. +// +// Darwinia 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 Darwinia. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] + +mod copy_paste_from_darwinia { + // --- darwinia-network --- + use bp_darwinia_core::*; + + pub const EXISTENTIAL_DEPOSIT: Balance = 100 * MICRO; + + pub const SESSION_LENGTH: BlockNumber = 4 * HOURS; +} +pub use copy_paste_from_darwinia::*; + +pub use bp_darwinia_core::*; + +/// Darwinia Chain. +pub type Darwinia = DarwiniaLike; diff --git a/primitives/chain-kusama/Cargo.toml b/primitives/chain-kusama/Cargo.toml index a676b565c..456f0fb98 100644 --- a/primitives/chain-kusama/Cargo.toml +++ b/primitives/chain-kusama/Cargo.toml @@ -11,17 +11,17 @@ smallvec = "1.7" # Bridge Dependencies -bp-messages = { path = "../messages", default-features = false } -bp-polkadot-core = { path = "../polkadot-core", default-features = false } -bp-runtime = { path = "../runtime", default-features = false } +bp-messages = { default-features = false, path = "../messages" } +bp-polkadot-core = { default-features = false, path = "../polkadot-core" } +bp-runtime = { default-features = false, path = "../runtime" } # Substrate Based Dependencies -frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } -sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } -sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-version = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } [features] default = ["std"] diff --git a/primitives/chain-kusama/src/lib.rs b/primitives/chain-kusama/src/lib.rs index d362fd164..e22c7fcea 100644 --- a/primitives/chain-kusama/src/lib.rs +++ b/primitives/chain-kusama/src/lib.rs @@ -18,60 +18,11 @@ // RuntimeApi generated functions #![allow(clippy::too_many_arguments)] -use bp_messages::{LaneId, MessageDetails, MessageNonce}; -use frame_support::weights::{ - WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, -}; -use sp_runtime::FixedU128; -use sp_std::prelude::*; -use sp_version::RuntimeVersion; - pub use bp_polkadot_core::*; /// Kusama Chain pub type Kusama = PolkadotLike; -// NOTE: This needs to be kept up to date with the Kusama runtime found in the Polkadot repo. -pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: sp_version::create_runtime_str!("kusama"), - impl_name: sp_version::create_runtime_str!("parity-kusama"), - authoring_version: 2, - spec_version: 9180, - impl_version: 0, - apis: sp_version::create_apis_vec![[]], - transaction_version: 11, - state_version: 0, -}; - -// NOTE: This needs to be kept up to date with the Kusama runtime found in the Polkadot repo. -pub struct WeightToFee; -impl WeightToFeePolynomial for WeightToFee { - type Balance = Balance; - - fn polynomial() -> WeightToFeeCoefficients { - const CENTS: Balance = 1_000_000_000_000 / 30_000; - // in Kusama, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT: - let p = CENTS; - let q = 10 * Balance::from(ExtrinsicBaseWeight::get()); - smallvec::smallvec![WeightToFeeCoefficient { - degree: 1, - negative: false, - coeff_frac: Perbill::from_rational(p % q, q), - coeff_integer: p / q, - }] - } -} - -// We use this to get the account on Kusama (target) which is derived from Polkadot's (source) -// account. -pub fn derive_account_from_polkadot_id(id: bp_runtime::SourceAccount) -> AccountId { - let encoded_id = bp_runtime::derive_account_id(bp_runtime::POLKADOT_CHAIN_ID, id); - AccountIdConverter::convert(encoded_id) -} - -/// Per-byte fee for Kusama transactions. -pub const TRANSACTION_BYTE_FEE: Balance = 10 * 1_000_000_000_000 / 30_000 / 1_000; - /// Existential deposit on Kusama. pub const EXISTENTIAL_DEPOSIT: Balance = 1_000_000_000_000 / 30_000; @@ -81,69 +32,3 @@ pub const EXISTENTIAL_DEPOSIT: Balance = 1_000_000_000_000 / 30_000; /// Note that since this is a target sessions may change before/after this time depending on network /// conditions. pub const SESSION_LENGTH: BlockNumber = time_units::HOURS; - -/// Name of the With-Kusama GRANDPA pallet instance that is deployed at bridged chains. -pub const WITH_KUSAMA_GRANDPA_PALLET_NAME: &str = "BridgeKusamaGrandpa"; -/// Name of the With-Kusama messages pallet instance that is deployed at bridged chains. -pub const WITH_KUSAMA_MESSAGES_PALLET_NAME: &str = "BridgeKusamaMessages"; - -/// Name of the transaction payment pallet at the Kusama runtime. -pub const TRANSACTION_PAYMENT_PALLET_NAME: &str = "TransactionPayment"; - -/// Name of the DOT->KSM conversion rate stored in the Kusama runtime. -pub const POLKADOT_TO_KUSAMA_CONVERSION_RATE_PARAMETER_NAME: &str = - "PolkadotToKusamaConversionRate"; -/// Name of the Polkadot fee multiplier parameter, stored in the Polkadot runtime. -pub const POLKADOT_FEE_MULTIPLIER_PARAMETER_NAME: &str = "PolkadotFeeMultiplier"; - -/// Name of the `KusamaFinalityApi::best_finalized` runtime method. -pub const BEST_FINALIZED_KUSAMA_HEADER_METHOD: &str = "KusamaFinalityApi_best_finalized"; - -/// Name of the `ToKusamaOutboundLaneApi::estimate_message_delivery_and_dispatch_fee` runtime -/// method. -pub const TO_KUSAMA_ESTIMATE_MESSAGE_FEE_METHOD: &str = - "ToKusamaOutboundLaneApi_estimate_message_delivery_and_dispatch_fee"; -/// Name of the `ToKusamaOutboundLaneApi::message_details` runtime method. -pub const TO_KUSAMA_MESSAGE_DETAILS_METHOD: &str = "ToKusamaOutboundLaneApi_message_details"; - -sp_api::decl_runtime_apis! { - /// API for querying information about the finalized Kusama headers. - /// - /// This API is implemented by runtimes that are bridging with the Kusama chain, not the - /// Kusama runtime itself. - pub trait KusamaFinalityApi { - /// Returns number and hash of the best finalized header known to the bridge module. - fn best_finalized() -> (BlockNumber, Hash); - } - - /// Outbound message lane API for messages that are sent to Kusama chain. - /// - /// This API is implemented by runtimes that are sending messages to Kusama chain, not the - /// Kusama runtime itself. - pub trait ToKusamaOutboundLaneApi { - /// Estimate message delivery and dispatch fee that needs to be paid by the sender on - /// this chain. - /// - /// Returns `None` if message is too expensive to be sent to Kusama from this chain. - /// - /// Please keep in mind that this method returns the lowest message fee required for message - /// to be accepted to the lane. It may be good idea to pay a bit over this price to account - /// future exchange rate changes and guarantee that relayer would deliver your message - /// to the target chain. - fn estimate_message_delivery_and_dispatch_fee( - lane_id: LaneId, - payload: OutboundPayload, - kusama_to_this_conversion_rate: Option, - ) -> Option; - /// Returns dispatch weight, encoded payload size and delivery+dispatch fee of all - /// messages in given inclusive range. - /// - /// If some (or all) messages are missing from the storage, they'll also will - /// be missing from the resulting vector. The vector is ordered by the nonce. - fn message_details( - lane: LaneId, - begin: MessageNonce, - end: MessageNonce, - ) -> Vec>; - } -} diff --git a/primitives/chain-pangolin-parachain/src/lib.rs b/primitives/chain-pangolin-parachain/src/lib.rs index ec8b61017..5a9e6eca5 100644 --- a/primitives/chain-pangolin-parachain/src/lib.rs +++ b/primitives/chain-pangolin-parachain/src/lib.rs @@ -21,19 +21,6 @@ mod copy_paste_from_darwinia { // --- darwinia-network --- use bp_darwinia_core::*; - // --- paritytech --- - use sp_version::RuntimeVersion; - - pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: sp_runtime::create_runtime_str!("Pangolin Parachain"), - impl_name: sp_runtime::create_runtime_str!("Pangolin Parachain"), - authoring_version: 1, - spec_version: 3, - impl_version: 1, - apis: sp_version::create_apis_vec![[]], - transaction_version: 1, - state_version: 0, - }; pub const EXISTENTIAL_DEPOSIT: Balance = 0; } @@ -41,51 +28,5 @@ pub use copy_paste_from_darwinia::*; pub use bp_darwinia_core::*; -// --- paritytech --- -use bp_messages::{LaneId, MessageDetails, MessageNonce}; -use frame_support::Parameter; -use sp_std::prelude::*; - /// PangolinParachain Chain. pub type PangolinParachain = DarwiniaLike; - -/// Name of the With-PangolinParachain GRANDPA pallet instance that is deployed at bridged chains. -pub const WITH_PANGOLIN_PARACHAIN_GRANDPA_PALLET_NAME: &str = "BridgePangolinParachainGrandpa"; -/// Name of the With-PangolinParachain messages pallet instance that is deployed at bridged chains. -pub const WITH_PANGOLIN_PARACHAIN_MESSAGES_PALLET_NAME: &str = "BridgePangolinParachainMessages"; - -/// Name of the `PangolinParachainFinalityApi::best_finalized` runtime method. -pub const BEST_FINALIZED_PANGOLIN_PARACHAIN_HEADER_METHOD: &str = - "PangolinParachainFinalityApi_best_finalized"; - -/// Name of the `ToPangolinParachainOutboundLaneApi::message_details` runtime method. -pub const TO_PANGOLIN_PARACHAIN_MESSAGE_DETAILS_METHOD: &str = - "ToPangolinParachainOutboundLaneApi_message_details"; - -sp_api::decl_runtime_apis! { - /// API for querying information about the finalized PangolinParachain headers. - /// - /// This API is implemented by runtimes that are bridging with the PangolinParachain chain, not the - /// PangolinParachain runtime itself. - pub trait PangolinParachainFinalityApi { - /// Returns number and hash of the best finalized header known to the bridge module. - fn best_finalized() -> (BlockNumber, Hash); - } - - /// Outbound message lane API for messages that are sent to PangolinParachain chain. - /// - /// This API is implemented by runtimes that are sending messages to PangolinParachain chain, not the - /// PangolinParachain runtime itself. - pub trait ToPangolinParachainOutboundLaneApi { - /// Returns dispatch weight, encoded payload size and delivery+dispatch fee of all - /// messages in given inclusive range. - /// - /// If some (or all) messages are missing from the storage, they'll also will - /// be missing from the resulting vector. The vector is ordered by the nonce. - fn message_details( - lane: LaneId, - begin: MessageNonce, - end: MessageNonce, - ) -> Vec>; - } -} diff --git a/primitives/chain-pangolin/src/lib.rs b/primitives/chain-pangolin/src/lib.rs index a1f1b2cd9..0acb5aa46 100644 --- a/primitives/chain-pangolin/src/lib.rs +++ b/primitives/chain-pangolin/src/lib.rs @@ -21,20 +21,6 @@ mod copy_paste_from_darwinia { // --- darwinia-network --- use bp_darwinia_core::*; - // --- paritytech --- - use sp_version::RuntimeVersion; - - pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: sp_runtime::create_runtime_str!("Pangolin"), - impl_name: sp_runtime::create_runtime_str!("Pangolin"), - authoring_version: 0, - #[allow(clippy::inconsistent_digit_grouping)] - spec_version: 2_8_06_0, - impl_version: 0, - apis: sp_version::create_apis_vec![[]], - transaction_version: 0, - state_version: 0, - }; pub const EXISTENTIAL_DEPOSIT: Balance = 0; @@ -44,49 +30,5 @@ pub use copy_paste_from_darwinia::*; pub use bp_darwinia_core::*; -// --- paritytech --- -use bp_messages::{LaneId, MessageDetails, MessageNonce}; -use frame_support::Parameter; -use sp_std::prelude::*; - /// Pangolin Chain. pub type Pangolin = DarwiniaLike; - -/// Name of the With-Pangolin GRANDPA pallet instance that is deployed at bridged chains. -pub const WITH_PANGOLIN_GRANDPA_PALLET_NAME: &str = "BridgePangolinGrandpa"; -/// Name of the With-Pangolin messages pallet instance that is deployed at bridged chains. -pub const WITH_PANGOLIN_MESSAGES_PALLET_NAME: &str = "BridgePangolinMessages"; - -/// Name of the `PangolinFinalityApi::best_finalized` runtime method. -pub const BEST_FINALIZED_PANGOLIN_HEADER_METHOD: &str = "PangolinFinalityApi_best_finalized"; - -/// Name of the `ToPangolinOutboundLaneApi::message_details` runtime method. -pub const TO_PANGOLIN_MESSAGE_DETAILS_METHOD: &str = "ToPangolinOutboundLaneApi_message_details"; - -sp_api::decl_runtime_apis! { - /// API for querying information about the finalized Pangolin headers. - /// - /// This API is implemented by runtimes that are bridging with the Pangolin chain, not the - /// Pangolin runtime itself. - pub trait PangolinFinalityApi { - /// Returns number and hash of the best finalized header known to the bridge module. - fn best_finalized() -> (BlockNumber, Hash); - } - - /// Outbound message lane API for messages that are sent to Pangolin chain. - /// - /// This API is implemented by runtimes that are sending messages to Pangolin chain, not the - /// Pangolin runtime itself. - pub trait ToPangolinOutboundLaneApi { - /// Returns dispatch weight, encoded payload size and delivery+dispatch fee of all - /// messages in given inclusive range. - /// - /// If some (or all) messages are missing from the storage, they'll also will - /// be missing from the resulting vector. The vector is ordered by the nonce. - fn message_details( - lane: LaneId, - begin: MessageNonce, - end: MessageNonce, - ) -> Vec>; - } -} diff --git a/primitives/chain-pangoro/src/lib.rs b/primitives/chain-pangoro/src/lib.rs index a14ee3473..d8880f215 100644 --- a/primitives/chain-pangoro/src/lib.rs +++ b/primitives/chain-pangoro/src/lib.rs @@ -21,20 +21,6 @@ mod copy_paste_from_darwinia { // --- darwinia-network --- use bp_darwinia_core::*; - // --- paritytech --- - use sp_version::RuntimeVersion; - - pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: sp_runtime::create_runtime_str!("Pangoro"), - impl_name: sp_runtime::create_runtime_str!("Pangoro"), - authoring_version: 0, - #[allow(clippy::inconsistent_digit_grouping)] - spec_version: 2_8_06_0, - impl_version: 0, - apis: sp_version::create_apis_vec![[]], - transaction_version: 0, - state_version: 0, - }; pub const EXISTENTIAL_DEPOSIT: Balance = 0; @@ -44,49 +30,5 @@ pub use copy_paste_from_darwinia::*; pub use bp_darwinia_core::*; -// --- paritytech --- -use bp_messages::{LaneId, MessageDetails, MessageNonce}; -use frame_support::Parameter; -use sp_std::prelude::*; - /// Pangoro Chain. pub type Pangoro = DarwiniaLike; - -/// Name of the With-Pangoro GRANDPA pallet instance that is deployed at bridged chains. -pub const WITH_PANGORO_GRANDPA_PALLET_NAME: &str = "BridgePangoroGrandpa"; -/// Name of the With-Pangoro messages pallet instance that is deployed at bridged chains. -pub const WITH_PANGORO_MESSAGES_PALLET_NAME: &str = "BridgePangoroMessages"; - -/// Name of the `PangoroFinalityApi::best_finalized` runtime method. -pub const BEST_FINALIZED_PANGORO_HEADER_METHOD: &str = "PangoroFinalityApi_best_finalized"; - -/// Name of the `ToPangoroOutboundLaneApi::message_details` runtime method. -pub const TO_PANGORO_MESSAGE_DETAILS_METHOD: &str = "ToPangoroOutboundLaneApi_message_details"; - -sp_api::decl_runtime_apis! { - /// API for querying information about the finalized Pangoro headers. - /// - /// This API is implemented by runtimes that are bridging with the Pangoro chain, not the - /// Pangoro runtime itself. - pub trait PangoroFinalityApi { - /// Returns number and hash of the best finalized header known to the bridge module. - fn best_finalized() -> (BlockNumber, Hash); - } - - /// Outbound message lane API for messages that are sent to Pangoro chain. - /// - /// This API is implemented by runtimes that are sending messages to Pangoro chain, not the - /// Pangoro runtime itself. - pub trait ToPangoroOutboundLaneApi { - /// Returns dispatch weight, encoded payload size and delivery+dispatch fee of all - /// messages in given inclusive range. - /// - /// If some (or all) messages are missing from the storage, they'll also will - /// be missing from the resulting vector. The vector is ordered by the nonce. - fn message_details( - lane: LaneId, - begin: MessageNonce, - end: MessageNonce, - ) -> Vec>; - } -} diff --git a/primitives/chain-polkadot/src/lib.rs b/primitives/chain-polkadot/src/lib.rs index 7194eb090..bb12047c1 100644 --- a/primitives/chain-polkadot/src/lib.rs +++ b/primitives/chain-polkadot/src/lib.rs @@ -18,63 +18,11 @@ // RuntimeApi generated functions #![allow(clippy::too_many_arguments)] -use bp_messages::{LaneId, MessageDetails, MessageNonce}; -use frame_support::weights::{ - WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, -}; -use sp_runtime::FixedU128; -use sp_std::prelude::*; -use sp_version::RuntimeVersion; - pub use bp_polkadot_core::*; /// Polkadot Chain pub type Polkadot = PolkadotLike; -// NOTE: This needs to be kept up to date with the Polkadot runtime found in the Polkadot repo. -pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: sp_version::create_runtime_str!("polkadot"), - impl_name: sp_version::create_runtime_str!("parity-polkadot"), - authoring_version: 0, - spec_version: 9180, - impl_version: 0, - apis: sp_version::create_apis_vec![[]], - transaction_version: 12, - state_version: 0, -}; - -// NOTE: This needs to be kept up to date with the Polkadot runtime found in the Polkadot repo. -pub struct WeightToFee; -impl WeightToFeePolynomial for WeightToFee { - type Balance = Balance; - - fn polynomial() -> WeightToFeeCoefficients { - const CENTS: Balance = 10_000_000_000 / 100; - // in Polkadot, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT: - let p = CENTS; - let q = 10 * Balance::from(ExtrinsicBaseWeight::get()); - smallvec::smallvec![WeightToFeeCoefficient { - degree: 1, - negative: false, - coeff_frac: Perbill::from_rational(p % q, q), - coeff_integer: p / q, - }] - } -} - -// We use this to get the account on Polkadot (target) which is derived from Kusama's (source) -// account. -pub fn derive_account_from_kusama_id(id: bp_runtime::SourceAccount) -> AccountId { - let encoded_id = bp_runtime::derive_account_id(bp_runtime::KUSAMA_CHAIN_ID, id); - AccountIdConverter::convert(encoded_id) -} - -/// Per-byte fee for Polkadot transactions. -pub const TRANSACTION_BYTE_FEE: Balance = 10 * 10_000_000_000 / 100 / 1_000; - -/// Existential deposit on Polkadot. -pub const EXISTENTIAL_DEPOSIT: Balance = 10_000_000_000; - /// The target length of a session (how often authorities change) on Polkadot measured in of number /// of blocks. /// @@ -82,68 +30,5 @@ pub const EXISTENTIAL_DEPOSIT: Balance = 10_000_000_000; /// conditions. pub const SESSION_LENGTH: BlockNumber = 4 * time_units::HOURS; -/// Name of the With-Polkadot GRANDPA pallet instance that is deployed at bridged chains. -pub const WITH_POLKADOT_GRANDPA_PALLET_NAME: &str = "BridgePolkadotGrandpa"; -/// Name of the With-Polkadot messages pallet instance that is deployed at bridged chains. -pub const WITH_POLKADOT_MESSAGES_PALLET_NAME: &str = "BridgePolkadotMessages"; - -/// Name of the transaction payment pallet at the Polkadot runtime. -pub const TRANSACTION_PAYMENT_PALLET_NAME: &str = "TransactionPayment"; - -/// Name of the KSM->DOT conversion rate parameter, stored in the Polkadot runtime. -pub const KUSAMA_TO_POLKADOT_CONVERSION_RATE_PARAMETER_NAME: &str = - "KusamaToPolkadotConversionRate"; -/// Name of the Kusama fee multiplier parameter, stored in the Polkadot runtime. -pub const KUSAMA_FEE_MULTIPLIER_PARAMETER_NAME: &str = "KusamaFeeMultiplier"; - -/// Name of the `PolkadotFinalityApi::best_finalized` runtime method. -pub const BEST_FINALIZED_POLKADOT_HEADER_METHOD: &str = "PolkadotFinalityApi_best_finalized"; - -/// Name of the `ToPolkadotOutboundLaneApi::estimate_message_delivery_and_dispatch_fee` runtime -/// method. -pub const TO_POLKADOT_ESTIMATE_MESSAGE_FEE_METHOD: &str = - "ToPolkadotOutboundLaneApi_estimate_message_delivery_and_dispatch_fee"; -/// Name of the `ToPolkadotOutboundLaneApi::message_details` runtime method. -pub const TO_POLKADOT_MESSAGE_DETAILS_METHOD: &str = "ToPolkadotOutboundLaneApi_message_details"; - -sp_api::decl_runtime_apis! { - /// API for querying information about the finalized Polkadot headers. - /// - /// This API is implemented by runtimes that are bridging with the Polkadot chain, not the - /// Polkadot runtime itself. - pub trait PolkadotFinalityApi { - /// Returns number and hash of the best finalized header known to the bridge module. - fn best_finalized() -> (BlockNumber, Hash); - } - - /// Outbound message lane API for messages that are sent to Polkadot chain. - /// - /// This API is implemented by runtimes that are sending messages to Polkadot chain, not the - /// Polkadot runtime itself. - pub trait ToPolkadotOutboundLaneApi { - /// Estimate message delivery and dispatch fee that needs to be paid by the sender on - /// this chain. - /// - /// Returns `None` if message is too expensive to be sent to Polkadot from this chain. - /// - /// Please keep in mind that this method returns the lowest message fee required for message - /// to be accepted to the lane. It may be good idea to pay a bit over this price to account - /// future exchange rate changes and guarantee that relayer would deliver your message - /// to the target chain. - fn estimate_message_delivery_and_dispatch_fee( - lane_id: LaneId, - payload: OutboundPayload, - polkadot_to_this_conversion_rate: Option, - ) -> Option; - /// Returns dispatch weight, encoded payload size and delivery+dispatch fee of all - /// messages in given inclusive range. - /// - /// If some (or all) messages are missing from the storage, they'll also will - /// be missing from the resulting vector. The vector is ordered by the nonce. - fn message_details( - lane: LaneId, - begin: MessageNonce, - end: MessageNonce, - ) -> Vec>; - } -} +/// Existential deposit on Polkadot. +pub const EXISTENTIAL_DEPOSIT: Balance = 10_000_000_000; diff --git a/primitives/chain-rococo/src/lib.rs b/primitives/chain-rococo/src/lib.rs index a4108443b..c75f54d15 100644 --- a/primitives/chain-rococo/src/lib.rs +++ b/primitives/chain-rococo/src/lib.rs @@ -18,14 +18,6 @@ // RuntimeApi generated functions #![allow(clippy::too_many_arguments)] -use bp_messages::{LaneId, MessageDetails, MessageNonce}; -use frame_support::weights::{ - Weight, WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, -}; -use sp_runtime::FixedU128; -use sp_std::prelude::*; -use sp_version::RuntimeVersion; - pub use bp_polkadot_core::*; /// Rococo Chain @@ -38,108 +30,5 @@ pub type Rococo = PolkadotLike; /// conditions. pub const SESSION_LENGTH: BlockNumber = time_units::HOURS; -// NOTE: This needs to be kept up to date with the Rococo runtime found in the Polkadot repo. -pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: sp_version::create_runtime_str!("rococo"), - impl_name: sp_version::create_runtime_str!("parity-rococo-v2.0"), - authoring_version: 0, - spec_version: 9180, - impl_version: 0, - apis: sp_version::create_apis_vec![[]], - transaction_version: 0, - state_version: 0, -}; - -// NOTE: This needs to be kept up to date with the Rococo runtime found in the Polkadot repo. -pub struct WeightToFee; -impl WeightToFeePolynomial for WeightToFee { - type Balance = Balance; - - fn polynomial() -> WeightToFeeCoefficients { - const CENTS: Balance = 1_000_000_000_000 / 100; - let p = CENTS; - let q = 10 * Balance::from(ExtrinsicBaseWeight::get()); - smallvec::smallvec![WeightToFeeCoefficient { - degree: 1, - negative: false, - coeff_frac: Perbill::from_rational(p % q, q), - coeff_integer: p / q, - }] - } -} - -// We use this to get the account on Rococo (target) which is derived from Wococo's (source) -// account. -pub fn derive_account_from_wococo_id(id: bp_runtime::SourceAccount) -> AccountId { - let encoded_id = bp_runtime::derive_account_id(bp_runtime::WOCOCO_CHAIN_ID, id); - AccountIdConverter::convert(encoded_id) -} - -/// Name of the With-Rococo GRANDPA pallet instance that is deployed at bridged chains. -pub const WITH_ROCOCO_GRANDPA_PALLET_NAME: &str = "BridgeRococoGrandpa"; -/// Name of the With-Rococo messages pallet instance that is deployed at bridged chains. -pub const WITH_ROCOCO_MESSAGES_PALLET_NAME: &str = "BridgeRococoMessages"; - -/// Name of the `RococoFinalityApi::best_finalized` runtime method. -pub const BEST_FINALIZED_ROCOCO_HEADER_METHOD: &str = "RococoFinalityApi_best_finalized"; - -/// Name of the `ToRococoOutboundLaneApi::estimate_message_delivery_and_dispatch_fee` runtime -/// method. -pub const TO_ROCOCO_ESTIMATE_MESSAGE_FEE_METHOD: &str = - "ToRococoOutboundLaneApi_estimate_message_delivery_and_dispatch_fee"; -/// Name of the `ToRococoOutboundLaneApi::message_details` runtime method. -pub const TO_ROCOCO_MESSAGE_DETAILS_METHOD: &str = "ToRococoOutboundLaneApi_message_details"; - /// Existential deposit on Rococo. pub const EXISTENTIAL_DEPOSIT: Balance = 1_000_000_000_000 / 100; - -/// Weight of pay-dispatch-fee operation for inbound messages at Rococo chain. -/// -/// This value corresponds to the result of -/// `pallet_bridge_messages::WeightInfoExt::pay_inbound_dispatch_fee_overhead()` call for your -/// chain. Don't put too much reserve there, because it is used to **decrease** -/// `DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT` cost. So putting large reserve would make delivery -/// transactions cheaper. -pub const PAY_INBOUND_DISPATCH_FEE_WEIGHT: Weight = 600_000_000; - -sp_api::decl_runtime_apis! { - /// API for querying information about the finalized Rococo headers. - /// - /// This API is implemented by runtimes that are bridging with the Rococo chain, not the - /// Rococo runtime itself. - pub trait RococoFinalityApi { - /// Returns number and hash of the best finalized header known to the bridge module. - fn best_finalized() -> (BlockNumber, Hash); - } - - /// Outbound message lane API for messages that are sent to Rococo chain. - /// - /// This API is implemented by runtimes that are sending messages to Rococo chain, not the - /// Rococo runtime itself. - pub trait ToRococoOutboundLaneApi { - /// Estimate message delivery and dispatch fee that needs to be paid by the sender on - /// this chain. - /// - /// Returns `None` if message is too expensive to be sent to Rococo from this chain. - /// - /// Please keep in mind that this method returns the lowest message fee required for message - /// to be accepted to the lane. It may be good idea to pay a bit over this price to account - /// future exchange rate changes and guarantee that relayer would deliver your message - /// to the target chain. - fn estimate_message_delivery_and_dispatch_fee( - lane_id: LaneId, - payload: OutboundPayload, - rococo_to_this_conversion_rate: Option, - ) -> Option; - /// Returns dispatch weight, encoded payload size and delivery+dispatch fee of all - /// messages in given inclusive range. - /// - /// If some (or all) messages are missing from the storage, they'll also will - /// be missing from the resulting vector. The vector is ordered by the nonce. - fn message_details( - lane: LaneId, - begin: MessageNonce, - end: MessageNonce, - ) -> Vec>; - } -} diff --git a/primitives/chain-wococo/Cargo.toml b/primitives/chain-wococo/Cargo.toml deleted file mode 100644 index 633cdd15c..000000000 --- a/primitives/chain-wococo/Cargo.toml +++ /dev/null @@ -1,34 +0,0 @@ -[package] -name = "bp-wococo" -description = "Primitives of Wococo runtime." -version = "0.1.0" -authors = ["Parity Technologies "] -edition = "2021" -license = "GPL-3.0-or-later WITH Classpath-exception-2.0" - -[dependencies] -parity-scale-codec = { version = "3.0.0", default-features = false, features = ["derive"] } - -# Bridge Dependencies -bp-messages = { path = "../messages", default-features = false } -bp-polkadot-core = { path = "../polkadot-core", default-features = false } -bp-rococo = { path = "../chain-rococo", default-features = false } -bp-runtime = { path = "../runtime", default-features = false } - -# Substrate Based Dependencies -sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } - -[features] -default = ["std"] -std = [ - "bp-messages/std", - "bp-polkadot-core/std", - "bp-runtime/std", - "bp-rococo/std", - "parity-scale-codec/std", - "sp-api/std", - "sp-runtime/std", - "sp-std/std", -] diff --git a/primitives/chain-wococo/src/lib.rs b/primitives/chain-wococo/src/lib.rs deleted file mode 100644 index f39543114..000000000 --- a/primitives/chain-wococo/src/lib.rs +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -#![cfg_attr(not(feature = "std"), no_std)] -// RuntimeApi generated functions -#![allow(clippy::too_many_arguments)] - -use bp_messages::{LaneId, MessageDetails, MessageNonce}; -use sp_runtime::FixedU128; -use sp_std::prelude::*; - -pub use bp_polkadot_core::*; -// Rococo runtime = Wococo runtime -pub use bp_rococo::{WeightToFee, EXISTENTIAL_DEPOSIT, PAY_INBOUND_DISPATCH_FEE_WEIGHT, VERSION}; - -/// Wococo Chain -pub type Wococo = PolkadotLike; - -/// The target length of a session (how often authorities change) on Wococo measured in of number -/// of blocks. -/// -/// Note that since this is a target sessions may change before/after this time depending on network -/// conditions. -pub const SESSION_LENGTH: BlockNumber = time_units::MINUTES; - -// We use this to get the account on Wococo (target) which is derived from Rococo's (source) -// account. -pub fn derive_account_from_rococo_id(id: bp_runtime::SourceAccount) -> AccountId { - let encoded_id = bp_runtime::derive_account_id(bp_runtime::ROCOCO_CHAIN_ID, id); - AccountIdConverter::convert(encoded_id) -} - -/// Name of the With-Wococo GRANDPA pallet instance that is deployed at bridged chains. -pub const WITH_WOCOCO_GRANDPA_PALLET_NAME: &str = "BridgeWococoGrandpa"; -/// Name of the With-Wococo messages pallet instance that is deployed at bridged chains. -pub const WITH_WOCOCO_MESSAGES_PALLET_NAME: &str = "BridgeWococoMessages"; - -/// Name of the `WococoFinalityApi::best_finalized` runtime method. -pub const BEST_FINALIZED_WOCOCO_HEADER_METHOD: &str = "WococoFinalityApi_best_finalized"; - -/// Name of the `ToWococoOutboundLaneApi::estimate_message_delivery_and_dispatch_fee` runtime -/// method. -pub const TO_WOCOCO_ESTIMATE_MESSAGE_FEE_METHOD: &str = - "ToWococoOutboundLaneApi_estimate_message_delivery_and_dispatch_fee"; -/// Name of the `ToWococoOutboundLaneApi::message_details` runtime method. -pub const TO_WOCOCO_MESSAGE_DETAILS_METHOD: &str = "ToWococoOutboundLaneApi_message_details"; - -sp_api::decl_runtime_apis! { - /// API for querying information about the finalized Wococo headers. - /// - /// This API is implemented by runtimes that are bridging with the Wococo chain, not the - /// Wococo runtime itself. - pub trait WococoFinalityApi { - /// Returns number and hash of the best finalized header known to the bridge module. - fn best_finalized() -> (BlockNumber, Hash); - } - - /// Outbound message lane API for messages that are sent to Wococo chain. - /// - /// This API is implemented by runtimes that are sending messages to Wococo chain, not the - /// Wococo runtime itself. - pub trait ToWococoOutboundLaneApi { - /// Estimate message delivery and dispatch fee that needs to be paid by the sender on - /// this chain. - /// - /// Returns `None` if message is too expensive to be sent to Wococo from this chain. - /// - /// Please keep in mind that this method returns the lowest message fee required for message - /// to be accepted to the lane. It may be good idea to pay a bit over this price to account - /// future exchange rate changes and guarantee that relayer would deliver your message - /// to the target chain. - fn estimate_message_delivery_and_dispatch_fee( - lane_id: LaneId, - payload: OutboundPayload, - wococo_to_this_conversion_rate: Option, - ) -> Option; - /// Returns dispatch weight, encoded payload size and delivery+dispatch fee of all - /// messages in given inclusive range. - /// - /// If some (or all) messages are missing from the storage, they'll also will - /// be missing from the resulting vector. The vector is ordered by the nonce. - fn message_details( - lane: LaneId, - begin: MessageNonce, - end: MessageNonce, - ) -> Vec>; - } -} diff --git a/primitives/header-chain/Cargo.toml b/primitives/header-chain/Cargo.toml index 7cd688d0d..f01ba0c06 100644 --- a/primitives/header-chain/Cargo.toml +++ b/primitives/header-chain/Cargo.toml @@ -8,7 +8,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0" [dependencies] codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } -finality-grandpa = { version = "0.15.0", default-features = false } +finality-grandpa = { version = "0.16.0", default-features = false } scale-info = { version = "2.0.1", default-features = false, features = ["derive"] } serde = { version = "1.0", optional = true } diff --git a/primitives/test-utils/Cargo.toml b/primitives/test-utils/Cargo.toml index 6da5c7c0f..7760f4f82 100644 --- a/primitives/test-utils/Cargo.toml +++ b/primitives/test-utils/Cargo.toml @@ -9,7 +9,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0" bp-header-chain = { path = "../header-chain", default-features = false } codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } ed25519-dalek = { version = "1.0", default-features = false, features = ["u64_backend"] } -finality-grandpa = { version = "0.15.0", default-features = false } +finality-grandpa = { version = "0.16.0", default-features = false } sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } diff --git a/primitives/test-utils/src/lib.rs b/primitives/test-utils/src/lib.rs index 9e044ed47..38d9453c9 100644 --- a/primitives/test-utils/src/lib.rs +++ b/primitives/test-utils/src/lib.rs @@ -20,7 +20,6 @@ use bp_header_chain::justification::GrandpaJustification; use codec::Encode; -use sp_application_crypto::TryFrom; use sp_finality_grandpa::{AuthorityId, AuthoritySignature, AuthorityWeight, SetId}; use sp_runtime::traits::{Header as HeaderT, One, Zero}; use sp_std::prelude::*; diff --git a/relays/client-kusama/Cargo.toml b/relays/client-kusama/Cargo.toml deleted file mode 100644 index 35c24c108..000000000 --- a/relays/client-kusama/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "relay-kusama-client" -version = "0.1.0" -authors = ["Parity Technologies "] -edition = "2021" -license = "GPL-3.0-or-later WITH Classpath-exception-2.0" - -[dependencies] -codec = { package = "parity-scale-codec", version = "3.0.0" } -relay-substrate-client = { path = "../client-substrate" } -relay-utils = { path = "../utils" } -scale-info = { version = "2.0.1", features = ["derive"] } - -# Bridge dependencies - -bp-header-chain = { path = "../../primitives/header-chain" } -bp-kusama = { path = "../../primitives/chain-kusama" } -bp-message-dispatch = { path = "../../primitives/message-dispatch" } -bp-messages = { path = "../../primitives/messages" } -bp-polkadot = { path = "../../primitives/chain-polkadot" } -bp-polkadot-core = { path = "../../primitives/polkadot-core" } -bp-runtime = { path = "../../primitives/runtime" } -bridge-runtime-common = { path = "../../bin/runtime-common" } -pallet-bridge-dispatch = { path = "../../modules/dispatch" } - -# Substrate Dependencies - -frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/relays/client-kusama/src/lib.rs b/relays/client-kusama/src/lib.rs deleted file mode 100644 index 47da76924..000000000 --- a/relays/client-kusama/src/lib.rs +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Types used to connect to the Kusama chain. - -use bp_messages::MessageNonce; -use codec::Encode; -use frame_support::weights::Weight; -use relay_substrate_client::{ - Chain, ChainBase, ChainWithBalances, ChainWithGrandpa, ChainWithMessages, - Error as SubstrateError, SignParam, TransactionSignScheme, UnsignedTransaction, -}; -use sp_core::{storage::StorageKey, Pair}; -use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount}; -use std::time::Duration; - -pub mod runtime; - -/// Kusama header id. -pub type HeaderId = relay_utils::HeaderId; - -/// Kusama chain definition -#[derive(Debug, Clone, Copy)] -pub struct Kusama; - -impl ChainBase for Kusama { - type AccountId = bp_kusama::AccountId; - type Balance = bp_kusama::Balance; - type BlockNumber = bp_kusama::BlockNumber; - type Hash = bp_kusama::Hash; - type Hasher = bp_kusama::Hasher; - type Header = bp_kusama::Header; - type Index = bp_kusama::Nonce; - type Signature = bp_kusama::Signature; - - fn max_extrinsic_size() -> u32 { - bp_kusama::Kusama::max_extrinsic_size() - } - - fn max_extrinsic_weight() -> Weight { - bp_kusama::Kusama::max_extrinsic_weight() - } -} - -impl Chain for Kusama { - type Call = crate::runtime::Call; - type SignedBlock = bp_kusama::SignedBlock; - type WeightToFee = bp_kusama::WeightToFee; - - const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6); - const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = - bp_kusama::BEST_FINALIZED_KUSAMA_HEADER_METHOD; - const MAXIMAL_ENCODED_ACCOUNT_ID_SIZE: u32 = bp_kusama::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE; - const NAME: &'static str = "Kusama"; - const STORAGE_PROOF_OVERHEAD: u32 = bp_kusama::EXTRA_STORAGE_PROOF_SIZE; - const TOKEN_ID: Option<&'static str> = Some("kusama"); -} - -impl ChainWithGrandpa for Kusama { - const WITH_CHAIN_GRANDPA_PALLET_NAME: &'static str = bp_kusama::WITH_KUSAMA_GRANDPA_PALLET_NAME; -} - -impl ChainWithMessages for Kusama { - type WeightInfo = (); - - const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = - bp_kusama::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; - const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = - bp_kusama::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; - const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN: Weight = - bp_kusama::PAY_INBOUND_DISPATCH_FEE_WEIGHT; - const TO_CHAIN_MESSAGE_DETAILS_METHOD: &'static str = - bp_kusama::TO_KUSAMA_MESSAGE_DETAILS_METHOD; - const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = - bp_kusama::WITH_KUSAMA_MESSAGES_PALLET_NAME; -} - -impl ChainWithBalances for Kusama { - fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey { - StorageKey(bp_kusama::account_info_storage_key(account_id)) - } -} - -impl TransactionSignScheme for Kusama { - type AccountKeyPair = sp_core::sr25519::Pair; - type Chain = Kusama; - type SignedTransaction = crate::runtime::UncheckedExtrinsic; - - fn sign_transaction(param: SignParam) -> Result { - let raw_payload = SignedPayload::new( - param.unsigned.call.clone(), - bp_kusama::SignedExtensions::new( - param.spec_version, - param.transaction_version, - param.era, - param.genesis_hash, - param.unsigned.nonce, - param.unsigned.tip, - ), - ) - .expect("SignedExtension never fails."); - - let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload)); - let signer: sp_runtime::MultiSigner = param.signer.public().into(); - let (call, extra, _) = raw_payload.deconstruct(); - - Ok(bp_kusama::UncheckedExtrinsic::new_signed( - call, - sp_runtime::MultiAddress::Id(signer.into_account()), - signature.into(), - extra, - )) - } - - fn is_signed(tx: &Self::SignedTransaction) -> bool { - tx.signature.is_some() - } - - fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool { - tx.signature - .as_ref() - .map(|(address, _, _)| { - *address == bp_kusama::AccountId::from(*signer.public().as_array_ref()).into() - }) - .unwrap_or(false) - } - - fn parse_transaction(tx: Self::SignedTransaction) -> Option> { - let extra = &tx.signature.as_ref()?.2; - Some(UnsignedTransaction { call: tx.function, nonce: extra.nonce(), tip: extra.tip() }) - } -} - -/// Kusama header type used in headers sync. -pub type SyncHeader = relay_substrate_client::SyncHeader; - -/// Kusama signing params. -pub type SigningParams = sp_core::sr25519::Pair; diff --git a/relays/client-kusama/src/runtime.rs b/relays/client-kusama/src/runtime.rs deleted file mode 100644 index 485ce1138..000000000 --- a/relays/client-kusama/src/runtime.rs +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Types that are specific to the Kusama runtime. - -use bp_messages::{LaneId, UnrewardedRelayersState}; -use bp_polkadot_core::{AccountAddress, Balance, PolkadotLike}; -use bp_runtime::Chain; -use codec::{Compact, Decode, Encode}; -use frame_support::weights::Weight; -use scale_info::TypeInfo; -use sp_runtime::FixedU128; - -/// Unchecked Kusama extrinsic. -pub type UncheckedExtrinsic = bp_polkadot_core::UncheckedExtrinsic; - -/// Polkadot account ownership digest from Kusama. -/// -/// The byte vector returned by this function should be signed with a Polkadot account private key. -/// This way, the owner of `kusama_account_id` on Kusama proves that the Polkadot account private -/// key is also under his control. -pub fn kusama_to_polkadot_account_ownership_digest( - polkadot_call: &Call, - kusama_account_id: AccountId, - polkadot_spec_version: SpecVersion, -) -> Vec -where - Call: codec::Encode, - AccountId: codec::Encode, - SpecVersion: codec::Encode, -{ - pallet_bridge_dispatch::account_ownership_digest( - polkadot_call, - kusama_account_id, - polkadot_spec_version, - bp_runtime::KUSAMA_CHAIN_ID, - bp_runtime::POLKADOT_CHAIN_ID, - ) -} - -/// Kusama Runtime `Call` enum. -/// -/// The enum represents a subset of possible `Call`s we can send to Kusama chain. -/// Ideally this code would be auto-generated from metadata, because we want to -/// avoid depending directly on the ENTIRE runtime just to get the encoding of `Dispatchable`s. -/// -/// All entries here (like pretty much in the entire file) must be kept in sync with Kusama -/// `construct_runtime`, so that we maintain SCALE-compatibility. -/// -/// See: [link](https://github.com/paritytech/polkadot/blob/master/runtime/kusama/src/lib.rs) -#[allow(clippy::large_enum_variant)] -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -pub enum Call { - /// System pallet. - #[codec(index = 0)] - System(SystemCall), - /// Balances pallet. - #[codec(index = 4)] - Balances(BalancesCall), - /// Utility pallet. - #[codec(index = 24)] - Utility(UtilityCall), - /// Polkadot bridge pallet. - #[codec(index = 110)] - BridgePolkadotGrandpa(BridgePolkadotGrandpaCall), - /// Polkadot messages pallet. - #[codec(index = 111)] - BridgePolkadotMessages(BridgePolkadotMessagesCall), -} - -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -#[allow(non_camel_case_types)] -pub enum SystemCall { - #[codec(index = 1)] - remark(Vec), -} - -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -#[allow(non_camel_case_types)] -pub enum BalancesCall { - #[codec(index = 0)] - transfer(AccountAddress, Compact), -} - -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -#[allow(non_camel_case_types)] -pub enum BridgePolkadotGrandpaCall { - #[codec(index = 0)] - submit_finality_proof( - Box<::Header>, - bp_header_chain::justification::GrandpaJustification<::Header>, - ), - #[codec(index = 1)] - initialize(bp_header_chain::InitializationData<::Header>), - #[codec(index = 3)] - set_operational(bool), -} - -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -#[allow(non_camel_case_types)] -pub enum BridgePolkadotMessagesCall { - #[codec(index = 2)] - update_pallet_parameter(BridgePolkadotMessagesParameter), - #[codec(index = 3)] - send_message( - LaneId, - bp_message_dispatch::MessagePayload< - bp_kusama::AccountId, - bp_polkadot::AccountId, - bp_polkadot::AccountPublic, - Vec, - >, - bp_kusama::Balance, - ), - #[codec(index = 5)] - receive_messages_proof( - bp_polkadot::AccountId, - bridge_runtime_common::messages::target::FromBridgedChainMessagesProof, - u32, - Weight, - ), - #[codec(index = 6)] - receive_messages_delivery_proof( - bridge_runtime_common::messages::source::FromBridgedChainMessagesDeliveryProof< - bp_polkadot::Hash, - >, - UnrewardedRelayersState, - ), -} - -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -#[allow(non_camel_case_types)] -pub enum UtilityCall { - #[codec(index = 2)] - batch_all(Vec), -} - -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -pub enum BridgePolkadotMessagesParameter { - #[codec(index = 0)] - PolkadotToKusamaConversionRate(FixedU128), -} - -impl sp_runtime::traits::Dispatchable for Call { - type Config = (); - type Info = (); - type Origin = (); - type PostInfo = (); - - fn dispatch(self, _origin: Self::Origin) -> sp_runtime::DispatchResultWithInfo { - unimplemented!("The Call is not expected to be dispatched.") - } -} diff --git a/relays/client-polkadot/Cargo.toml b/relays/client-polkadot/Cargo.toml deleted file mode 100644 index 96cfa2ce1..000000000 --- a/relays/client-polkadot/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "relay-polkadot-client" -version = "0.1.0" -authors = ["Parity Technologies "] -edition = "2021" -license = "GPL-3.0-or-later WITH Classpath-exception-2.0" - -[dependencies] -codec = { package = "parity-scale-codec", version = "3.0.0" } -relay-substrate-client = { path = "../client-substrate" } -relay-utils = { path = "../utils" } -scale-info = { version = "2.0.1", features = ["derive"] } - -# Bridge dependencies - -bp-header-chain = { path = "../../primitives/header-chain" } -bp-kusama = { path = "../../primitives/chain-kusama" } -bp-message-dispatch = { path = "../../primitives/message-dispatch" } -bp-messages = { path = "../../primitives/messages" } -bp-polkadot = { path = "../../primitives/chain-polkadot" } -bp-polkadot-core = { path = "../../primitives/polkadot-core" } -bp-runtime = { path = "../../primitives/runtime" } -bridge-runtime-common = { path = "../../bin/runtime-common" } -pallet-bridge-dispatch = { path = "../../modules/dispatch" } - -# Substrate Dependencies - -frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/relays/client-polkadot/src/lib.rs b/relays/client-polkadot/src/lib.rs deleted file mode 100644 index b18c5b3bb..000000000 --- a/relays/client-polkadot/src/lib.rs +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Types used to connect to the Polkadot chain. - -use bp_messages::MessageNonce; -use codec::Encode; -use frame_support::weights::Weight; -use relay_substrate_client::{ - Chain, ChainBase, ChainWithBalances, ChainWithGrandpa, ChainWithMessages, - Error as SubstrateError, SignParam, TransactionSignScheme, UnsignedTransaction, -}; -use sp_core::{storage::StorageKey, Pair}; -use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount}; -use std::time::Duration; - -pub mod runtime; - -/// Polkadot header id. -pub type HeaderId = relay_utils::HeaderId; - -/// Polkadot chain definition -#[derive(Debug, Clone, Copy)] -pub struct Polkadot; - -impl ChainBase for Polkadot { - type AccountId = bp_polkadot::AccountId; - type Balance = bp_polkadot::Balance; - type BlockNumber = bp_polkadot::BlockNumber; - type Hash = bp_polkadot::Hash; - type Hasher = bp_polkadot::Hasher; - type Header = bp_polkadot::Header; - type Index = bp_polkadot::Nonce; - type Signature = bp_polkadot::Signature; - - fn max_extrinsic_size() -> u32 { - bp_polkadot::Polkadot::max_extrinsic_size() - } - - fn max_extrinsic_weight() -> Weight { - bp_polkadot::Polkadot::max_extrinsic_weight() - } -} - -impl Chain for Polkadot { - type Call = crate::runtime::Call; - type SignedBlock = bp_polkadot::SignedBlock; - type WeightToFee = bp_polkadot::WeightToFee; - - const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6); - const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = - bp_polkadot::BEST_FINALIZED_POLKADOT_HEADER_METHOD; - const MAXIMAL_ENCODED_ACCOUNT_ID_SIZE: u32 = bp_polkadot::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE; - const NAME: &'static str = "Polkadot"; - const STORAGE_PROOF_OVERHEAD: u32 = bp_polkadot::EXTRA_STORAGE_PROOF_SIZE; - const TOKEN_ID: Option<&'static str> = Some("polkadot"); -} - -impl ChainWithGrandpa for Polkadot { - const WITH_CHAIN_GRANDPA_PALLET_NAME: &'static str = - bp_polkadot::WITH_POLKADOT_GRANDPA_PALLET_NAME; -} - -impl ChainWithMessages for Polkadot { - type WeightInfo = (); - - const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = - bp_polkadot::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; - const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = - bp_polkadot::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; - const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN: Weight = - bp_polkadot::PAY_INBOUND_DISPATCH_FEE_WEIGHT; - const TO_CHAIN_MESSAGE_DETAILS_METHOD: &'static str = - bp_polkadot::TO_POLKADOT_MESSAGE_DETAILS_METHOD; - const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = - bp_polkadot::WITH_POLKADOT_MESSAGES_PALLET_NAME; -} - -impl ChainWithBalances for Polkadot { - fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey { - StorageKey(bp_polkadot::account_info_storage_key(account_id)) - } -} - -impl TransactionSignScheme for Polkadot { - type AccountKeyPair = sp_core::sr25519::Pair; - type Chain = Polkadot; - type SignedTransaction = crate::runtime::UncheckedExtrinsic; - - fn sign_transaction(param: SignParam) -> Result { - let raw_payload = SignedPayload::new( - param.unsigned.call.clone(), - bp_polkadot::SignedExtensions::new( - param.spec_version, - param.transaction_version, - param.era, - param.genesis_hash, - param.unsigned.nonce, - param.unsigned.tip, - ), - ) - .expect("SignedExtension never fails."); - - let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload)); - let signer: sp_runtime::MultiSigner = param.signer.public().into(); - let (call, extra, _) = raw_payload.deconstruct(); - - Ok(bp_polkadot::UncheckedExtrinsic::new_signed( - call, - sp_runtime::MultiAddress::Id(signer.into_account()), - signature.into(), - extra, - )) - } - - fn is_signed(tx: &Self::SignedTransaction) -> bool { - tx.signature.is_some() - } - - fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool { - tx.signature - .as_ref() - .map(|(address, _, _)| { - *address == bp_polkadot::AccountId::from(*signer.public().as_array_ref()).into() - }) - .unwrap_or(false) - } - - fn parse_transaction(tx: Self::SignedTransaction) -> Option> { - let extra = &tx.signature.as_ref()?.2; - Some(UnsignedTransaction { call: tx.function, nonce: extra.nonce(), tip: extra.tip() }) - } -} - -/// Polkadot header type used in headers sync. -pub type SyncHeader = relay_substrate_client::SyncHeader; - -/// Polkadot signing params. -pub type SigningParams = sp_core::sr25519::Pair; diff --git a/relays/client-polkadot/src/runtime.rs b/relays/client-polkadot/src/runtime.rs deleted file mode 100644 index 613f55c21..000000000 --- a/relays/client-polkadot/src/runtime.rs +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Types that are specific to the Polkadot runtime. - -use bp_messages::{LaneId, UnrewardedRelayersState}; -use bp_polkadot_core::{AccountAddress, Balance, PolkadotLike}; -use bp_runtime::Chain; -use codec::{Compact, Decode, Encode}; -use frame_support::weights::Weight; -use scale_info::TypeInfo; -use sp_runtime::FixedU128; - -/// Unchecked Polkadot extrinsic. -pub type UncheckedExtrinsic = bp_polkadot_core::UncheckedExtrinsic; - -/// Kusama account ownership digest from Polkadot. -/// -/// The byte vector returned by this function should be signed with a Kusama account private key. -/// This way, the owner of `kusam_account_id` on Polkadot proves that the Kusama account private key -/// is also under his control. -pub fn polkadot_to_kusama_account_ownership_digest( - kusama_call: &Call, - kusam_account_id: AccountId, - kusama_spec_version: SpecVersion, -) -> Vec -where - Call: codec::Encode, - AccountId: codec::Encode, - SpecVersion: codec::Encode, -{ - pallet_bridge_dispatch::account_ownership_digest( - kusama_call, - kusam_account_id, - kusama_spec_version, - bp_runtime::POLKADOT_CHAIN_ID, - bp_runtime::KUSAMA_CHAIN_ID, - ) -} - -/// Polkadot Runtime `Call` enum. -/// -/// The enum represents a subset of possible `Call`s we can send to Polkadot chain. -/// Ideally this code would be auto-generated from metadata, because we want to -/// avoid depending directly on the ENTIRE runtime just to get the encoding of `Dispatchable`s. -/// -/// All entries here (like pretty much in the entire file) must be kept in sync with Polkadot -/// `construct_runtime`, so that we maintain SCALE-compatibility. -/// -/// See: [link](https://github.com/paritytech/kusama/blob/master/runtime/kusam/src/lib.rs) -#[allow(clippy::large_enum_variant)] -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -pub enum Call { - /// System pallet. - #[codec(index = 0)] - System(SystemCall), - /// Balances pallet. - #[codec(index = 5)] - Balances(BalancesCall), - /// Utility pallet. - #[codec(index = 26)] - Utility(UtilityCall), - /// Kusama bridge pallet. - #[codec(index = 110)] - BridgeKusamaGrandpa(BridgeKusamaGrandpaCall), - /// Kusama messages pallet. - #[codec(index = 111)] - BridgeKusamaMessages(BridgeKusamaMessagesCall), -} - -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -#[allow(non_camel_case_types)] -pub enum SystemCall { - #[codec(index = 1)] - remark(Vec), -} - -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -#[allow(non_camel_case_types)] -pub enum BalancesCall { - #[codec(index = 0)] - transfer(AccountAddress, Compact), -} - -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -#[allow(non_camel_case_types)] -pub enum BridgeKusamaGrandpaCall { - #[codec(index = 0)] - submit_finality_proof( - Box<::Header>, - bp_header_chain::justification::GrandpaJustification<::Header>, - ), - #[codec(index = 1)] - initialize(bp_header_chain::InitializationData<::Header>), - #[codec(index = 3)] - set_operational(bool), -} - -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -#[allow(non_camel_case_types)] -pub enum BridgeKusamaMessagesCall { - #[codec(index = 2)] - update_pallet_parameter(BridgeKusamaMessagesParameter), - #[codec(index = 3)] - send_message( - LaneId, - bp_message_dispatch::MessagePayload< - bp_polkadot::AccountId, - bp_kusama::AccountId, - bp_kusama::AccountPublic, - Vec, - >, - bp_polkadot::Balance, - ), - #[codec(index = 5)] - receive_messages_proof( - bp_kusama::AccountId, - bridge_runtime_common::messages::target::FromBridgedChainMessagesProof, - u32, - Weight, - ), - #[codec(index = 6)] - receive_messages_delivery_proof( - bridge_runtime_common::messages::source::FromBridgedChainMessagesDeliveryProof< - bp_kusama::Hash, - >, - UnrewardedRelayersState, - ), -} - -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -#[allow(non_camel_case_types)] -pub enum UtilityCall { - #[codec(index = 2)] - batch_all(Vec), -} - -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -pub enum BridgeKusamaMessagesParameter { - #[codec(index = 0)] - KusamaToPolkadotConversionRate(FixedU128), -} - -impl sp_runtime::traits::Dispatchable for Call { - type Config = (); - type Info = (); - type Origin = (); - type PostInfo = (); - - fn dispatch(self, _origin: Self::Origin) -> sp_runtime::DispatchResultWithInfo { - unimplemented!("The Call is not expected to be dispatched.") - } -} diff --git a/relays/client-rococo/Cargo.toml b/relays/client-rococo/Cargo.toml deleted file mode 100644 index 2b78684a8..000000000 --- a/relays/client-rococo/Cargo.toml +++ /dev/null @@ -1,31 +0,0 @@ -[package] -name = "relay-rococo-client" -version = "0.1.0" -authors = ["Parity Technologies "] -edition = "2021" -license = "GPL-3.0-or-later WITH Classpath-exception-2.0" - -[dependencies] -codec = { package = "parity-scale-codec", version = "3.0.0" } -relay-substrate-client = { path = "../client-substrate" } -relay-utils = { path = "../utils" } -scale-info = { version = "2.0.1", features = ["derive"] } - -# Bridge dependencies - -bridge-runtime-common = { path = "../../bin/runtime-common" } -bp-header-chain = { path = "../../primitives/header-chain" } -bp-message-dispatch = { path = "../../primitives/message-dispatch" } -bp-messages = { path = "../../primitives/messages" } -bp-polkadot-core = { path = "../../primitives/polkadot-core" } -bp-rococo = { path = "../../primitives/chain-rococo" } -bp-runtime = { path = "../../primitives/runtime" } -bp-wococo = { path = "../../primitives/chain-wococo" } -pallet-bridge-dispatch = { path = "../../modules/dispatch" } -pallet-bridge-messages = { path = "../../modules/messages" } - -# Substrate Dependencies - -frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/relays/client-rococo/src/lib.rs b/relays/client-rococo/src/lib.rs deleted file mode 100644 index 4380621c2..000000000 --- a/relays/client-rococo/src/lib.rs +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Types used to connect to the Rococo-Substrate chain. - -use bp_messages::MessageNonce; -use codec::Encode; -use frame_support::weights::Weight; -use relay_substrate_client::{ - Chain, ChainBase, ChainWithBalances, ChainWithGrandpa, ChainWithMessages, - Error as SubstrateError, SignParam, TransactionSignScheme, UnsignedTransaction, -}; -use sp_core::{storage::StorageKey, Pair}; -use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount}; -use std::time::Duration; - -pub mod runtime; - -/// Rococo header id. -pub type HeaderId = relay_utils::HeaderId; - -/// Rococo header type used in headers sync. -pub type SyncHeader = relay_substrate_client::SyncHeader; - -/// Rococo chain definition -#[derive(Debug, Clone, Copy)] -pub struct Rococo; - -impl ChainBase for Rococo { - type AccountId = bp_rococo::AccountId; - type Balance = bp_rococo::Balance; - type BlockNumber = bp_rococo::BlockNumber; - type Hash = bp_rococo::Hash; - type Hasher = bp_rococo::Hashing; - type Header = bp_rococo::Header; - type Index = bp_rococo::Nonce; - type Signature = bp_rococo::Signature; - - fn max_extrinsic_size() -> u32 { - bp_rococo::Rococo::max_extrinsic_size() - } - - fn max_extrinsic_weight() -> Weight { - bp_rococo::Rococo::max_extrinsic_weight() - } -} - -impl Chain for Rococo { - type Call = crate::runtime::Call; - type SignedBlock = bp_rococo::SignedBlock; - type WeightToFee = bp_rococo::WeightToFee; - - const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6); - const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = - bp_rococo::BEST_FINALIZED_ROCOCO_HEADER_METHOD; - const MAXIMAL_ENCODED_ACCOUNT_ID_SIZE: u32 = bp_rococo::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE; - const NAME: &'static str = "Rococo"; - const STORAGE_PROOF_OVERHEAD: u32 = bp_rococo::EXTRA_STORAGE_PROOF_SIZE; - const TOKEN_ID: Option<&'static str> = None; -} - -impl ChainWithGrandpa for Rococo { - const WITH_CHAIN_GRANDPA_PALLET_NAME: &'static str = bp_rococo::WITH_ROCOCO_GRANDPA_PALLET_NAME; -} - -impl ChainWithMessages for Rococo { - type WeightInfo = (); - - const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = - bp_rococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; - const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = - bp_rococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; - const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN: Weight = - bp_rococo::PAY_INBOUND_DISPATCH_FEE_WEIGHT; - const TO_CHAIN_MESSAGE_DETAILS_METHOD: &'static str = - bp_rococo::TO_ROCOCO_MESSAGE_DETAILS_METHOD; - const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = - bp_rococo::WITH_ROCOCO_MESSAGES_PALLET_NAME; -} - -impl ChainWithBalances for Rococo { - fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey { - StorageKey(bp_rococo::account_info_storage_key(account_id)) - } -} - -impl TransactionSignScheme for Rococo { - type AccountKeyPair = sp_core::sr25519::Pair; - type Chain = Rococo; - type SignedTransaction = crate::runtime::UncheckedExtrinsic; - - fn sign_transaction(param: SignParam) -> Result { - let raw_payload = SignedPayload::new( - param.unsigned.call.clone(), - bp_rococo::SignedExtensions::new( - param.spec_version, - param.transaction_version, - param.era, - param.genesis_hash, - param.unsigned.nonce, - param.unsigned.tip, - ), - ) - .expect("SignedExtension never fails."); - - let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload)); - let signer: sp_runtime::MultiSigner = param.signer.public().into(); - let (call, extra, _) = raw_payload.deconstruct(); - - Ok(bp_rococo::UncheckedExtrinsic::new_signed( - call, - sp_runtime::MultiAddress::Id(signer.into_account()), - signature.into(), - extra, - )) - } - - fn is_signed(tx: &Self::SignedTransaction) -> bool { - tx.signature.is_some() - } - - fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool { - tx.signature - .as_ref() - .map(|(address, _, _)| { - *address == bp_rococo::AccountId::from(*signer.public().as_array_ref()).into() - }) - .unwrap_or(false) - } - - fn parse_transaction(tx: Self::SignedTransaction) -> Option> { - let extra = &tx.signature.as_ref()?.2; - Some(UnsignedTransaction { call: tx.function, nonce: extra.nonce(), tip: extra.tip() }) - } -} - -/// Rococo signing params. -pub type SigningParams = sp_core::sr25519::Pair; diff --git a/relays/client-rococo/src/runtime.rs b/relays/client-rococo/src/runtime.rs deleted file mode 100644 index b3fb90fe0..000000000 --- a/relays/client-rococo/src/runtime.rs +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Types that are specific to the Rococo runtime. - -use bp_messages::{LaneId, UnrewardedRelayersState}; -use bp_polkadot_core::{AccountAddress, Balance, PolkadotLike}; -use bp_runtime::Chain; -use codec::{Compact, Decode, Encode}; -use frame_support::weights::Weight; -use scale_info::TypeInfo; - -/// Unchecked Rococo extrinsic. -pub type UncheckedExtrinsic = bp_polkadot_core::UncheckedExtrinsic; - -/// Wococo account ownership digest from Rococo. -/// -/// The byte vector returned by this function should be signed with a Wococo account private key. -/// This way, the owner of `rococo_account_id` on Rococo proves that the Wococo account private key -/// is also under his control. -pub fn rococo_to_wococo_account_ownership_digest( - wococo_call: &Call, - rococo_account_id: AccountId, - wococo_spec_version: SpecVersion, -) -> Vec -where - Call: codec::Encode, - AccountId: codec::Encode, - SpecVersion: codec::Encode, -{ - pallet_bridge_dispatch::account_ownership_digest( - wococo_call, - rococo_account_id, - wococo_spec_version, - bp_runtime::ROCOCO_CHAIN_ID, - bp_runtime::WOCOCO_CHAIN_ID, - ) -} - -/// Rococo Runtime `Call` enum. -/// -/// The enum represents a subset of possible `Call`s we can send to Rococo chain. -/// Ideally this code would be auto-generated from metadata, because we want to -/// avoid depending directly on the ENTIRE runtime just to get the encoding of `Dispatchable`s. -/// -/// All entries here (like pretty much in the entire file) must be kept in sync with Rococo -/// `construct_runtime`, so that we maintain SCALE-compatibility. -/// -/// See: [link](https://github.com/paritytech/polkadot/blob/master/runtime/rococo/src/lib.rs) -#[allow(clippy::large_enum_variant)] -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -pub enum Call { - /// System pallet. - #[codec(index = 0)] - System(SystemCall), - /// Balances pallet. - #[codec(index = 4)] - Balances(BalancesCall), - /// Wococo bridge pallet. - #[codec(index = 41)] - BridgeGrandpaWococo(BridgeGrandpaWococoCall), - /// Wococo messages pallet. - #[codec(index = 44)] - BridgeWococoMessages(BridgeWococoMessagesCall), -} - -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -#[allow(non_camel_case_types)] -pub enum SystemCall { - #[codec(index = 1)] - remark(Vec), -} - -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -#[allow(non_camel_case_types)] -pub enum BalancesCall { - #[codec(index = 0)] - transfer(AccountAddress, Compact), -} - -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -#[allow(non_camel_case_types)] -pub enum BridgeGrandpaWococoCall { - #[codec(index = 0)] - submit_finality_proof( - Box<::Header>, - bp_header_chain::justification::GrandpaJustification<::Header>, - ), - #[codec(index = 1)] - initialize(bp_header_chain::InitializationData<::Header>), -} - -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -#[allow(non_camel_case_types)] -pub enum BridgeWococoMessagesCall { - #[codec(index = 3)] - send_message( - LaneId, - bp_message_dispatch::MessagePayload< - bp_rococo::AccountId, - bp_wococo::AccountId, - bp_wococo::AccountPublic, - Vec, - >, - bp_rococo::Balance, - ), - #[codec(index = 5)] - receive_messages_proof( - bp_wococo::AccountId, - bridge_runtime_common::messages::target::FromBridgedChainMessagesProof, - u32, - Weight, - ), - #[codec(index = 6)] - receive_messages_delivery_proof( - bridge_runtime_common::messages::source::FromBridgedChainMessagesDeliveryProof< - bp_wococo::Hash, - >, - UnrewardedRelayersState, - ), -} - -impl sp_runtime::traits::Dispatchable for Call { - type Config = (); - type Info = (); - type Origin = (); - type PostInfo = (); - - fn dispatch(self, _origin: Self::Origin) -> sp_runtime::DispatchResultWithInfo { - unimplemented!("The Call is not expected to be dispatched.") - } -} diff --git a/relays/client-substrate/Cargo.toml b/relays/client-substrate/Cargo.toml deleted file mode 100644 index dad864965..000000000 --- a/relays/client-substrate/Cargo.toml +++ /dev/null @@ -1,48 +0,0 @@ -[package] -name = "relay-substrate-client" -version = "0.1.0" -authors = ["Parity Technologies "] -edition = "2021" -license = "GPL-3.0-or-later WITH Classpath-exception-2.0" - -[dependencies] -async-std = { version = "1.6.5", features = ["attributes"] } -async-trait = "0.1.40" -codec = { package = "parity-scale-codec", version = "3.0.0" } -jsonrpsee = { version = "0.8", features = ["macros", "ws-client"] } -log = "0.4.11" -num-traits = "0.2" -rand = "0.7" -serde = { version = "1.0" } -tokio = { version = "1.8", features = ["rt-multi-thread"] } -thiserror = "1.0.26" - -# Bridge dependencies - -bp-header-chain = { path = "../../primitives/header-chain" } -bp-messages = { path = "../../primitives/messages" } -bp-runtime = { path = "../../primitives/runtime" } -pallet-bridge-messages = { path = "../../modules/messages" } -finality-relay = { path = "../finality" } -relay-utils = { path = "../utils" } - -# Substrate Dependencies - -frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" } -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" } -pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master" } -pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master" } -sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "master" } -sc-rpc-api = { git = "https://github.com/paritytech/substrate", branch = "master" } -sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-storage = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-version = { git = "https://github.com/paritytech/substrate", branch = "master" } - -#[dev-dependencies] -futures = "0.3.7" diff --git a/relays/client-substrate/src/chain.rs b/relays/client-substrate/src/chain.rs deleted file mode 100644 index 57732bbd7..000000000 --- a/relays/client-substrate/src/chain.rs +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -use bp_messages::MessageNonce; -use bp_runtime::{Chain as ChainBase, EncodedOrDecodedCall, HashOf, TransactionEraOf}; -use codec::{Codec, Encode}; -use frame_support::weights::{Weight, WeightToFeePolynomial}; -use jsonrpsee::core::{DeserializeOwned, Serialize}; -use num_traits::Zero; -use sc_transaction_pool_api::TransactionStatus; -use sp_core::{storage::StorageKey, Pair}; -use sp_runtime::{ - generic::SignedBlock, - traits::{Block as BlockT, Dispatchable, Member}, - EncodedJustification, -}; -use std::{fmt::Debug, time::Duration}; - -/// Substrate-based chain from minimal relay-client point of view. -pub trait Chain: ChainBase + Clone { - /// Chain name. - const NAME: &'static str; - /// Identifier of the basic token of the chain (if applicable). - /// - /// This identifier is used to fetch token price. In case of testnets, you may either - /// set it to `None`, or associate testnet with one of the existing tokens. - const TOKEN_ID: Option<&'static str>; - /// Name of the runtime API method that is returning best known finalized header number - /// and hash (as tuple). - /// - /// Keep in mind that this method is normally provided by the other chain, which is - /// bridged with this chain. - const BEST_FINALIZED_HEADER_ID_METHOD: &'static str; - - /// Average block interval. - /// - /// How often blocks are produced on that chain. It's suggested to set this value - /// to match the block time of the chain. - const AVERAGE_BLOCK_INTERVAL: Duration; - /// Maximal expected storage proof overhead (in bytes). - const STORAGE_PROOF_OVERHEAD: u32; - /// Maximal size (in bytes) of SCALE-encoded account id on this chain. - const MAXIMAL_ENCODED_ACCOUNT_ID_SIZE: u32; - - /// Block type. - type SignedBlock: Member + Serialize + DeserializeOwned + BlockWithJustification; - /// The aggregated `Call` type. - type Call: Clone + Codec + Dispatchable + Debug + Send; - - /// Type that is used by the chain, to convert from weight to fee. - type WeightToFee: WeightToFeePolynomial; -} - -/// Substrate-based chain that is using direct GRANDPA finality from minimal relay-client point of -/// view. -/// -/// Keep in mind that parachains are relying on relay chain GRANDPA, so they should not implement -/// this trait. -pub trait ChainWithGrandpa: Chain { - /// Name of the bridge GRANDPA pallet (used in `construct_runtime` macro call) that is deployed - /// at some other chain to bridge with this `ChainWithGrandpa`. - /// - /// We assume that all chains that are bridging with this `ChainWithGrandpa` are using - /// the same name. - const WITH_CHAIN_GRANDPA_PALLET_NAME: &'static str; -} - -/// Substrate-based chain with messaging support from minimal relay-client point of view. -pub trait ChainWithMessages: Chain { - /// Name of the bridge messages pallet (used in `construct_runtime` macro call) that is deployed - /// at some other chain to bridge with this `ChainWithMessages`. - /// - /// We assume that all chains that are bridging with this `ChainWithMessages` are using - /// the same name. - const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str; - - /// Name of the `ToOutboundLaneApi::message_details` runtime API method. - /// The method is provided by the runtime that is bridged with this `ChainWithMessages`. - const TO_CHAIN_MESSAGE_DETAILS_METHOD: &'static str; - - /// Additional weight of the dispatch fee payment if dispatch is paid at the target chain - /// and this `ChainWithMessages` is the target chain. - const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN: Weight; - - /// Maximal number of unrewarded relayers in a single confirmation transaction at this - /// `ChainWithMessages`. - const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce; - /// Maximal number of unconfirmed messages in a single confirmation transaction at this - /// `ChainWithMessages`. - const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce; - - /// Weights of message pallet calls. - type WeightInfo: pallet_bridge_messages::WeightInfoExt; -} - -/// Call type used by the chain. -pub type CallOf = ::Call; -/// Weight-to-Fee type used by the chain. -pub type WeightToFeeOf = ::WeightToFee; -/// Transaction status of the chain. -pub type TransactionStatusOf = TransactionStatus, HashOf>; - -/// Substrate-based chain with `AccountData` generic argument of `frame_system::AccountInfo` set to -/// the `pallet_balances::AccountData`. -pub trait ChainWithBalances: Chain { - /// Return runtime storage key for getting `frame_system::AccountInfo` of given account. - fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey; -} - -/// SCALE-encoded extrinsic. -pub type EncodedExtrinsic = Vec; - -/// Block with justification. -pub trait BlockWithJustification
{ - /// Return block header. - fn header(&self) -> Header; - /// Return encoded block extrinsics. - fn extrinsics(&self) -> Vec; - /// Return block justification, if known. - fn justification(&self) -> Option<&EncodedJustification>; -} - -/// Transaction before it is signed. -#[derive(Clone, Debug, PartialEq)] -pub struct UnsignedTransaction { - /// Runtime call of this transaction. - pub call: EncodedOrDecodedCall, - /// Transaction nonce. - pub nonce: C::Index, - /// Tip included into transaction. - pub tip: C::Balance, -} - -impl UnsignedTransaction { - /// Create new unsigned transaction with given call, nonce and zero tip. - pub fn new(call: EncodedOrDecodedCall, nonce: C::Index) -> Self { - Self { call, nonce, tip: Zero::zero() } - } - - /// Set transaction tip. - pub fn tip(mut self, tip: C::Balance) -> Self { - self.tip = tip; - self - } -} - -/// Account key pair used by transactions signing scheme. -pub type AccountKeyPairOf = ::AccountKeyPair; - -/// Substrate-based chain transactions signing scheme. -pub trait TransactionSignScheme { - /// Chain that this scheme is to be used. - type Chain: Chain; - /// Type of key pairs used to sign transactions. - type AccountKeyPair: Pair; - /// Signed transaction. - type SignedTransaction: Clone + Debug + Codec + Send + 'static; - - /// Create transaction for given runtime call, signed by given account. - fn sign_transaction(param: SignParam) -> Result - where - Self: Sized; - - /// Returns true if transaction is signed. - fn is_signed(tx: &Self::SignedTransaction) -> bool; - - /// Returns true if transaction is signed by given signer. - fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool; - - /// Parse signed transaction into its unsigned part. - /// - /// Returns `None` if signed transaction has unsupported format. - fn parse_transaction(tx: Self::SignedTransaction) -> Option>; -} - -/// Sign transaction parameters -pub struct SignParam { - /// Version of the runtime specification. - pub spec_version: u32, - /// Transaction version - pub transaction_version: u32, - /// Hash of the genesis block. - pub genesis_hash: ::Hash, - /// Signer account - pub signer: T::AccountKeyPair, - /// Transaction era used by the chain. - pub era: TransactionEraOf, - /// Transaction before it is signed. - pub unsigned: UnsignedTransaction, -} - -impl BlockWithJustification for SignedBlock { - fn header(&self) -> Block::Header { - self.block.header().clone() - } - - fn extrinsics(&self) -> Vec { - self.block.extrinsics().iter().map(Encode::encode).collect() - } - - fn justification(&self) -> Option<&EncodedJustification> { - self.justifications.as_ref().and_then(|j| j.get(sp_finality_grandpa::GRANDPA_ENGINE_ID)) - } -} diff --git a/relays/client-substrate/src/client.rs b/relays/client-substrate/src/client.rs deleted file mode 100644 index 8179492cf..000000000 --- a/relays/client-substrate/src/client.rs +++ /dev/null @@ -1,787 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Substrate node client. - -use crate::{ - chain::{Chain, ChainWithBalances, TransactionStatusOf}, - rpc::SubstrateClient, - AccountIdOf, BlockNumberOf, ConnectionParams, Error, HashOf, HeaderIdOf, HeaderOf, IndexOf, - Result, -}; - -use async_std::sync::{Arc, Mutex}; -use async_trait::async_trait; -use codec::{Decode, Encode}; -use frame_system::AccountInfo; -use futures::{SinkExt, StreamExt}; -use jsonrpsee::{ - core::{client::SubscriptionClientT, DeserializeOwned}, - types::params::ParamsSer, - ws_client::{WsClient as RpcClient, WsClientBuilder as RpcClientBuilder}, -}; -use num_traits::{Bounded, CheckedSub, One, Zero}; -use pallet_balances::AccountData; -use pallet_transaction_payment::InclusionFee; -use relay_utils::{relay_loop::RECONNECT_DELAY, HeaderId}; -use sp_core::{ - storage::{StorageData, StorageKey}, - Bytes, Hasher, -}; -use sp_runtime::{ - traits::Header as HeaderT, - transaction_validity::{TransactionSource, TransactionValidity}, -}; -use sp_trie::StorageProof; -use sp_version::RuntimeVersion; -use std::{convert::TryFrom, future::Future}; - -const SUB_API_GRANDPA_AUTHORITIES: &str = "GrandpaApi_grandpa_authorities"; -const SUB_API_TXPOOL_VALIDATE_TRANSACTION: &str = "TaggedTransactionQueue_validate_transaction"; -const MAX_SUBSCRIPTION_CAPACITY: usize = 4096; - -/// Opaque justifications subscription type. -pub struct Subscription(Mutex>>); - -/// Opaque GRANDPA authorities set. -pub type OpaqueGrandpaAuthoritiesSet = Vec; - -/// Chain runtime version in client -#[derive(Clone, Debug)] -pub enum ChainRuntimeVersion { - /// Auto query from chain. - Auto, - /// Custom runtime version, defined by user. - /// the first is `spec_version` - /// the second is `transaction_version` - Custom(u32, u32), -} - -/// Substrate client type. -/// -/// Cloning `Client` is a cheap operation. -pub struct Client { - /// Tokio runtime handle. - tokio: Arc, - /// Client connection params. - params: ConnectionParams, - /// Substrate RPC client. - client: Arc, - /// Genesis block hash. - genesis_hash: HashOf, - /// If several tasks are submitting their transactions simultaneously using - /// `submit_signed_extrinsic` method, they may get the same transaction nonce. So one of - /// transactions will be rejected from the pool. This lock is here to prevent situations like - /// that. - submit_signed_extrinsic_lock: Arc>, - /// Saved chain runtime version - chain_runtime_version: ChainRuntimeVersion, -} - -#[async_trait] -impl relay_utils::relay_loop::Client for Client { - type Error = Error; - - async fn reconnect(&mut self) -> Result<()> { - let (tokio, client) = Self::build_client(self.params.clone()).await?; - self.tokio = tokio; - self.client = client; - Ok(()) - } -} - -impl Clone for Client { - fn clone(&self) -> Self { - Client { - tokio: self.tokio.clone(), - params: self.params.clone(), - client: self.client.clone(), - genesis_hash: self.genesis_hash, - submit_signed_extrinsic_lock: self.submit_signed_extrinsic_lock.clone(), - chain_runtime_version: self.chain_runtime_version.clone(), - } - } -} - -impl std::fmt::Debug for Client { - fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { - fmt.debug_struct("Client").field("genesis_hash", &self.genesis_hash).finish() - } -} - -impl Client { - /// Returns client that is able to call RPCs on Substrate node over websocket connection. - /// - /// This function will keep connecting to given Substrate node until connection is established - /// and is functional. If attempt fail, it will wait for `RECONNECT_DELAY` and retry again. - pub async fn new(params: ConnectionParams) -> Self { - loop { - match Self::try_connect(params.clone()).await { - Ok(client) => return client, - Err(error) => log::error!( - target: "bridge", - "Failed to connect to {} node: {:?}. Going to retry in {}s", - C::NAME, - error, - RECONNECT_DELAY.as_secs(), - ), - } - - async_std::task::sleep(RECONNECT_DELAY).await; - } - } - - /// Try to connect to Substrate node over websocket. Returns Substrate RPC client if connection - /// has been established or error otherwise. - pub async fn try_connect(params: ConnectionParams) -> Result { - let (tokio, client) = Self::build_client(params.clone()).await?; - - let number: C::BlockNumber = Zero::zero(); - let genesis_hash_client = client.clone(); - let genesis_hash = tokio - .spawn(async move { - SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::chain_get_block_hash(&*genesis_hash_client, Some(number)) - .await - }) - .await??; - - let chain_runtime_version = params.chain_runtime_version.clone(); - Ok(Self { - tokio, - params, - client, - genesis_hash, - submit_signed_extrinsic_lock: Arc::new(Mutex::new(())), - chain_runtime_version, - }) - } - - /// Build client to use in connection. - async fn build_client( - params: ConnectionParams, - ) -> Result<(Arc, Arc)> { - let tokio = tokio::runtime::Runtime::new()?; - let uri = format!( - "{}://{}:{}", - if params.secure { "wss" } else { "ws" }, - params.host, - params.port, - ); - let client = tokio - .spawn(async move { - RpcClientBuilder::default() - .max_notifs_per_subscription(MAX_SUBSCRIPTION_CAPACITY) - .build(&uri) - .await - }) - .await??; - - Ok((Arc::new(tokio), Arc::new(client))) - } -} - -impl Client { - /// Return simple runtime version, only include `spec_version` and `transaction_version`. - pub async fn simple_runtime_version(&self) -> Result<(u32, u32)> { - let (spec_version, transaction_version) = match self.chain_runtime_version { - ChainRuntimeVersion::Auto => { - let runtime_version = self.runtime_version().await?; - (runtime_version.spec_version, runtime_version.transaction_version) - }, - ChainRuntimeVersion::Custom(spec_version, transaction_version) => - (spec_version, transaction_version), - }; - Ok((spec_version, transaction_version)) - } - - /// Returns true if client is connected to at least one peer and is in synced state. - pub async fn ensure_synced(&self) -> Result<()> { - self.jsonrpsee_execute(|client| async move { - let health = SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::system_health(&*client) - .await?; - let is_synced = !health.is_syncing && (!health.should_have_peers || health.peers > 0); - if is_synced { - Ok(()) - } else { - Err(Error::ClientNotSynced(health)) - } - }) - .await - } - - /// Return hash of the genesis block. - pub fn genesis_hash(&self) -> &C::Hash { - &self.genesis_hash - } - - /// Return hash of the best finalized block. - pub async fn best_finalized_header_hash(&self) -> Result { - self.jsonrpsee_execute(|client| async move { - Ok(SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::chain_get_finalized_head(&*client) - .await?) - }) - .await - } - - /// Return number of the best finalized block. - pub async fn best_finalized_header_number(&self) -> Result { - Ok(*self.header_by_hash(self.best_finalized_header_hash().await?).await?.number()) - } - - /// Returns the best Substrate header. - pub async fn best_header(&self) -> Result - where - C::Header: DeserializeOwned, - { - self.jsonrpsee_execute(|client| async move { - Ok(SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::chain_get_header(&*client, None) - .await?) - }) - .await - } - - /// Get a Substrate block from its hash. - pub async fn get_block(&self, block_hash: Option) -> Result { - self.jsonrpsee_execute(move |client| async move { - Ok(SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::chain_get_block(&*client, block_hash) - .await?) - }) - .await - } - - /// Get a Substrate header by its hash. - pub async fn header_by_hash(&self, block_hash: C::Hash) -> Result - where - C::Header: DeserializeOwned, - { - self.jsonrpsee_execute(move |client| async move { - Ok(SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::chain_get_header(&*client, Some(block_hash)) - .await?) - }) - .await - } - - /// Get a Substrate block hash by its number. - pub async fn block_hash_by_number(&self, number: C::BlockNumber) -> Result { - self.jsonrpsee_execute(move |client| async move { - Ok(SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::chain_get_block_hash(&*client, Some(number)) - .await?) - }) - .await - } - - /// Get a Substrate header by its number. - pub async fn header_by_number(&self, block_number: C::BlockNumber) -> Result - where - C::Header: DeserializeOwned, - { - let block_hash = Self::block_hash_by_number(self, block_number).await?; - let header_by_hash = Self::header_by_hash(self, block_hash).await?; - Ok(header_by_hash) - } - - /// Return runtime version. - pub async fn runtime_version(&self) -> Result { - self.jsonrpsee_execute(move |client| async move { - Ok(SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::state_runtime_version(&*client) - .await?) - }) - .await - } - - /// Read value from runtime storage. - pub async fn storage_value( - &self, - storage_key: StorageKey, - block_hash: Option, - ) -> Result> { - self.raw_storage_value(storage_key, block_hash) - .await? - .map(|encoded_value| { - T::decode(&mut &encoded_value.0[..]).map_err(Error::ResponseParseFailed) - }) - .transpose() - } - - /// Read raw value from runtime storage. - pub async fn raw_storage_value( - &self, - storage_key: StorageKey, - block_hash: Option, - ) -> Result> { - self.jsonrpsee_execute(move |client| async move { - Ok(SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::state_get_storage(&*client, storage_key, block_hash) - .await?) - }) - .await - } - - /// Return native tokens balance of the account. - pub async fn free_native_balance(&self, account: C::AccountId) -> Result - where - C: ChainWithBalances, - { - self.jsonrpsee_execute(move |client| async move { - let storage_key = C::account_info_storage_key(&account); - let encoded_account_data = SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::state_get_storage(&*client, storage_key, None) - .await? - .ok_or(Error::AccountDoesNotExist)?; - let decoded_account_data = AccountInfo::>::decode( - &mut &encoded_account_data.0[..], - ) - .map_err(Error::ResponseParseFailed)?; - Ok(decoded_account_data.data.free) - }) - .await - } - - /// Get the nonce of the given Substrate account. - /// - /// Note: It's the caller's responsibility to make sure `account` is a valid SS58 address. - pub async fn next_account_index(&self, account: C::AccountId) -> Result { - self.jsonrpsee_execute(move |client| async move { - Ok(SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::system_account_next_index(&*client, account) - .await?) - }) - .await - } - - /// Submit unsigned extrinsic for inclusion in a block. - /// - /// Note: The given transaction needs to be SCALE encoded beforehand. - pub async fn submit_unsigned_extrinsic(&self, transaction: Bytes) -> Result { - self.jsonrpsee_execute(move |client| async move { - let tx_hash = SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::author_submit_extrinsic(&*client, transaction) - .await?; - log::trace!(target: "bridge", "Sent transaction to Substrate node: {:?}", tx_hash); - Ok(tx_hash) - }) - .await - } - - /// Submit an extrinsic signed by given account. - /// - /// All calls of this method are synchronized, so there can't be more than one active - /// `submit_signed_extrinsic()` call. This guarantees that no nonces collision may happen - /// if all client instances are clones of the same initial `Client`. - /// - /// Note: The given transaction needs to be SCALE encoded beforehand. - pub async fn submit_signed_extrinsic( - &self, - extrinsic_signer: C::AccountId, - prepare_extrinsic: impl FnOnce(HeaderIdOf, C::Index) -> Result + Send + 'static, - ) -> Result { - let _guard = self.submit_signed_extrinsic_lock.lock().await; - let transaction_nonce = self.next_account_index(extrinsic_signer).await?; - let best_header = self.best_header().await?; - - // By using parent of best block here, we are protecing again best-block reorganizations. - // E.g. transaction my have been submitted when the best block was `A[num=100]`. Then it has - // been changed to `B[num=100]`. Hash of `A` has been included into transaction signature - // payload. So when signature will be checked, the check will fail and transaction will be - // dropped from the pool. - let best_header_id = match best_header.number().checked_sub(&One::one()) { - Some(parent_block_number) => HeaderId(parent_block_number, *best_header.parent_hash()), - None => HeaderId(*best_header.number(), best_header.hash()), - }; - - self.jsonrpsee_execute(move |client| async move { - let extrinsic = prepare_extrinsic(best_header_id, transaction_nonce)?; - let tx_hash = SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::author_submit_extrinsic(&*client, extrinsic) - .await?; - log::trace!(target: "bridge", "Sent transaction to {} node: {:?}", C::NAME, tx_hash); - Ok(tx_hash) - }) - .await - } - - /// Does exactly the same as `submit_signed_extrinsic`, but keeps watching for extrinsic status - /// after submission. - pub async fn submit_and_watch_signed_extrinsic( - &self, - extrinsic_signer: C::AccountId, - prepare_extrinsic: impl FnOnce(HeaderIdOf, C::Index) -> Result + Send + 'static, - ) -> Result>> { - let _guard = self.submit_signed_extrinsic_lock.lock().await; - let transaction_nonce = self.next_account_index(extrinsic_signer).await?; - let best_header = self.best_header().await?; - let best_header_id = HeaderId(*best_header.number(), best_header.hash()); - let subscription = self - .jsonrpsee_execute(move |client| async move { - let extrinsic = prepare_extrinsic(best_header_id, transaction_nonce)?; - let tx_hash = C::Hasher::hash(&extrinsic.0); - let subscription = client - .subscribe( - "author_submitAndWatchExtrinsic", - Some(ParamsSer::Array(vec![jsonrpsee::core::to_json_value(extrinsic) - .map_err(|e| Error::RpcError(e.into()))?])), - "author_unwatchExtrinsic", - ) - .await?; - log::trace!(target: "bridge", "Sent transaction to {} node: {:?}", C::NAME, tx_hash); - Ok(subscription) - }) - .await?; - let (sender, receiver) = futures::channel::mpsc::channel(MAX_SUBSCRIPTION_CAPACITY); - self.tokio.spawn(Subscription::background_worker( - C::NAME.into(), - "extrinsic".into(), - subscription, - sender, - )); - Ok(Subscription(Mutex::new(receiver))) - } - - /// Returns pending extrinsics from transaction pool. - pub async fn pending_extrinsics(&self) -> Result> { - self.jsonrpsee_execute(move |client| async move { - Ok(SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::author_pending_extrinsics(&*client) - .await?) - }) - .await - } - - /// Validate transaction at given block state. - pub async fn validate_transaction( - &self, - at_block: C::Hash, - transaction: SignedTransaction, - ) -> Result { - self.jsonrpsee_execute(move |client| async move { - let call = SUB_API_TXPOOL_VALIDATE_TRANSACTION.to_string(); - let data = Bytes((TransactionSource::External, transaction, at_block).encode()); - - let encoded_response = SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::state_call(&*client, call, data, Some(at_block)) - .await?; - let validity = TransactionValidity::decode(&mut &encoded_response.0[..]) - .map_err(Error::ResponseParseFailed)?; - - Ok(validity) - }) - .await - } - - /// Estimate fee that will be spent on given extrinsic. - pub async fn estimate_extrinsic_fee( - &self, - transaction: Bytes, - ) -> Result> { - self.jsonrpsee_execute(move |client| async move { - let fee_details = SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::payment_query_fee_details(&*client, transaction, None) - .await?; - let inclusion_fee = fee_details - .inclusion_fee - .map(|inclusion_fee| InclusionFee { - base_fee: C::Balance::try_from(inclusion_fee.base_fee.into_u256()) - .unwrap_or_else(|_| C::Balance::max_value()), - len_fee: C::Balance::try_from(inclusion_fee.len_fee.into_u256()) - .unwrap_or_else(|_| C::Balance::max_value()), - adjusted_weight_fee: C::Balance::try_from( - inclusion_fee.adjusted_weight_fee.into_u256(), - ) - .unwrap_or_else(|_| C::Balance::max_value()), - }) - .unwrap_or_else(|| InclusionFee { - base_fee: Zero::zero(), - len_fee: Zero::zero(), - adjusted_weight_fee: Zero::zero(), - }); - Ok(inclusion_fee) - }) - .await - } - - /// Get the GRANDPA authority set at given block. - pub async fn grandpa_authorities_set( - &self, - block: C::Hash, - ) -> Result { - self.jsonrpsee_execute(move |client| async move { - let call = SUB_API_GRANDPA_AUTHORITIES.to_string(); - let data = Bytes(Vec::new()); - - let encoded_response = SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::state_call(&*client, call, data, Some(block)) - .await?; - let authority_list = encoded_response.0; - - Ok(authority_list) - }) - .await - } - - /// Execute runtime call at given block. - pub async fn state_call( - &self, - method: String, - data: Bytes, - at_block: Option, - ) -> Result { - self.jsonrpsee_execute(move |client| async move { - SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::state_call(&*client, method, data, at_block) - .await - .map_err(Into::into) - }) - .await - } - - /// Returns storage proof of given storage keys. - pub async fn prove_storage( - &self, - keys: Vec, - at_block: C::Hash, - ) -> Result { - self.jsonrpsee_execute(move |client| async move { - SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::state_prove_storage(&*client, keys, Some(at_block)) - .await - .map(|proof| { - StorageProof::new(proof.proof.into_iter().map(|b| b.0).collect::>()) - }) - .map_err(Into::into) - }) - .await - } - - /// Return `tokenDecimals` property from the set of chain properties. - pub async fn token_decimals(&self) -> Result> { - self.jsonrpsee_execute(move |client| async move { - let system_properties = SubstrateClient::< - AccountIdOf, - BlockNumberOf, - HashOf, - HeaderOf, - IndexOf, - C::SignedBlock, - >::system_properties(&*client) - .await?; - Ok(system_properties.get("tokenDecimals").and_then(|v| v.as_u64())) - }) - .await - } - - /// Return new justifications stream. - pub async fn subscribe_justifications(&self) -> Result> { - let subscription = self - .jsonrpsee_execute(move |client| async move { - Ok(client - .subscribe( - "grandpa_subscribeJustifications", - None, - "grandpa_unsubscribeJustifications", - ) - .await?) - }) - .await?; - let (sender, receiver) = futures::channel::mpsc::channel(MAX_SUBSCRIPTION_CAPACITY); - self.tokio.spawn(Subscription::background_worker( - C::NAME.into(), - "justification".into(), - subscription, - sender, - )); - Ok(Subscription(Mutex::new(receiver))) - } - - /// Execute jsonrpsee future in tokio context. - async fn jsonrpsee_execute(&self, make_jsonrpsee_future: MF) -> Result - where - MF: FnOnce(Arc) -> F + Send + 'static, - F: Future> + Send, - T: Send + 'static, - { - let client = self.client.clone(); - self.tokio.spawn(async move { make_jsonrpsee_future(client).await }).await? - } -} - -impl Subscription { - /// Return next item from the subscription. - pub async fn next(&self) -> Result> { - let mut receiver = self.0.lock().await; - let item = receiver.next().await; - Ok(item.unwrap_or(None)) - } - - /// Background worker that is executed in tokio context as `jsonrpsee` requires. - async fn background_worker( - chain_name: String, - item_type: String, - mut subscription: jsonrpsee::core::client::Subscription, - mut sender: futures::channel::mpsc::Sender>, - ) { - loop { - match subscription.next().await { - Some(Ok(item)) => - if sender.send(Some(item)).await.is_err() { - break; - }, - Some(Err(e)) => { - log::trace!( - target: "bridge", - "{} {} subscription stream has returned '{:?}'. Stream needs to be restarted.", - chain_name, - item_type, - e, - ); - let _ = sender.send(None).await; - break; - }, - None => { - log::trace!( - target: "bridge", - "{} {} subscription stream has returned None. Stream needs to be restarted.", - chain_name, - item_type, - ); - let _ = sender.send(None).await; - break; - }, - } - } - } -} diff --git a/relays/client-substrate/src/error.rs b/relays/client-substrate/src/error.rs deleted file mode 100644 index e698f2596..000000000 --- a/relays/client-substrate/src/error.rs +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Substrate node RPC errors. - -use jsonrpsee::core::Error as RpcError; -use relay_utils::MaybeConnectionError; -use sc_rpc_api::system::Health; -use sp_runtime::transaction_validity::TransactionValidityError; -use thiserror::Error; - -/// Result type used by Substrate client. -pub type Result = std::result::Result; - -/// Errors that can occur only when interacting with -/// a Substrate node through RPC. -#[derive(Error, Debug)] -pub enum Error { - /// IO error. - #[error("IO error: {0}")] - Io(#[from] std::io::Error), - /// An error that can occur when making a request to - /// an JSON-RPC server. - #[error("RPC error: {0}")] - RpcError(#[from] RpcError), - /// The response from the server could not be SCALE decoded. - #[error("Response parse failed: {0}")] - ResponseParseFailed(#[from] codec::Error), - /// The Substrate bridge pallet has not yet been initialized. - #[error("The Substrate bridge pallet has not been initialized yet.")] - UninitializedBridgePallet, - /// Account does not exist on the chain. - #[error("Account does not exist on the chain.")] - AccountDoesNotExist, - /// Runtime storage is missing mandatory ":code:" entry. - #[error("Mandatory :code: entry is missing from runtime storage.")] - MissingMandatoryCodeEntry, - /// The client we're connected to is not synced, so we can't rely on its state. - #[error("Substrate client is not synced {0}.")] - ClientNotSynced(Health), - /// The bridge pallet is halted and all transactions will be rejected. - #[error("Bridge pallet is halted.")] - BridgePalletIsHalted, - /// An error has happened when we have tried to parse storage proof. - #[error("Error when parsing storage proof: {0:?}.")] - StorageProofError(bp_runtime::StorageProofError), - /// The Substrate transaction is invalid. - #[error("Substrate transaction is invalid: {0:?}")] - TransactionInvalid(#[from] TransactionValidityError), - /// Custom logic error. - #[error("{0}")] - Custom(String), -} - -impl From for Error { - fn from(error: tokio::task::JoinError) -> Self { - Error::Custom(format!("Failed to wait tokio task: {}", error)) - } -} - -impl MaybeConnectionError for Error { - fn is_connection_error(&self) -> bool { - matches!( - *self, - Error::RpcError(RpcError::Transport(_)) - // right now if connection to the ws server is dropped (after it is already established), - // we're getting this error - | Error::RpcError(RpcError::Internal(_)) - | Error::RpcError(RpcError::RestartNeeded(_)) - | Error::ClientNotSynced(_), - ) - } -} diff --git a/relays/client-substrate/src/guard.rs b/relays/client-substrate/src/guard.rs deleted file mode 100644 index e1f9b0d31..000000000 --- a/relays/client-substrate/src/guard.rs +++ /dev/null @@ -1,415 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Pallet provides a set of guard functions that are running in background threads -//! and are aborting process if some condition fails. - -use crate::{error::Error, Chain, ChainWithBalances, Client}; - -use async_trait::async_trait; -use num_traits::CheckedSub; -use sp_version::RuntimeVersion; -use std::{ - collections::VecDeque, - fmt::Display, - time::{Duration, Instant}, -}; - -/// Guards environment. -#[async_trait] -pub trait Environment: Send + Sync + 'static { - /// Error type. - type Error: Display + Send + Sync + 'static; - - /// Return current runtime version. - async fn runtime_version(&mut self) -> Result; - /// Return free native balance of the account on the chain. - async fn free_native_balance( - &mut self, - account: C::AccountId, - ) -> Result; - - /// Return current time. - fn now(&self) -> Instant { - Instant::now() - } - - /// Sleep given amount of time. - async fn sleep(&mut self, duration: Duration) { - async_std::task::sleep(duration).await - } - - /// Abort current process. Called when guard condition check fails. - async fn abort(&mut self) { - std::process::abort(); - } -} - -/// Abort when runtime spec version is different from specified. -pub fn abort_on_spec_version_change( - mut env: impl Environment, - expected_spec_version: u32, -) { - async_std::task::spawn(async move { - log::info!( - target: "bridge-guard", - "Starting spec_version guard for {}. Expected spec_version: {}", - C::NAME, - expected_spec_version, - ); - - loop { - let actual_spec_version = env.runtime_version().await; - match actual_spec_version { - Ok(version) if version.spec_version == expected_spec_version => (), - Ok(version) => { - log::error!( - target: "bridge-guard", - "{} runtime spec version has changed from {} to {}. Aborting relay", - C::NAME, - expected_spec_version, - version.spec_version, - ); - - env.abort().await; - }, - Err(error) => log::warn!( - target: "bridge-guard", - "Failed to read {} runtime version: {}. Relay may need to be stopped manually", - C::NAME, - error, - ), - } - - env.sleep(conditions_check_delay::()).await; - } - }); -} - -/// Abort if, during 24 hours, free balance of given account is decreased at least by given value. -/// Other components may increase (or decrease) balance of account and it WILL affect logic of the -/// guard. -pub fn abort_when_account_balance_decreased( - mut env: impl Environment, - account_id: C::AccountId, - maximal_decrease: C::Balance, -) { - const DAY: Duration = Duration::from_secs(60 * 60 * 24); - - async_std::task::spawn(async move { - log::info!( - target: "bridge-guard", - "Starting balance guard for {}/{:?}. Maximal decrease: {:?}", - C::NAME, - account_id, - maximal_decrease, - ); - - let mut balances = VecDeque::new(); - - loop { - let current_time = env.now(); - - // remember balances that are beyound 24h border - let time_border = current_time - DAY; - while balances.front().map(|(time, _)| *time < time_border).unwrap_or(false) { - balances.pop_front(); - } - - // read balance of the account - let current_balance = env.free_native_balance(account_id.clone()).await; - - // remember balance and check difference - match current_balance { - Ok(current_balance) => { - // remember balance - balances.push_back((current_time, current_balance)); - - // check if difference between current and oldest balance is too large - let (oldest_time, oldest_balance) = - balances.front().expect("pushed to queue couple of lines above; qed"); - let balances_difference = oldest_balance.checked_sub(¤t_balance); - if balances_difference > Some(maximal_decrease) { - log::error!( - target: "bridge-guard", - "Balance of {} account {:?} has decreased from {:?} to {:?} in {} minutes. Aborting relay", - C::NAME, - account_id, - oldest_balance, - current_balance, - current_time.duration_since(*oldest_time).as_secs() / 60, - ); - - env.abort().await; - } - }, - Err(error) => { - log::warn!( - target: "bridge-guard", - "Failed to read {} account {:?} balance: {}. Relay may need to be stopped manually", - C::NAME, - account_id, - error, - ); - }, - }; - - env.sleep(conditions_check_delay::()).await; - } - }); -} - -/// Delay between conditions check. -fn conditions_check_delay() -> Duration { - C::AVERAGE_BLOCK_INTERVAL * (10 + rand::random::() % 10) -} - -#[async_trait] -impl Environment for Client { - type Error = Error; - - async fn runtime_version(&mut self) -> Result { - Client::::runtime_version(self).await - } - - async fn free_native_balance( - &mut self, - account: C::AccountId, - ) -> Result { - Client::::free_native_balance(self, account).await - } -} - -#[cfg(test)] -mod tests { - use super::*; - use frame_support::weights::{IdentityFee, Weight}; - use futures::{ - channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}, - future::FutureExt, - stream::StreamExt, - SinkExt, - }; - - #[derive(Debug, Clone)] - struct TestChain; - - impl bp_runtime::Chain for TestChain { - type AccountId = u32; - type Balance = u32; - type BlockNumber = u32; - type Hash = sp_core::H256; - type Hasher = sp_runtime::traits::BlakeTwo256; - type Header = sp_runtime::generic::Header; - type Index = u32; - type Signature = sp_runtime::testing::TestSignature; - - fn max_extrinsic_size() -> u32 { - unreachable!() - } - - fn max_extrinsic_weight() -> Weight { - unreachable!() - } - } - - impl Chain for TestChain { - type Call = (); - type SignedBlock = sp_runtime::generic::SignedBlock< - sp_runtime::generic::Block, - >; - type WeightToFee = IdentityFee; - - const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_millis(1); - const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = "BestTestHeader"; - const MAXIMAL_ENCODED_ACCOUNT_ID_SIZE: u32 = 0; - const NAME: &'static str = "Test"; - const STORAGE_PROOF_OVERHEAD: u32 = 0; - const TOKEN_ID: Option<&'static str> = None; - } - - impl ChainWithBalances for TestChain { - fn account_info_storage_key(_account_id: &u32) -> sp_core::storage::StorageKey { - unreachable!() - } - } - - struct TestEnvironment { - runtime_version_rx: UnboundedReceiver, - free_native_balance_rx: UnboundedReceiver, - slept_tx: UnboundedSender<()>, - aborted_tx: UnboundedSender<()>, - } - - #[async_trait] - impl Environment for TestEnvironment { - type Error = Error; - - async fn runtime_version(&mut self) -> Result { - Ok(self.runtime_version_rx.next().await.unwrap_or_default()) - } - - async fn free_native_balance(&mut self, _account: u32) -> Result { - Ok(self.free_native_balance_rx.next().await.unwrap_or_default()) - } - - async fn sleep(&mut self, _duration: Duration) { - let _ = self.slept_tx.send(()).await; - } - - async fn abort(&mut self) { - let _ = self.aborted_tx.send(()).await; - // simulate process abort :) - async_std::task::sleep(Duration::from_secs(60)).await; - } - } - - #[test] - fn aborts_when_spec_version_is_changed() { - async_std::task::block_on(async { - let ( - (mut runtime_version_tx, runtime_version_rx), - (_free_native_balance_tx, free_native_balance_rx), - (slept_tx, mut slept_rx), - (aborted_tx, mut aborted_rx), - ) = (unbounded(), unbounded(), unbounded(), unbounded()); - abort_on_spec_version_change( - TestEnvironment { - runtime_version_rx, - free_native_balance_rx, - slept_tx, - aborted_tx, - }, - 0, - ); - - // client responds with wrong version - runtime_version_tx - .send(RuntimeVersion { spec_version: 42, ..Default::default() }) - .await - .unwrap(); - - // then the `abort` function is called - aborted_rx.next().await; - // and we do not reach the `sleep` function call - assert!(slept_rx.next().now_or_never().is_none()); - }); - } - - #[test] - fn does_not_aborts_when_spec_version_is_unchanged() { - async_std::task::block_on(async { - let ( - (mut runtime_version_tx, runtime_version_rx), - (_free_native_balance_tx, free_native_balance_rx), - (slept_tx, mut slept_rx), - (aborted_tx, mut aborted_rx), - ) = (unbounded(), unbounded(), unbounded(), unbounded()); - abort_on_spec_version_change( - TestEnvironment { - runtime_version_rx, - free_native_balance_rx, - slept_tx, - aborted_tx, - }, - 42, - ); - - // client responds with the same version - runtime_version_tx - .send(RuntimeVersion { spec_version: 42, ..Default::default() }) - .await - .unwrap(); - - // then the `sleep` function is called - slept_rx.next().await; - // and the `abort` function is not called - assert!(aborted_rx.next().now_or_never().is_none()); - }); - } - - #[test] - fn aborts_when_balance_is_too_low() { - async_std::task::block_on(async { - let ( - (_runtime_version_tx, runtime_version_rx), - (mut free_native_balance_tx, free_native_balance_rx), - (slept_tx, mut slept_rx), - (aborted_tx, mut aborted_rx), - ) = (unbounded(), unbounded(), unbounded(), unbounded()); - abort_when_account_balance_decreased( - TestEnvironment { - runtime_version_rx, - free_native_balance_rx, - slept_tx, - aborted_tx, - }, - 0, - 100, - ); - - // client responds with initial balance - free_native_balance_tx.send(1000).await.unwrap(); - - // then the guard sleeps - slept_rx.next().await; - - // and then client responds with updated balance, which is too low - free_native_balance_tx.send(899).await.unwrap(); - - // then the `abort` function is called - aborted_rx.next().await; - // and we do not reach next `sleep` function call - assert!(slept_rx.next().now_or_never().is_none()); - }); - } - - #[test] - fn does_not_aborts_when_balance_is_enough() { - async_std::task::block_on(async { - let ( - (_runtime_version_tx, runtime_version_rx), - (mut free_native_balance_tx, free_native_balance_rx), - (slept_tx, mut slept_rx), - (aborted_tx, mut aborted_rx), - ) = (unbounded(), unbounded(), unbounded(), unbounded()); - abort_when_account_balance_decreased( - TestEnvironment { - runtime_version_rx, - free_native_balance_rx, - slept_tx, - aborted_tx, - }, - 0, - 100, - ); - - // client responds with initial balance - free_native_balance_tx.send(1000).await.unwrap(); - - // then the guard sleeps - slept_rx.next().await; - - // and then client responds with updated balance, which is enough - free_native_balance_tx.send(950).await.unwrap(); - - // then the `sleep` function is called - slept_rx.next().await; - // and `abort` is not called - assert!(aborted_rx.next().now_or_never().is_none()); - }); - } -} diff --git a/relays/client-substrate/src/lib.rs b/relays/client-substrate/src/lib.rs deleted file mode 100644 index b3a7ec414..000000000 --- a/relays/client-substrate/src/lib.rs +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Tools to interact with Substrate node using RPC methods. - -#![warn(missing_docs)] - -mod chain; -mod client; -mod error; -mod rpc; -mod sync_header; - -pub mod guard; -pub mod metrics; - -use std::time::Duration; - -pub use crate::{ - chain::{ - AccountKeyPairOf, BlockWithJustification, CallOf, Chain, ChainWithBalances, - ChainWithGrandpa, ChainWithMessages, SignParam, TransactionSignScheme, TransactionStatusOf, - UnsignedTransaction, WeightToFeeOf, - }, - client::{ChainRuntimeVersion, Client, OpaqueGrandpaAuthoritiesSet, Subscription}, - error::{Error, Result}, - sync_header::SyncHeader, -}; -pub use bp_runtime::{ - AccountIdOf, AccountPublicOf, BalanceOf, BlockNumberOf, Chain as ChainBase, HashOf, HeaderOf, - IndexOf, SignatureOf, TransactionEra, TransactionEraOf, -}; - -/// Header id used by the chain. -pub type HeaderIdOf = relay_utils::HeaderId, BlockNumberOf>; - -/// Substrate-over-websocket connection params. -#[derive(Debug, Clone)] -pub struct ConnectionParams { - /// Websocket server host name. - pub host: String, - /// Websocket server TCP port. - pub port: u16, - /// Use secure websocket connection. - pub secure: bool, - /// Defined chain runtime version - pub chain_runtime_version: ChainRuntimeVersion, -} - -impl Default for ConnectionParams { - fn default() -> Self { - ConnectionParams { - host: "localhost".into(), - port: 9944, - secure: false, - chain_runtime_version: ChainRuntimeVersion::Auto, - } - } -} - -/// Returns stall timeout for relay loop. -/// -/// Relay considers himself stalled if he has submitted transaction to the node, but it has not -/// been mined for this period. -pub fn transaction_stall_timeout( - mortality_period: Option, - average_block_interval: Duration, - default_stall_timeout: Duration, -) -> Duration { - // 1 extra block for transaction to reach the pool && 1 for relayer to awake after it is mined - mortality_period - .map(|mortality_period| average_block_interval.saturating_mul(mortality_period + 1 + 1)) - .unwrap_or(default_stall_timeout) -} - -/// Returns stall timeout for relay loop that submit transactions to two chains. -/// -/// Bidirectional relay may have two active transactions. Even if one of them has been spoiled, we -/// can't just restart the loop - the other transaction may still be alive and we'll be submitting -/// duplicate transaction, which may result in funds loss. So we'll be selecting maximal mortality -/// for choosing loop stall timeout. -pub fn bidirectional_transaction_stall_timeout( - left_mortality_period: Option, - right_mortality_period: Option, - left_average_block_interval: Duration, - right_average_block_interval: Duration, - default_stall_timeout: Duration, -) -> Duration { - std::cmp::max( - transaction_stall_timeout( - left_mortality_period, - left_average_block_interval, - default_stall_timeout, - ), - transaction_stall_timeout( - right_mortality_period, - right_average_block_interval, - default_stall_timeout, - ), - ) -} diff --git a/relays/client-substrate/src/metrics/float_storage_value.rs b/relays/client-substrate/src/metrics/float_storage_value.rs deleted file mode 100644 index 7b5c56e1e..000000000 --- a/relays/client-substrate/src/metrics/float_storage_value.rs +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -use crate::{chain::Chain, client::Client, Error as SubstrateError}; - -use async_std::sync::{Arc, RwLock}; -use async_trait::async_trait; -use codec::Decode; -use num_traits::One; -use relay_utils::metrics::{ - metric_name, register, F64SharedRef, Gauge, Metric, PrometheusError, Registry, - StandaloneMetric, F64, -}; -use sp_core::storage::{StorageData, StorageKey}; -use sp_runtime::{traits::UniqueSaturatedInto, FixedPointNumber, FixedU128}; -use std::{marker::PhantomData, time::Duration}; - -/// Storage value update interval (in blocks). -const UPDATE_INTERVAL_IN_BLOCKS: u32 = 5; - -/// Fied-point storage value and the way it is decoded from the raw storage value. -pub trait FloatStorageValue: 'static + Clone + Send + Sync { - /// Type of the value. - type Value: FixedPointNumber; - /// Try to decode value from the raw storage value. - fn decode( - &self, - maybe_raw_value: Option, - ) -> Result, SubstrateError>; -} - -/// Implementation of `FloatStorageValue` that expects encoded `FixedU128` value and returns `1` if -/// value is missing from the storage. -#[derive(Clone, Debug, Default)] -pub struct FixedU128OrOne; - -impl FloatStorageValue for FixedU128OrOne { - type Value = FixedU128; - - fn decode( - &self, - maybe_raw_value: Option, - ) -> Result, SubstrateError> { - maybe_raw_value - .map(|raw_value| { - FixedU128::decode(&mut &raw_value.0[..]) - .map_err(SubstrateError::ResponseParseFailed) - .map(Some) - }) - .unwrap_or_else(|| Ok(Some(FixedU128::one()))) - } -} - -/// Metric that represents fixed-point runtime storage value as float gauge. -#[derive(Clone, Debug)] -pub struct FloatStorageValueMetric { - value_converter: V, - client: Client, - storage_key: StorageKey, - metric: Gauge, - shared_value_ref: F64SharedRef, - _phantom: PhantomData, -} - -impl FloatStorageValueMetric { - /// Create new metric. - pub fn new( - value_converter: V, - client: Client, - storage_key: StorageKey, - name: String, - help: String, - ) -> Result { - let shared_value_ref = Arc::new(RwLock::new(None)); - Ok(FloatStorageValueMetric { - value_converter, - client, - storage_key, - metric: Gauge::new(metric_name(None, &name), help)?, - shared_value_ref, - _phantom: Default::default(), - }) - } - - /// Get shared reference to metric value. - pub fn shared_value_ref(&self) -> F64SharedRef { - self.shared_value_ref.clone() - } -} - -impl Metric for FloatStorageValueMetric { - fn register(&self, registry: &Registry) -> Result<(), PrometheusError> { - register(self.metric.clone(), registry).map(drop) - } -} - -#[async_trait] -impl StandaloneMetric for FloatStorageValueMetric { - fn update_interval(&self) -> Duration { - C::AVERAGE_BLOCK_INTERVAL * UPDATE_INTERVAL_IN_BLOCKS - } - - async fn update(&self) { - let value = self - .client - .raw_storage_value(self.storage_key.clone(), None) - .await - .and_then(|maybe_storage_value| { - self.value_converter.decode(maybe_storage_value).map(|maybe_fixed_point_value| { - maybe_fixed_point_value.map(|fixed_point_value| { - fixed_point_value.into_inner().unique_saturated_into() as f64 - / V::Value::DIV.unique_saturated_into() as f64 - }) - }) - }) - .map_err(|e| e.to_string()); - relay_utils::metrics::set_gauge_value(&self.metric, value.clone()); - *self.shared_value_ref.write().await = value.ok().and_then(|x| x); - } -} diff --git a/relays/client-substrate/src/metrics/mod.rs b/relays/client-substrate/src/metrics/mod.rs deleted file mode 100644 index 3b63099e0..000000000 --- a/relays/client-substrate/src/metrics/mod.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Contains several Substrate-specific metrics that may be exposed by relay. - -pub use float_storage_value::{FixedU128OrOne, FloatStorageValue, FloatStorageValueMetric}; -pub use storage_proof_overhead::StorageProofOverheadMetric; - -mod float_storage_value; -mod storage_proof_overhead; diff --git a/relays/client-substrate/src/metrics/storage_proof_overhead.rs b/relays/client-substrate/src/metrics/storage_proof_overhead.rs deleted file mode 100644 index ec3f7ffa0..000000000 --- a/relays/client-substrate/src/metrics/storage_proof_overhead.rs +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -use crate::{chain::Chain, client::Client, error::Error}; - -use async_trait::async_trait; -use relay_utils::metrics::{ - metric_name, register, Gauge, Metric, PrometheusError, Registry, StandaloneMetric, U64, -}; -use sp_core::storage::StorageKey; -use sp_runtime::traits::Header as HeaderT; -use sp_storage::well_known_keys::CODE; -use std::time::Duration; - -/// Storage proof overhead update interval (in blocks). -const UPDATE_INTERVAL_IN_BLOCKS: u32 = 100; - -/// Metric that represents extra size of storage proof as unsigned integer gauge. -/// -/// There's one thing to keep in mind when using this metric: the overhead may be slightly -/// different for other values, but this metric gives a good estimation. -#[derive(Debug)] -pub struct StorageProofOverheadMetric { - client: Client, - metric: Gauge, -} - -impl Clone for StorageProofOverheadMetric { - fn clone(&self) -> Self { - StorageProofOverheadMetric { client: self.client.clone(), metric: self.metric.clone() } - } -} - -impl StorageProofOverheadMetric { - /// Create new metric instance with given name and help. - pub fn new(client: Client, name: String, help: String) -> Result { - Ok(StorageProofOverheadMetric { - client, - metric: Gauge::new(metric_name(None, &name), help)?, - }) - } - - /// Returns approximate storage proof size overhead. - async fn compute_storage_proof_overhead(&self) -> Result { - let best_header_hash = self.client.best_finalized_header_hash().await?; - let best_header = self.client.header_by_hash(best_header_hash).await?; - - let storage_proof = - self.client.prove_storage(vec![StorageKey(CODE.to_vec())], best_header_hash).await?; - let storage_proof_size: usize = storage_proof.clone().iter_nodes().map(|n| n.len()).sum(); - - let storage_value_reader = bp_runtime::StorageProofChecker::::new( - *best_header.state_root(), - storage_proof, - ) - .map_err(Error::StorageProofError)?; - let maybe_encoded_storage_value = - storage_value_reader.read_value(CODE).map_err(Error::StorageProofError)?; - let encoded_storage_value_size = - maybe_encoded_storage_value.ok_or(Error::MissingMandatoryCodeEntry)?.len(); - - Ok(storage_proof_size - encoded_storage_value_size) - } -} - -impl Metric for StorageProofOverheadMetric { - fn register(&self, registry: &Registry) -> Result<(), PrometheusError> { - register(self.metric.clone(), registry).map(drop) - } -} - -#[async_trait] -impl StandaloneMetric for StorageProofOverheadMetric { - fn update_interval(&self) -> Duration { - C::AVERAGE_BLOCK_INTERVAL * UPDATE_INTERVAL_IN_BLOCKS - } - - async fn update(&self) { - relay_utils::metrics::set_gauge_value( - &self.metric, - self.compute_storage_proof_overhead().await.map(|overhead| Some(overhead as u64)), - ); - } -} diff --git a/relays/client-substrate/src/rpc.rs b/relays/client-substrate/src/rpc.rs deleted file mode 100644 index a0172d1e5..000000000 --- a/relays/client-substrate/src/rpc.rs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! The most generic Substrate node RPC interface. - -use jsonrpsee::{core::RpcResult, proc_macros::rpc}; -use pallet_transaction_payment_rpc_runtime_api::FeeDetails; -use sc_rpc_api::{state::ReadProof, system::Health}; -use sp_core::{ - storage::{StorageData, StorageKey}, - Bytes, -}; -use sp_rpc::number::NumberOrHex; -use sp_version::RuntimeVersion; - -#[rpc(client)] -pub(crate) trait Substrate { - #[method(name = "system_health", param_kind = array)] - async fn system_health(&self) -> RpcResult; - #[method(name = "system_properties", param_kind = array)] - async fn system_properties(&self) -> RpcResult; - #[method(name = "chain_getHeader", param_kind = array)] - async fn chain_get_header(&self, block_hash: Option) -> RpcResult
; - #[method(name = "chain_getFinalizedHead", param_kind = array)] - async fn chain_get_finalized_head(&self) -> RpcResult; - #[method(name = "chain_getBlock", param_kind = array)] - async fn chain_get_block(&self, block_hash: Option) -> RpcResult; - #[method(name = "chain_getBlockHash", param_kind = array)] - async fn chain_get_block_hash(&self, block_number: Option) -> RpcResult; - #[method(name = "system_accountNextIndex", param_kind = array)] - async fn system_account_next_index(&self, account_id: AccountId) -> RpcResult; - #[method(name = "author_submitExtrinsic", param_kind = array)] - async fn author_submit_extrinsic(&self, extrinsic: Bytes) -> RpcResult; - #[method(name = "author_pendingExtrinsics", param_kind = array)] - async fn author_pending_extrinsics(&self) -> RpcResult>; - #[method(name = "state_call", param_kind = array)] - async fn state_call( - &self, - method: String, - data: Bytes, - at_block: Option, - ) -> RpcResult; - #[method(name = "state_getStorage", param_kind = array)] - async fn state_get_storage( - &self, - key: StorageKey, - at_block: Option, - ) -> RpcResult>; - #[method(name = "state_getReadProof", param_kind = array)] - async fn state_prove_storage( - &self, - keys: Vec, - hash: Option, - ) -> RpcResult>; - #[method(name = "state_getRuntimeVersion", param_kind = array)] - async fn state_runtime_version(&self) -> RpcResult; - #[method(name = "payment_queryFeeDetails", param_kind = array)] - async fn payment_query_fee_details( - &self, - extrinsic: Bytes, - at_block: Option, - ) -> RpcResult>; -} diff --git a/relays/client-substrate/src/sync_header.rs b/relays/client-substrate/src/sync_header.rs deleted file mode 100644 index e45e6b419..000000000 --- a/relays/client-substrate/src/sync_header.rs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -use bp_header_chain::find_grandpa_authorities_scheduled_change; -use finality_relay::SourceHeader as FinalitySourceHeader; -use sp_runtime::traits::Header as HeaderT; - -/// Generic wrapper for `sp_runtime::traits::Header` based headers, that -/// implements `finality_relay::SourceHeader` and may be used in headers sync directly. -#[derive(Clone, Debug, PartialEq)] -pub struct SyncHeader
(Header); - -impl
SyncHeader
{ - /// Extracts wrapped header from self. - pub fn into_inner(self) -> Header { - self.0 - } -} - -impl
std::ops::Deref for SyncHeader
{ - type Target = Header; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl
From
for SyncHeader
{ - fn from(header: Header) -> Self { - Self(header) - } -} - -impl FinalitySourceHeader for SyncHeader
{ - fn hash(&self) -> Header::Hash { - self.0.hash() - } - - fn number(&self) -> Header::Number { - *self.0.number() - } - - fn is_mandatory(&self) -> bool { - find_grandpa_authorities_scheduled_change(&self.0).is_some() - } -} diff --git a/relays/finality/Cargo.toml b/relays/finality/Cargo.toml deleted file mode 100644 index cc5ae54be..000000000 --- a/relays/finality/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "finality-relay" -version = "0.1.0" -authors = ["Parity Technologies "] -edition = "2021" -license = "GPL-3.0-or-later WITH Classpath-exception-2.0" -description = "Finality proofs relay" - -[dependencies] -async-std = "1.6.5" -async-trait = "0.1.40" -backoff = "0.2" -bp-header-chain = { path = "../../primitives/header-chain" } -futures = "0.3.5" -log = "0.4.11" -num-traits = "0.2" -relay-utils = { path = "../utils" } - -[dev-dependencies] -parking_lot = "0.11.0" diff --git a/relays/finality/src/finality_loop.rs b/relays/finality/src/finality_loop.rs deleted file mode 100644 index c1ba3410d..000000000 --- a/relays/finality/src/finality_loop.rs +++ /dev/null @@ -1,689 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! The loop basically reads all missing headers and their finality proofs from the source client. -//! The proof for the best possible header is then submitted to the target node. The only exception -//! is the mandatory headers, which we always submit to the target node. For such headers, we -//! assume that the persistent proof either exists, or will eventually become available. - -use crate::{ - sync_loop_metrics::SyncLoopMetrics, FinalityProof, FinalitySyncPipeline, SourceHeader, -}; - -use async_trait::async_trait; -use backoff::backoff::Backoff; -use futures::{select, Future, FutureExt, Stream, StreamExt}; -use num_traits::{One, Saturating}; -use relay_utils::{ - metrics::MetricsParams, relay_loop::Client as RelayClient, retry_backoff, FailedClient, - HeaderId, MaybeConnectionError, -}; -use std::{ - pin::Pin, - time::{Duration, Instant}, -}; - -/// Finality proof synchronization loop parameters. -#[derive(Debug, Clone)] -pub struct FinalitySyncParams { - /// Interval at which we check updates on both clients. Normally should be larger than - /// `min(source_block_time, target_block_time)`. - /// - /// This parameter may be used to limit transactions rate. Increase the value && you'll get - /// infrequent updates => sparse headers => potential slow down of bridge applications, but - /// pallet storage won't be super large. Decrease the value to near `source_block_time` and - /// you'll get transaction for (almost) every block of the source chain => all source headers - /// will be known to the target chain => bridge applications will run faster, but pallet - /// storage may explode (but if pruning is there, then it's fine). - pub tick: Duration, - /// Number of finality proofs to keep in internal buffer between loop iterations. - /// - /// While in "major syncing" state, we still read finality proofs from the stream. They're - /// stored in the internal buffer between loop iterations. When we're close to the tip of the - /// chain, we may meet finality delays if headers are not finalized frequently. So instead of - /// waiting for next finality proof to appear in the stream, we may use existing proof from - /// that buffer. - pub recent_finality_proofs_limit: usize, - /// Timeout before we treat our transactions as lost and restart the whole sync process. - pub stall_timeout: Duration, - /// If true, only mandatory headers are relayed. - pub only_mandatory_headers: bool, -} - -/// Source client used in finality synchronization loop. -#[async_trait] -pub trait SourceClient: RelayClient { - /// Stream of new finality proofs. The stream is allowed to miss proofs for some - /// headers, even if those headers are mandatory. - type FinalityProofsStream: Stream + Send; - - /// Get best finalized block number. - async fn best_finalized_block_number(&self) -> Result; - - /// Get canonical header and its finality proof by number. - async fn header_and_finality_proof( - &self, - number: P::Number, - ) -> Result<(P::Header, Option), Self::Error>; - - /// Subscribe to new finality proofs. - async fn finality_proofs(&self) -> Result; -} - -/// Target client used in finality synchronization loop. -#[async_trait] -pub trait TargetClient: RelayClient { - /// Get best finalized source block number. - async fn best_finalized_source_block_id( - &self, - ) -> Result, Self::Error>; - - /// Submit header finality proof. - async fn submit_finality_proof( - &self, - header: P::Header, - proof: P::FinalityProof, - ) -> Result<(), Self::Error>; -} - -/// Return prefix that will be used by default to expose Prometheus metrics of the finality proofs -/// sync loop. -pub fn metrics_prefix() -> String { - format!("{}_to_{}_Sync", P::SOURCE_NAME, P::TARGET_NAME) -} - -/// Run finality proofs synchronization loop. -pub async fn run( - source_client: impl SourceClient

, - target_client: impl TargetClient

, - sync_params: FinalitySyncParams, - metrics_params: MetricsParams, - exit_signal: impl Future + 'static + Send, -) -> Result<(), relay_utils::Error> { - let exit_signal = exit_signal.shared(); - relay_utils::relay_loop(source_client, target_client) - .with_metrics(metrics_params) - .loop_metric(SyncLoopMetrics::new( - Some(&metrics_prefix::

()), - "source", - "source_at_target", - )?)? - .expose() - .await? - .run(metrics_prefix::

(), move |source_client, target_client, metrics| { - run_until_connection_lost( - source_client, - target_client, - sync_params.clone(), - metrics, - exit_signal.clone(), - ) - }) - .await -} - -/// Unjustified headers container. Ordered by header number. -pub(crate) type UnjustifiedHeaders = Vec; -/// Finality proofs container. Ordered by target header number. -pub(crate) type FinalityProofs

= - Vec<(

::Number,

::FinalityProof)>; -/// Reference to finality proofs container. -pub(crate) type FinalityProofsRef<'a, P> = - &'a [(

::Number,

::FinalityProof)]; - -/// Error that may happen inside finality synchronization loop. -#[derive(Debug)] -pub(crate) enum Error { - /// Source client request has failed with given error. - Source(SourceError), - /// Target client request has failed with given error. - Target(TargetError), - /// Finality proof for mandatory header is missing from the source node. - MissingMandatoryFinalityProof(P::Number), - /// The synchronization has stalled. - Stalled, -} - -impl Error -where - P: FinalitySyncPipeline, - SourceError: MaybeConnectionError, - TargetError: MaybeConnectionError, -{ - fn fail_if_connection_error(&self) -> Result<(), FailedClient> { - match *self { - Error::Source(ref error) if error.is_connection_error() => Err(FailedClient::Source), - Error::Target(ref error) if error.is_connection_error() => Err(FailedClient::Target), - Error::Stalled => Err(FailedClient::Both), - _ => Ok(()), - } - } -} - -/// Information about transaction that we have submitted. -#[derive(Debug, Clone)] -pub(crate) struct Transaction { - /// Time when we have submitted this transaction. - pub time: Instant, - /// The number of the header we have submitted. - pub submitted_header_number: Number, -} - -/// Finality proofs stream that may be restarted. -pub(crate) struct RestartableFinalityProofsStream { - /// Flag that the stream needs to be restarted. - pub(crate) needs_restart: bool, - /// The stream itself. - pub(crate) stream: Pin>, -} - -#[cfg(test)] -impl From for RestartableFinalityProofsStream { - fn from(stream: S) -> Self { - RestartableFinalityProofsStream { needs_restart: false, stream: Box::pin(stream) } - } -} - -/// Finality synchronization loop state. -pub(crate) struct FinalityLoopState<'a, P: FinalitySyncPipeline, FinalityProofsStream> { - /// Synchronization loop progress. - pub(crate) progress: &'a mut (Instant, Option), - /// Finality proofs stream. - pub(crate) finality_proofs_stream: - &'a mut RestartableFinalityProofsStream, - /// Recent finality proofs that we have read from the stream. - pub(crate) recent_finality_proofs: &'a mut FinalityProofs

, - /// Last transaction that we have submitted to the target node. - pub(crate) last_transaction: Option>, -} - -async fn run_until_connection_lost( - source_client: impl SourceClient

, - target_client: impl TargetClient

, - sync_params: FinalitySyncParams, - metrics_sync: Option, - exit_signal: impl Future, -) -> Result<(), FailedClient> { - let restart_finality_proofs_stream = || async { - source_client.finality_proofs().await.map_err(|error| { - log::error!( - target: "bridge", - "Failed to subscribe to {} justifications: {:?}. Going to reconnect", - P::SOURCE_NAME, - error, - ); - - FailedClient::Source - }) - }; - - let exit_signal = exit_signal.fuse(); - futures::pin_mut!(exit_signal); - - let mut finality_proofs_stream = RestartableFinalityProofsStream { - needs_restart: false, - stream: Box::pin(restart_finality_proofs_stream().await?), - }; - let mut recent_finality_proofs = Vec::new(); - - let mut progress = (Instant::now(), None); - let mut retry_backoff = retry_backoff(); - let mut last_transaction = None; - - loop { - // run loop iteration - let iteration_result = run_loop_iteration( - &source_client, - &target_client, - FinalityLoopState { - progress: &mut progress, - finality_proofs_stream: &mut finality_proofs_stream, - recent_finality_proofs: &mut recent_finality_proofs, - last_transaction: last_transaction.clone(), - }, - &sync_params, - &metrics_sync, - ) - .await; - - // deal with errors - let next_tick = match iteration_result { - Ok(updated_last_transaction) => { - last_transaction = updated_last_transaction; - retry_backoff.reset(); - sync_params.tick - }, - Err(error) => { - log::error!(target: "bridge", "Finality sync loop iteration has failed with error: {:?}", error); - error.fail_if_connection_error()?; - retry_backoff.next_backoff().unwrap_or(relay_utils::relay_loop::RECONNECT_DELAY) - }, - }; - if finality_proofs_stream.needs_restart { - log::warn!(target: "bridge", "{} finality proofs stream is being restarted", P::SOURCE_NAME); - - finality_proofs_stream.needs_restart = false; - finality_proofs_stream.stream = Box::pin(restart_finality_proofs_stream().await?); - } - - // wait till exit signal, or new source block - select! { - _ = async_std::task::sleep(next_tick).fuse() => {}, - _ = exit_signal => return Ok(()), - } - } -} - -pub(crate) async fn run_loop_iteration( - source_client: &SC, - target_client: &TC, - state: FinalityLoopState<'_, P, SC::FinalityProofsStream>, - sync_params: &FinalitySyncParams, - metrics_sync: &Option, -) -> Result>, Error> -where - P: FinalitySyncPipeline, - SC: SourceClient

, - TC: TargetClient

, -{ - // read best source headers ids from source and target nodes - let best_number_at_source = - source_client.best_finalized_block_number().await.map_err(Error::Source)?; - let best_id_at_target = - target_client.best_finalized_source_block_id().await.map_err(Error::Target)?; - let best_number_at_target = best_id_at_target.0; - - let different_hash_at_source = - ensure_same_fork::(&best_id_at_target, source_client).await.map_err(Error::Source)?; - let using_same_fork = different_hash_at_source.is_none(); - if let Some(ref different_hash_at_source) = different_hash_at_source { - log::error!( - target: "bridge", - "Source node ({}) and pallet at target node ({}) have different headers at the same height {:?}: \ - at-source {:?} vs at-target {:?}", - P::SOURCE_NAME, - P::TARGET_NAME, - best_number_at_target, - different_hash_at_source, - best_id_at_target.1, - ); - } - - if let Some(ref metrics_sync) = *metrics_sync { - metrics_sync.update_best_block_at_source(best_number_at_source); - metrics_sync.update_best_block_at_target(best_number_at_target); - metrics_sync.update_using_same_fork(using_same_fork); - } - *state.progress = - print_sync_progress::

(*state.progress, best_number_at_source, best_number_at_target); - - // if we have already submitted header, then we just need to wait for it - // if we're waiting too much, then we believe our transaction has been lost and restart sync - if let Some(last_transaction) = state.last_transaction { - if best_number_at_target >= last_transaction.submitted_header_number { - // transaction has been mined && we can continue - } else if last_transaction.time.elapsed() > sync_params.stall_timeout { - log::error!( - target: "bridge", - "Finality synchronization from {} to {} has stalled. Going to restart", - P::SOURCE_NAME, - P::TARGET_NAME, - ); - - return Err(Error::Stalled); - } else { - return Ok(Some(last_transaction)); - } - } - - // submit new header if we have something new - match select_header_to_submit( - source_client, - target_client, - state.finality_proofs_stream, - state.recent_finality_proofs, - best_number_at_source, - best_number_at_target, - sync_params, - ) - .await? - { - Some((header, justification)) => { - let new_transaction = - Transaction { time: Instant::now(), submitted_header_number: header.number() }; - - log::debug!( - target: "bridge", - "Going to submit finality proof of {} header #{:?} to {}", - P::SOURCE_NAME, - new_transaction.submitted_header_number, - P::TARGET_NAME, - ); - - target_client - .submit_finality_proof(header, justification) - .await - .map_err(Error::Target)?; - Ok(Some(new_transaction)) - }, - None => Ok(None), - } -} - -pub(crate) async fn select_header_to_submit( - source_client: &SC, - target_client: &TC, - finality_proofs_stream: &mut RestartableFinalityProofsStream, - recent_finality_proofs: &mut FinalityProofs

, - best_number_at_source: P::Number, - best_number_at_target: P::Number, - sync_params: &FinalitySyncParams, -) -> Result, Error> -where - P: FinalitySyncPipeline, - SC: SourceClient

, - TC: TargetClient

, -{ - // to see that the loop is progressing - log::trace!( - target: "bridge", - "Considering range of headers ({:?}; {:?}]", - best_number_at_target, - best_number_at_source, - ); - - // read missing headers. if we see that the header schedules GRANDPA change, we need to - // submit this header - let selected_finality_proof = read_missing_headers::( - source_client, - target_client, - best_number_at_source, - best_number_at_target, - ) - .await?; - let (mut unjustified_headers, mut selected_finality_proof) = match selected_finality_proof { - SelectedFinalityProof::Mandatory(header, finality_proof) => - return Ok(Some((header, finality_proof))), - _ if sync_params.only_mandatory_headers => { - // we are not reading finality proofs from the stream, so eventually it'll break - // but we don't care about transient proofs at all, so it is acceptable - return Ok(None); - }, - SelectedFinalityProof::Regular(unjustified_headers, header, finality_proof) => - (unjustified_headers, Some((header, finality_proof))), - SelectedFinalityProof::None(unjustified_headers) => (unjustified_headers, None), - }; - - // all headers that are missing from the target client are non-mandatory - // => even if we have already selected some header and its persistent finality proof, - // we may try to select better header by reading non-persistent proofs from the stream - read_finality_proofs_from_stream::(finality_proofs_stream, recent_finality_proofs); - selected_finality_proof = select_better_recent_finality_proof::

( - recent_finality_proofs, - &mut unjustified_headers, - selected_finality_proof, - ); - - // remove obsolete 'recent' finality proofs + keep its size under certain limit - let oldest_finality_proof_to_keep = selected_finality_proof - .as_ref() - .map(|(header, _)| header.number()) - .unwrap_or(best_number_at_target); - prune_recent_finality_proofs::

( - oldest_finality_proof_to_keep, - recent_finality_proofs, - sync_params.recent_finality_proofs_limit, - ); - - Ok(selected_finality_proof) -} - -/// Ensures that both clients are on the same fork. -/// -/// Returns `Some(_)` with header has at the source client if headers are different. -async fn ensure_same_fork>( - best_id_at_target: &HeaderId, - source_client: &SC, -) -> Result, SC::Error> { - let header_at_source = source_client.header_and_finality_proof(best_id_at_target.0).await?.0; - let header_hash_at_source = header_at_source.hash(); - Ok(if best_id_at_target.1 == header_hash_at_source { - None - } else { - Some(header_hash_at_source) - }) -} - -/// Finality proof that has been selected by the `read_missing_headers` function. -pub(crate) enum SelectedFinalityProof { - /// Mandatory header and its proof has been selected. We shall submit proof for this header. - Mandatory(Header, FinalityProof), - /// Regular header and its proof has been selected. We may submit this proof, or proof for - /// some better header. - Regular(UnjustifiedHeaders

, Header, FinalityProof), - /// We haven't found any missing header with persistent proof at the target client. - None(UnjustifiedHeaders
), -} - -/// Read missing headers and their persistent finality proofs from the target client. -/// -/// If we have found some header with known proof, it is returned. -/// Otherwise, `SelectedFinalityProof::None` is returned. -/// -/// Unless we have found mandatory header, all missing headers are collected and returned. -pub(crate) async fn read_missing_headers< - P: FinalitySyncPipeline, - SC: SourceClient

, - TC: TargetClient

, ->( - source_client: &SC, - _target_client: &TC, - best_number_at_source: P::Number, - best_number_at_target: P::Number, -) -> Result, Error> { - let mut unjustified_headers = Vec::new(); - let mut selected_finality_proof = None; - let mut header_number = best_number_at_target + One::one(); - while header_number <= best_number_at_source { - let (header, finality_proof) = - source_client.header_and_finality_proof(header_number).await.map_err(Error::Source)?; - let is_mandatory = header.is_mandatory(); - - match (is_mandatory, finality_proof) { - (true, Some(finality_proof)) => { - log::trace!(target: "bridge", "Header {:?} is mandatory", header_number); - return Ok(SelectedFinalityProof::Mandatory(header, finality_proof)); - }, - (true, None) => return Err(Error::MissingMandatoryFinalityProof(header.number())), - (false, Some(finality_proof)) => { - log::trace!(target: "bridge", "Header {:?} has persistent finality proof", header_number); - unjustified_headers.clear(); - selected_finality_proof = Some((header, finality_proof)); - }, - (false, None) => { - unjustified_headers.push(header); - }, - } - - header_number = header_number + One::one(); - } - - log::trace!( - target: "bridge", - "Read {} {} headers. Selected finality proof for header: {:?}", - best_number_at_source.saturating_sub(best_number_at_target), - P::SOURCE_NAME, - selected_finality_proof.as_ref().map(|(header, _)| header), - ); - - Ok(match selected_finality_proof { - Some((header, proof)) => SelectedFinalityProof::Regular(unjustified_headers, header, proof), - None => SelectedFinalityProof::None(unjustified_headers), - }) -} - -/// Read finality proofs from the stream. -pub(crate) fn read_finality_proofs_from_stream< - P: FinalitySyncPipeline, - FPS: Stream, ->( - finality_proofs_stream: &mut RestartableFinalityProofsStream, - recent_finality_proofs: &mut FinalityProofs

, -) { - let mut proofs_count = 0; - let mut first_header_number = None; - let mut last_header_number = None; - loop { - let next_proof = finality_proofs_stream.stream.next(); - let finality_proof = match next_proof.now_or_never() { - Some(Some(finality_proof)) => finality_proof, - Some(None) => { - finality_proofs_stream.needs_restart = true; - break; - }, - None => break, - }; - - let target_header_number = finality_proof.target_header_number(); - if first_header_number.is_none() { - first_header_number = Some(target_header_number); - } - last_header_number = Some(target_header_number); - proofs_count += 1; - - recent_finality_proofs.push((target_header_number, finality_proof)); - } - - if proofs_count != 0 { - log::trace!( - target: "bridge", - "Read {} finality proofs from {} finality stream for headers in range [{:?}; {:?}]", - proofs_count, - P::SOURCE_NAME, - first_header_number, - last_header_number, - ); - } -} - -/// Try to select better header and its proof, given finality proofs that we -/// have recently read from the stream. -pub(crate) fn select_better_recent_finality_proof( - recent_finality_proofs: FinalityProofsRef

, - unjustified_headers: &mut UnjustifiedHeaders, - selected_finality_proof: Option<(P::Header, P::FinalityProof)>, -) -> Option<(P::Header, P::FinalityProof)> { - if unjustified_headers.is_empty() || recent_finality_proofs.is_empty() { - log::trace!( - target: "bridge", - "Can not improve selected {} finality proof {:?}. No unjustified headers and recent proofs", - P::SOURCE_NAME, - selected_finality_proof.as_ref().map(|(h, _)| h.number()), - ); - return selected_finality_proof; - } - - const NOT_EMPTY_PROOF: &str = "we have checked that the vec is not empty; qed"; - - // we need proofs for headers in range unjustified_range_begin..=unjustified_range_end - let unjustified_range_begin = unjustified_headers.first().expect(NOT_EMPTY_PROOF).number(); - let unjustified_range_end = unjustified_headers.last().expect(NOT_EMPTY_PROOF).number(); - - // we have proofs for headers in range buffered_range_begin..=buffered_range_end - let buffered_range_begin = recent_finality_proofs.first().expect(NOT_EMPTY_PROOF).0; - let buffered_range_end = recent_finality_proofs.last().expect(NOT_EMPTY_PROOF).0; - - // we have two ranges => find intersection - let intersection_begin = std::cmp::max(unjustified_range_begin, buffered_range_begin); - let intersection_end = std::cmp::min(unjustified_range_end, buffered_range_end); - let intersection = intersection_begin..=intersection_end; - - // find last proof from intersection - let selected_finality_proof_index = recent_finality_proofs - .binary_search_by_key(intersection.end(), |(number, _)| *number) - .unwrap_or_else(|index| index.saturating_sub(1)); - let (selected_header_number, finality_proof) = - &recent_finality_proofs[selected_finality_proof_index]; - let has_selected_finality_proof = intersection.contains(selected_header_number); - log::trace!( - target: "bridge", - "Trying to improve selected {} finality proof {:?}. Headers range: [{:?}; {:?}]. Proofs range: [{:?}; {:?}].\ - Trying to improve to: {:?}. Result: {}", - P::SOURCE_NAME, - selected_finality_proof.as_ref().map(|(h, _)| h.number()), - unjustified_range_begin, - unjustified_range_end, - buffered_range_begin, - buffered_range_end, - selected_header_number, - if has_selected_finality_proof { "improved" } else { "not improved" }, - ); - if !has_selected_finality_proof { - return selected_finality_proof; - } - - // now remove all obsolete headers and extract selected header - let selected_header_position = unjustified_headers - .binary_search_by_key(selected_header_number, |header| header.number()) - .expect("unjustified_headers contain all headers from intersection; qed"); - let selected_header = unjustified_headers.swap_remove(selected_header_position); - Some((selected_header, finality_proof.clone())) -} - -pub(crate) fn prune_recent_finality_proofs( - justified_header_number: P::Number, - recent_finality_proofs: &mut FinalityProofs

, - recent_finality_proofs_limit: usize, -) { - let position = recent_finality_proofs - .binary_search_by_key(&justified_header_number, |(header_number, _)| *header_number); - - // remove all obsolete elements - *recent_finality_proofs = recent_finality_proofs - .split_off(position.map(|position| position + 1).unwrap_or_else(|position| position)); - - // now - limit vec by size - let split_index = recent_finality_proofs.len().saturating_sub(recent_finality_proofs_limit); - *recent_finality_proofs = recent_finality_proofs.split_off(split_index); -} - -fn print_sync_progress( - progress_context: (Instant, Option), - best_number_at_source: P::Number, - best_number_at_target: P::Number, -) -> (Instant, Option) { - let (prev_time, prev_best_number_at_target) = progress_context; - let now = Instant::now(); - - let need_update = now - prev_time > Duration::from_secs(10) - || prev_best_number_at_target - .map(|prev_best_number_at_target| { - best_number_at_target.saturating_sub(prev_best_number_at_target) > 10.into() - }) - .unwrap_or(true); - - if !need_update { - return (prev_time, prev_best_number_at_target); - } - - log::info!( - target: "bridge", - "Synced {:?} of {:?} headers", - best_number_at_target, - best_number_at_source, - ); - (now, Some(best_number_at_target)) -} diff --git a/relays/finality/src/finality_loop_tests.rs b/relays/finality/src/finality_loop_tests.rs deleted file mode 100644 index 2c2ae2bc4..000000000 --- a/relays/finality/src/finality_loop_tests.rs +++ /dev/null @@ -1,548 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Tests for finality synchronization loop. - -#![cfg(test)] - -use crate::{ - finality_loop::{ - prune_recent_finality_proofs, read_finality_proofs_from_stream, run, run_loop_iteration, - select_better_recent_finality_proof, select_header_to_submit, FinalityLoopState, - FinalityProofs, FinalitySyncParams, RestartableFinalityProofsStream, SourceClient, - TargetClient, - }, - sync_loop_metrics::SyncLoopMetrics, - FinalityProof, FinalitySyncPipeline, SourceHeader, -}; - -use async_trait::async_trait; -use futures::{FutureExt, Stream, StreamExt}; -use parking_lot::Mutex; -use relay_utils::{ - metrics::MetricsParams, relay_loop::Client as RelayClient, HeaderId, MaybeConnectionError, -}; -use std::{ - collections::HashMap, - pin::Pin, - sync::Arc, - time::{Duration, Instant}, -}; - -type IsMandatory = bool; -type TestNumber = u64; -type TestHash = u64; - -#[derive(Debug, Clone)] -enum TestError { - NonConnection, -} - -impl MaybeConnectionError for TestError { - fn is_connection_error(&self) -> bool { - false - } -} - -#[derive(Debug, Clone)] -struct TestFinalitySyncPipeline; - -impl FinalitySyncPipeline for TestFinalitySyncPipeline { - type FinalityProof = TestFinalityProof; - type Hash = TestHash; - type Header = TestSourceHeader; - type Number = TestNumber; - - const SOURCE_NAME: &'static str = "TestSource"; - const TARGET_NAME: &'static str = "TestTarget"; -} - -#[derive(Debug, Clone, PartialEq)] -struct TestSourceHeader(IsMandatory, TestNumber, TestHash); - -impl SourceHeader for TestSourceHeader { - fn hash(&self) -> TestHash { - self.2 - } - - fn number(&self) -> TestNumber { - self.1 - } - - fn is_mandatory(&self) -> bool { - self.0 - } -} - -#[derive(Debug, Clone, PartialEq)] -struct TestFinalityProof(TestNumber); - -impl FinalityProof for TestFinalityProof { - fn target_header_number(&self) -> TestNumber { - self.0 - } -} - -#[derive(Debug, Clone, Default)] -struct ClientsData { - source_best_block_number: TestNumber, - source_headers: HashMap)>, - source_proofs: Vec, - - target_best_block_id: HeaderId, - target_headers: Vec<(TestSourceHeader, TestFinalityProof)>, -} - -#[derive(Clone)] -struct TestSourceClient { - on_method_call: Arc, - data: Arc>, -} - -#[async_trait] -impl RelayClient for TestSourceClient { - type Error = TestError; - - async fn reconnect(&mut self) -> Result<(), TestError> { - unreachable!() - } -} - -#[async_trait] -impl SourceClient for TestSourceClient { - type FinalityProofsStream = Pin + 'static + Send>>; - - async fn best_finalized_block_number(&self) -> Result { - let mut data = self.data.lock(); - (self.on_method_call)(&mut *data); - Ok(data.source_best_block_number) - } - - async fn header_and_finality_proof( - &self, - number: TestNumber, - ) -> Result<(TestSourceHeader, Option), TestError> { - let mut data = self.data.lock(); - (self.on_method_call)(&mut *data); - data.source_headers.get(&number).cloned().ok_or(TestError::NonConnection) - } - - async fn finality_proofs(&self) -> Result { - let mut data = self.data.lock(); - (self.on_method_call)(&mut *data); - Ok(futures::stream::iter(data.source_proofs.clone()).boxed()) - } -} - -#[derive(Clone)] -struct TestTargetClient { - on_method_call: Arc, - data: Arc>, -} - -#[async_trait] -impl RelayClient for TestTargetClient { - type Error = TestError; - - async fn reconnect(&mut self) -> Result<(), TestError> { - unreachable!() - } -} - -#[async_trait] -impl TargetClient for TestTargetClient { - async fn best_finalized_source_block_id( - &self, - ) -> Result, TestError> { - let mut data = self.data.lock(); - (self.on_method_call)(&mut *data); - Ok(data.target_best_block_id) - } - - async fn submit_finality_proof( - &self, - header: TestSourceHeader, - proof: TestFinalityProof, - ) -> Result<(), TestError> { - let mut data = self.data.lock(); - (self.on_method_call)(&mut *data); - data.target_best_block_id = HeaderId(header.number(), header.hash()); - data.target_headers.push((header, proof)); - Ok(()) - } -} - -fn prepare_test_clients( - exit_sender: futures::channel::mpsc::UnboundedSender<()>, - state_function: impl Fn(&mut ClientsData) -> bool + Send + Sync + 'static, - source_headers: HashMap)>, -) -> (TestSourceClient, TestTargetClient) { - let internal_state_function: Arc = - Arc::new(move |data| { - if state_function(data) { - exit_sender.unbounded_send(()).unwrap(); - } - }); - let clients_data = Arc::new(Mutex::new(ClientsData { - source_best_block_number: 10, - source_headers, - source_proofs: vec![TestFinalityProof(12), TestFinalityProof(14)], - - target_best_block_id: HeaderId(5, 5), - target_headers: vec![], - })); - ( - TestSourceClient { - on_method_call: internal_state_function.clone(), - data: clients_data.clone(), - }, - TestTargetClient { on_method_call: internal_state_function, data: clients_data }, - ) -} - -fn test_sync_params() -> FinalitySyncParams { - FinalitySyncParams { - tick: Duration::from_secs(0), - recent_finality_proofs_limit: 1024, - stall_timeout: Duration::from_secs(1), - only_mandatory_headers: false, - } -} - -fn run_sync_loop( - state_function: impl Fn(&mut ClientsData) -> bool + Send + Sync + 'static, -) -> ClientsData { - let (exit_sender, exit_receiver) = futures::channel::mpsc::unbounded(); - let (source_client, target_client) = prepare_test_clients( - exit_sender, - state_function, - vec![ - (5, (TestSourceHeader(false, 5, 5), None)), - (6, (TestSourceHeader(false, 6, 6), None)), - (7, (TestSourceHeader(false, 7, 7), Some(TestFinalityProof(7)))), - (8, (TestSourceHeader(true, 8, 8), Some(TestFinalityProof(8)))), - (9, (TestSourceHeader(false, 9, 9), Some(TestFinalityProof(9)))), - (10, (TestSourceHeader(false, 10, 10), None)), - ] - .into_iter() - .collect(), - ); - let sync_params = test_sync_params(); - - let clients_data = source_client.data.clone(); - let _ = async_std::task::block_on(run( - source_client, - target_client, - sync_params, - MetricsParams::disabled(), - exit_receiver.into_future().map(|(_, _)| ()), - )); - - let clients_data = clients_data.lock().clone(); - clients_data -} - -#[test] -fn finality_sync_loop_works() { - let client_data = run_sync_loop(|data| { - // header#7 has persistent finality proof, but it isn't mandatory => it isn't submitted, - // because header#8 has persistent finality proof && it is mandatory => it is submitted - // header#9 has persistent finality proof, but it isn't mandatory => it is submitted, - // because there are no more persistent finality proofs - // - // once this ^^^ is done, we generate more blocks && read proof for blocks 12 and 14 from - // the stream - if data.target_best_block_id.0 == 9 { - data.source_best_block_number = 14; - data.source_headers.insert(11, (TestSourceHeader(false, 11, 11), None)); - data.source_headers - .insert(12, (TestSourceHeader(false, 12, 12), Some(TestFinalityProof(12)))); - data.source_headers.insert(13, (TestSourceHeader(false, 13, 13), None)); - data.source_headers - .insert(14, (TestSourceHeader(false, 14, 14), Some(TestFinalityProof(14)))); - } - // once this ^^^ is done, we generate more blocks && read persistent proof for block 16 - if data.target_best_block_id.0 == 14 { - data.source_best_block_number = 17; - data.source_headers.insert(15, (TestSourceHeader(false, 15, 15), None)); - data.source_headers - .insert(16, (TestSourceHeader(false, 16, 16), Some(TestFinalityProof(16)))); - data.source_headers.insert(17, (TestSourceHeader(false, 17, 17), None)); - } - - data.target_best_block_id.0 == 16 - }); - - assert_eq!( - client_data.target_headers, - vec![ - // before adding 11..14: finality proof for mandatory header#8 - (TestSourceHeader(true, 8, 8), TestFinalityProof(8)), - // before adding 11..14: persistent finality proof for non-mandatory header#9 - (TestSourceHeader(false, 9, 9), TestFinalityProof(9)), - // after adding 11..14: ephemeral finality proof for non-mandatory header#14 - (TestSourceHeader(false, 14, 14), TestFinalityProof(14)), - // after adding 15..17: persistent finality proof for non-mandatory header#16 - (TestSourceHeader(false, 16, 16), TestFinalityProof(16)), - ], - ); -} - -fn run_only_mandatory_headers_mode_test( - only_mandatory_headers: bool, - has_mandatory_headers: bool, -) -> Option<(TestSourceHeader, TestFinalityProof)> { - let (exit_sender, _) = futures::channel::mpsc::unbounded(); - let (source_client, target_client) = prepare_test_clients( - exit_sender, - |_| false, - vec![ - (6, (TestSourceHeader(false, 6, 6), Some(TestFinalityProof(6)))), - (7, (TestSourceHeader(false, 7, 7), Some(TestFinalityProof(7)))), - (8, (TestSourceHeader(has_mandatory_headers, 8, 8), Some(TestFinalityProof(8)))), - (9, (TestSourceHeader(false, 9, 9), Some(TestFinalityProof(9)))), - (10, (TestSourceHeader(false, 10, 10), Some(TestFinalityProof(10)))), - ] - .into_iter() - .collect(), - ); - async_std::task::block_on(select_header_to_submit( - &source_client, - &target_client, - &mut RestartableFinalityProofsStream::from(futures::stream::empty().boxed()), - &mut vec![], - 10, - 5, - &FinalitySyncParams { - tick: Duration::from_secs(0), - recent_finality_proofs_limit: 0, - stall_timeout: Duration::from_secs(0), - only_mandatory_headers, - }, - )) - .unwrap() -} - -#[test] -fn select_header_to_submit_skips_non_mandatory_headers_when_only_mandatory_headers_are_required() { - assert_eq!(run_only_mandatory_headers_mode_test(true, false), None); - assert_eq!( - run_only_mandatory_headers_mode_test(false, false), - Some((TestSourceHeader(false, 10, 10), TestFinalityProof(10))), - ); -} - -#[test] -fn select_header_to_submit_selects_mandatory_headers_when_only_mandatory_headers_are_required() { - assert_eq!( - run_only_mandatory_headers_mode_test(true, true), - Some((TestSourceHeader(true, 8, 8), TestFinalityProof(8))), - ); - assert_eq!( - run_only_mandatory_headers_mode_test(false, true), - Some((TestSourceHeader(true, 8, 8), TestFinalityProof(8))), - ); -} - -#[test] -fn select_better_recent_finality_proof_works() { - // if there are no unjustified headers, nothing is changed - assert_eq!( - select_better_recent_finality_proof::( - &[(5, TestFinalityProof(5))], - &mut vec![], - Some((TestSourceHeader(false, 2, 2), TestFinalityProof(2))), - ), - Some((TestSourceHeader(false, 2, 2), TestFinalityProof(2))), - ); - - // if there are no recent finality proofs, nothing is changed - assert_eq!( - select_better_recent_finality_proof::( - &[], - &mut vec![TestSourceHeader(false, 5, 5)], - Some((TestSourceHeader(false, 2, 2), TestFinalityProof(2))), - ), - Some((TestSourceHeader(false, 2, 2), TestFinalityProof(2))), - ); - - // if there's no intersection between recent finality proofs and unjustified headers, nothing is - // changed - let mut unjustified_headers = - vec![TestSourceHeader(false, 9, 9), TestSourceHeader(false, 10, 10)]; - assert_eq!( - select_better_recent_finality_proof::( - &[(1, TestFinalityProof(1)), (4, TestFinalityProof(4))], - &mut unjustified_headers, - Some((TestSourceHeader(false, 2, 2), TestFinalityProof(2))), - ), - Some((TestSourceHeader(false, 2, 2), TestFinalityProof(2))), - ); - - // if there's intersection between recent finality proofs and unjustified headers, but there are - // no proofs in this intersection, nothing is changed - let mut unjustified_headers = vec![ - TestSourceHeader(false, 8, 8), - TestSourceHeader(false, 9, 9), - TestSourceHeader(false, 10, 10), - ]; - assert_eq!( - select_better_recent_finality_proof::( - &[(7, TestFinalityProof(7)), (11, TestFinalityProof(11))], - &mut unjustified_headers, - Some((TestSourceHeader(false, 2, 2), TestFinalityProof(2))), - ), - Some((TestSourceHeader(false, 2, 2), TestFinalityProof(2))), - ); - assert_eq!( - unjustified_headers, - vec![ - TestSourceHeader(false, 8, 8), - TestSourceHeader(false, 9, 9), - TestSourceHeader(false, 10, 10) - ] - ); - - // if there's intersection between recent finality proofs and unjustified headers and there's - // a proof in this intersection: - // - this better (last from intersection) proof is selected; - // - 'obsolete' unjustified headers are pruned. - let mut unjustified_headers = vec![ - TestSourceHeader(false, 8, 8), - TestSourceHeader(false, 9, 9), - TestSourceHeader(false, 10, 10), - ]; - assert_eq!( - select_better_recent_finality_proof::( - &[(7, TestFinalityProof(7)), (9, TestFinalityProof(9))], - &mut unjustified_headers, - Some((TestSourceHeader(false, 2, 2), TestFinalityProof(2))), - ), - Some((TestSourceHeader(false, 9, 9), TestFinalityProof(9))), - ); -} - -#[test] -fn read_finality_proofs_from_stream_works() { - // when stream is currently empty, nothing is changed - let mut recent_finality_proofs = vec![(1, TestFinalityProof(1))]; - let mut stream = futures::stream::pending().into(); - read_finality_proofs_from_stream::( - &mut stream, - &mut recent_finality_proofs, - ); - assert_eq!(recent_finality_proofs, vec![(1, TestFinalityProof(1))]); - assert!(!stream.needs_restart); - - // when stream has entry with target, it is added to the recent proofs container - let mut stream = - futures::stream::iter(vec![TestFinalityProof(4)]).chain(futures::stream::pending()).into(); - read_finality_proofs_from_stream::( - &mut stream, - &mut recent_finality_proofs, - ); - assert_eq!(recent_finality_proofs, vec![(1, TestFinalityProof(1)), (4, TestFinalityProof(4))]); - assert!(!stream.needs_restart); - - // when stream has ended, we'll need to restart it - let mut stream = futures::stream::empty().into(); - read_finality_proofs_from_stream::( - &mut stream, - &mut recent_finality_proofs, - ); - assert_eq!(recent_finality_proofs, vec![(1, TestFinalityProof(1)), (4, TestFinalityProof(4))]); - assert!(stream.needs_restart); -} - -#[test] -fn prune_recent_finality_proofs_works() { - let original_recent_finality_proofs: FinalityProofs = vec![ - (10, TestFinalityProof(10)), - (13, TestFinalityProof(13)), - (15, TestFinalityProof(15)), - (17, TestFinalityProof(17)), - (19, TestFinalityProof(19)), - ] - .into_iter() - .collect(); - - // when there's proof for justified header in the vec - let mut recent_finality_proofs = original_recent_finality_proofs.clone(); - prune_recent_finality_proofs::(10, &mut recent_finality_proofs, 1024); - assert_eq!(&original_recent_finality_proofs[1..], recent_finality_proofs,); - - // when there are no proof for justified header in the vec - let mut recent_finality_proofs = original_recent_finality_proofs.clone(); - prune_recent_finality_proofs::(11, &mut recent_finality_proofs, 1024); - assert_eq!(&original_recent_finality_proofs[1..], recent_finality_proofs,); - - // when there are too many entries after initial prune && they also need to be pruned - let mut recent_finality_proofs = original_recent_finality_proofs.clone(); - prune_recent_finality_proofs::(10, &mut recent_finality_proofs, 2); - assert_eq!(&original_recent_finality_proofs[3..], recent_finality_proofs,); - - // when last entry is pruned - let mut recent_finality_proofs = original_recent_finality_proofs.clone(); - prune_recent_finality_proofs::(19, &mut recent_finality_proofs, 2); - assert_eq!(&original_recent_finality_proofs[5..], recent_finality_proofs,); - - // when post-last entry is pruned - let mut recent_finality_proofs = original_recent_finality_proofs.clone(); - prune_recent_finality_proofs::(20, &mut recent_finality_proofs, 2); - assert_eq!(&original_recent_finality_proofs[5..], recent_finality_proofs,); -} - -#[test] -fn different_forks_at_source_and_at_target_are_detected() { - let (exit_sender, _exit_receiver) = futures::channel::mpsc::unbounded(); - let (source_client, target_client) = prepare_test_clients( - exit_sender, - |_| false, - vec![ - (5, (TestSourceHeader(false, 5, 42), None)), - (6, (TestSourceHeader(false, 6, 6), None)), - (7, (TestSourceHeader(false, 7, 7), None)), - (8, (TestSourceHeader(false, 8, 8), None)), - (9, (TestSourceHeader(false, 9, 9), None)), - (10, (TestSourceHeader(false, 10, 10), None)), - ] - .into_iter() - .collect(), - ); - - let mut progress = (Instant::now(), None); - let mut finality_proofs_stream = RestartableFinalityProofsStream { - needs_restart: false, - stream: Box::pin(futures::stream::iter(vec![]).boxed()), - }; - let mut recent_finality_proofs = Vec::new(); - let metrics_sync = SyncLoopMetrics::new(None, "source", "target").unwrap(); - async_std::task::block_on(run_loop_iteration::( - &source_client, - &target_client, - FinalityLoopState { - progress: &mut progress, - finality_proofs_stream: &mut finality_proofs_stream, - recent_finality_proofs: &mut recent_finality_proofs, - last_transaction: None, - }, - &test_sync_params(), - &Some(metrics_sync.clone()), - )) - .unwrap(); - - assert!(!metrics_sync.is_using_same_fork()); -} diff --git a/relays/finality/src/lib.rs b/relays/finality/src/lib.rs deleted file mode 100644 index 49be64ff7..000000000 --- a/relays/finality/src/lib.rs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! This crate has single entrypoint to run synchronization loop that is built around finality -//! proofs, as opposed to headers synchronization loop, which is built around headers. The headers -//! are still submitted to the target node, but are treated as auxiliary data as we are not trying -//! to submit all source headers to the target node. - -pub use crate::{ - finality_loop::{metrics_prefix, run, FinalitySyncParams, SourceClient, TargetClient}, - sync_loop_metrics::SyncLoopMetrics, -}; - -use bp_header_chain::FinalityProof; -use std::fmt::Debug; - -mod finality_loop; -mod finality_loop_tests; -mod sync_loop_metrics; - -/// Finality proofs synchronization pipeline. -pub trait FinalitySyncPipeline: 'static + Clone + Debug + Send + Sync { - /// Name of the finality proofs source. - const SOURCE_NAME: &'static str; - /// Name of the finality proofs target. - const TARGET_NAME: &'static str; - - /// Headers we're syncing are identified by this hash. - type Hash: Eq + Clone + Copy + Send + Sync + Debug; - /// Headers we're syncing are identified by this number. - type Number: relay_utils::BlockNumberBase; - /// Type of header that we're syncing. - type Header: SourceHeader; - /// Finality proof type. - type FinalityProof: FinalityProof; -} - -/// Header that we're receiving from source node. -pub trait SourceHeader: Clone + Debug + PartialEq + Send + Sync { - /// Returns hash of header. - fn hash(&self) -> Hash; - /// Returns number of header. - fn number(&self) -> Number; - /// Returns true if this header needs to be submitted to target node. - fn is_mandatory(&self) -> bool; -} diff --git a/relays/finality/src/sync_loop_metrics.rs b/relays/finality/src/sync_loop_metrics.rs deleted file mode 100644 index a003a47d8..000000000 --- a/relays/finality/src/sync_loop_metrics.rs +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Metrics for headers synchronization relay loop. - -use relay_utils::metrics::{metric_name, register, IntGauge, Metric, PrometheusError, Registry}; - -/// Headers sync metrics. -#[derive(Clone)] -pub struct SyncLoopMetrics { - /// Best syncing header at the source. - best_source_block_number: IntGauge, - /// Best syncing header at the target. - best_target_block_number: IntGauge, - /// Flag that has `0` value when best source headers at the source node and at-target-chain - /// are matching and `1` otherwise. - using_different_forks: IntGauge, -} - -impl SyncLoopMetrics { - /// Create and register headers loop metrics. - pub fn new( - prefix: Option<&str>, - at_source_chain_label: &str, - at_target_chain_label: &str, - ) -> Result { - Ok(SyncLoopMetrics { - best_source_block_number: IntGauge::new( - metric_name(prefix, &format!("best_{}_block_number", at_source_chain_label)), - format!("Best block number at the {}", at_source_chain_label), - )?, - best_target_block_number: IntGauge::new( - metric_name(prefix, &format!("best_{}_block_number", at_target_chain_label)), - format!("Best block number at the {}", at_target_chain_label), - )?, - using_different_forks: IntGauge::new( - metric_name(prefix, &format!("is_{}_and_{}_using_different_forks", at_source_chain_label, at_target_chain_label)), - "Whether the best finalized source block at target node is different (value 1) from the \ - corresponding block at the source node", - )?, - }) - } - - /// Returns current value of the using-same-fork flag. - #[cfg(test)] - pub(crate) fn is_using_same_fork(&self) -> bool { - self.using_different_forks.get() == 0 - } - - /// Update best block number at source. - pub fn update_best_block_at_source>(&self, source_best_number: Number) { - self.best_source_block_number.set(source_best_number.into()); - } - - /// Update best block number at target. - pub fn update_best_block_at_target>(&self, target_best_number: Number) { - self.best_target_block_number.set(target_best_number.into()); - } - - /// Update using-same-fork flag. - pub fn update_using_same_fork(&self, using_same_fork: bool) { - self.using_different_forks.set(if using_same_fork { 0 } else { 1 }) - } -} - -impl Metric for SyncLoopMetrics { - fn register(&self, registry: &Registry) -> Result<(), PrometheusError> { - register(self.best_source_block_number.clone(), registry)?; - register(self.best_target_block_number.clone(), registry)?; - register(self.using_different_forks.clone(), registry)?; - Ok(()) - } -} diff --git a/relays/messages/Cargo.toml b/relays/messages/Cargo.toml deleted file mode 100644 index b3357994b..000000000 --- a/relays/messages/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "messages-relay" -version = "0.1.0" -authors = ["Parity Technologies "] -edition = "2021" -license = "GPL-3.0-or-later WITH Classpath-exception-2.0" - -[dependencies] -async-std = { version = "1.6.5", features = ["attributes"] } -async-trait = "0.1.40" -futures = "0.3.5" -hex = "0.4" -log = "0.4.11" -num-traits = "0.2" -parking_lot = "0.11.0" - -# Bridge Dependencies - -bp-messages = { path = "../../primitives/messages" } -bp-runtime = { path = "../../primitives/runtime" } -finality-relay = { path = "../finality" } -relay-utils = { path = "../utils" } - -sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/relays/messages/src/lib.rs b/relays/messages/src/lib.rs deleted file mode 100644 index c9e460300..000000000 --- a/relays/messages/src/lib.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Relaying [`pallet-bridge-messages`](../pallet_bridge_messages/index.html) application specific -//! data. Message lane allows sending arbitrary messages between bridged chains. This -//! module provides entrypoint that starts reading messages from given message lane -//! of source chain and submits proof-of-message-at-source-chain transactions to the -//! target chain. Additionally, proofs-of-messages-delivery are sent back from the -//! target chain to the source chain. - -// required for futures::select! -#![recursion_limit = "1024"] -#![warn(missing_docs)] - -mod metrics; - -pub mod message_lane; -pub mod message_lane_loop; -pub mod relay_strategy; - -mod message_race_delivery; -mod message_race_loop; -mod message_race_receiving; -mod message_race_strategy; diff --git a/relays/messages/src/message_lane.rs b/relays/messages/src/message_lane.rs deleted file mode 100644 index 5c9728ad9..000000000 --- a/relays/messages/src/message_lane.rs +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! One-way message lane types. Within single one-way lane we have three 'races' where we try to: -//! -//! 1) relay new messages from source to target node; -//! 2) relay proof-of-delivery from target to source node. - -use num_traits::{SaturatingAdd, Zero}; -use relay_utils::{BlockNumberBase, HeaderId}; -use sp_arithmetic::traits::AtLeast32BitUnsigned; -use std::{fmt::Debug, ops::Sub}; - -/// One-way message lane. -pub trait MessageLane: 'static + Clone + Send + Sync { - /// Name of the messages source. - const SOURCE_NAME: &'static str; - /// Name of the messages target. - const TARGET_NAME: &'static str; - - /// Messages proof. - type MessagesProof: Clone + Debug + Send + Sync; - /// Messages receiving proof. - type MessagesReceivingProof: Clone + Debug + Send + Sync; - - /// The type of the source chain token balance, that is used to: - /// - /// 1) pay transaction fees; - /// 2) pay message delivery and dispatch fee; - /// 3) pay relayer rewards. - type SourceChainBalance: AtLeast32BitUnsigned - + Clone - + Copy - + Debug - + PartialOrd - + Sub - + SaturatingAdd - + Zero - + Send - + Sync; - /// Number of the source header. - type SourceHeaderNumber: BlockNumberBase; - /// Hash of the source header. - type SourceHeaderHash: Clone + Debug + Default + PartialEq + Send + Sync; - - /// Number of the target header. - type TargetHeaderNumber: BlockNumberBase; - /// Hash of the target header. - type TargetHeaderHash: Clone + Debug + Default + PartialEq + Send + Sync; -} - -/// Source header id within given one-way message lane. -pub type SourceHeaderIdOf

= - HeaderId<

::SourceHeaderHash,

::SourceHeaderNumber>; - -/// Target header id within given one-way message lane. -pub type TargetHeaderIdOf

= - HeaderId<

::TargetHeaderHash,

::TargetHeaderNumber>; diff --git a/relays/messages/src/message_lane_loop.rs b/relays/messages/src/message_lane_loop.rs deleted file mode 100644 index 5764be3fb..000000000 --- a/relays/messages/src/message_lane_loop.rs +++ /dev/null @@ -1,966 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Message delivery loop. Designed to work with messages pallet. -//! -//! Single relay instance delivers messages of single lane in single direction. -//! To serve two-way lane, you would need two instances of relay. -//! To serve N two-way lanes, you would need N*2 instances of relay. -//! -//! Please keep in mind that the best header in this file is actually best -//! finalized header. I.e. when talking about headers in lane context, we -//! only care about finalized headers. - -use std::{collections::BTreeMap, fmt::Debug, future::Future, ops::RangeInclusive, time::Duration}; - -use async_trait::async_trait; -use futures::{channel::mpsc::unbounded, future::FutureExt, stream::StreamExt}; - -use bp_messages::{LaneId, MessageNonce, UnrewardedRelayersState, Weight}; -use bp_runtime::messages::DispatchFeePayment; -use relay_utils::{ - interval, metrics::MetricsParams, process_future_result, relay_loop::Client as RelayClient, - retry_backoff, FailedClient, -}; - -use crate::{ - message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf}, - message_race_delivery::run as run_message_delivery_race, - message_race_receiving::run as run_message_receiving_race, - metrics::MessageLaneLoopMetrics, - relay_strategy::RelayStrategy, -}; - -/// Message lane loop configuration params. -#[derive(Debug, Clone)] -pub struct Params { - /// Id of lane this loop is servicing. - pub lane: LaneId, - /// Interval at which we ask target node about its updates. - pub source_tick: Duration, - /// Interval at which we ask target node about its updates. - pub target_tick: Duration, - /// Delay between moments when connection error happens and our reconnect attempt. - pub reconnect_delay: Duration, - /// The loop will auto-restart if there has been no updates during this period. - pub stall_timeout: Duration, - /// Message delivery race parameters. - pub delivery_params: MessageDeliveryParams, -} - -/// Relayer operating mode. -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum RelayerMode { - /// The relayer doesn't care about rewards. - Altruistic, - /// The relayer will deliver all messages and confirmations as long as he's not losing any - /// funds. - Rational, -} - -/// Message delivery race parameters. -#[derive(Debug, Clone)] -pub struct MessageDeliveryParams { - /// Maximal number of unconfirmed relayer entries at the inbound lane. If there's that number - /// of entries in the `InboundLaneData::relayers` set, all new messages will be rejected until - /// reward payment will be proved (by including outbound lane state to the message delivery - /// transaction). - pub max_unrewarded_relayer_entries_at_target: MessageNonce, - /// Message delivery race will stop delivering messages if there are - /// `max_unconfirmed_nonces_at_target` unconfirmed nonces on the target node. The race would - /// continue once they're confirmed by the receiving race. - pub max_unconfirmed_nonces_at_target: MessageNonce, - /// Maximal number of relayed messages in single delivery transaction. - pub max_messages_in_single_batch: MessageNonce, - /// Maximal cumulative dispatch weight of relayed messages in single delivery transaction. - pub max_messages_weight_in_single_batch: Weight, - /// Maximal cumulative size of relayed messages in single delivery transaction. - pub max_messages_size_in_single_batch: u32, - /// Relay strategy - pub relay_strategy: Strategy, -} - -/// Message details. -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct MessageDetails { - /// Message dispatch weight. - pub dispatch_weight: Weight, - /// Message size (number of bytes in encoded payload). - pub size: u32, - /// The relayer reward paid in the source chain tokens. - pub reward: SourceChainBalance, - /// Where the fee for dispatching message is paid? - pub dispatch_fee_payment: DispatchFeePayment, -} - -/// Messages details map. -pub type MessageDetailsMap = - BTreeMap>; - -/// Message delivery race proof parameters. -#[derive(Debug, PartialEq)] -pub struct MessageProofParameters { - /// Include outbound lane state proof? - pub outbound_state_proof_required: bool, - /// Cumulative dispatch weight of messages that we're building proof for. - pub dispatch_weight: Weight, -} - -/// Source client trait. -#[async_trait] -pub trait SourceClient: RelayClient { - /// Returns state of the client. - async fn state(&self) -> Result, Self::Error>; - - /// Get nonce of instance of latest generated message. - async fn latest_generated_nonce( - &self, - id: SourceHeaderIdOf

, - ) -> Result<(SourceHeaderIdOf

, MessageNonce), Self::Error>; - - /// Get nonce of the latest message, which receiving has been confirmed by the target chain. - async fn latest_confirmed_received_nonce( - &self, - id: SourceHeaderIdOf

, - ) -> Result<(SourceHeaderIdOf

, MessageNonce), Self::Error>; - - /// Returns mapping of message nonces, generated on this client, to their weights. - /// - /// Some messages may be missing from returned map, if corresponding messages were pruned at - /// the source chain. - async fn generated_message_details( - &self, - id: SourceHeaderIdOf

, - nonces: RangeInclusive, - ) -> Result, Self::Error>; - - /// Prove messages in inclusive range [begin; end]. - async fn prove_messages( - &self, - id: SourceHeaderIdOf

, - nonces: RangeInclusive, - proof_parameters: MessageProofParameters, - ) -> Result<(SourceHeaderIdOf

, RangeInclusive, P::MessagesProof), Self::Error>; - - /// Submit messages receiving proof. - async fn submit_messages_receiving_proof( - &self, - generated_at_block: TargetHeaderIdOf

, - proof: P::MessagesReceivingProof, - ) -> Result<(), Self::Error>; - - /// We need given finalized target header on source to continue synchronization. - async fn require_target_header_on_source(&self, id: TargetHeaderIdOf

); - - /// Estimate cost of single message confirmation transaction in source chain tokens. - async fn estimate_confirmation_transaction(&self) -> P::SourceChainBalance; -} - -/// Target client trait. -#[async_trait] -pub trait TargetClient: RelayClient { - /// Returns state of the client. - async fn state(&self) -> Result, Self::Error>; - - /// Get nonce of latest received message. - async fn latest_received_nonce( - &self, - id: TargetHeaderIdOf

, - ) -> Result<(TargetHeaderIdOf

, MessageNonce), Self::Error>; - - /// Get nonce of the latest confirmed message. - async fn latest_confirmed_received_nonce( - &self, - id: TargetHeaderIdOf

, - ) -> Result<(TargetHeaderIdOf

, MessageNonce), Self::Error>; - - /// Get state of unrewarded relayers set at the inbound lane. - async fn unrewarded_relayers_state( - &self, - id: TargetHeaderIdOf

, - ) -> Result<(TargetHeaderIdOf

, UnrewardedRelayersState), Self::Error>; - - /// Prove messages receiving at given block. - async fn prove_messages_receiving( - &self, - id: TargetHeaderIdOf

, - ) -> Result<(TargetHeaderIdOf

, P::MessagesReceivingProof), Self::Error>; - - /// Submit messages proof. - async fn submit_messages_proof( - &self, - generated_at_header: SourceHeaderIdOf

, - nonces: RangeInclusive, - proof: P::MessagesProof, - ) -> Result, Self::Error>; - - /// We need given finalized source header on target to continue synchronization. - async fn require_source_header_on_target(&self, id: SourceHeaderIdOf

); - - /// Estimate cost of messages delivery transaction in source chain tokens. - /// - /// Please keep in mind that the returned cost must be converted to the source chain - /// tokens, even though the transaction fee will be paid in the target chain tokens. - async fn estimate_delivery_transaction_in_source_tokens( - &self, - nonces: RangeInclusive, - total_prepaid_nonces: MessageNonce, - total_dispatch_weight: Weight, - total_size: u32, - ) -> Result; -} - -/// State of the client. -#[derive(Clone, Debug, Default, PartialEq)] -pub struct ClientState { - /// The best header id of this chain. - pub best_self: SelfHeaderId, - /// Best finalized header id of this chain. - pub best_finalized_self: SelfHeaderId, - /// Best finalized header id of the peer chain read at the best block of this chain (at - /// `best_finalized_self`). - pub best_finalized_peer_at_best_self: PeerHeaderId, - /// Header id of the peer chain with the number, matching the - /// `best_finalized_peer_at_best_self`. - pub actual_best_finalized_peer_at_best_self: PeerHeaderId, -} - -/// State of source client in one-way message lane. -pub type SourceClientState

= ClientState, TargetHeaderIdOf

>; - -/// State of target client in one-way message lane. -pub type TargetClientState

= ClientState, SourceHeaderIdOf

>; - -/// Both clients state. -#[derive(Debug, Default)] -pub struct ClientsState { - /// Source client state. - pub source: Option>, - /// Target client state. - pub target: Option>, -} - -/// Return prefix that will be used by default to expose Prometheus metrics of the finality proofs -/// sync loop. -pub fn metrics_prefix(lane: &LaneId) -> String { - format!("{}_to_{}_MessageLane_{}", P::SOURCE_NAME, P::TARGET_NAME, hex::encode(lane)) -} - -/// Run message lane service loop. -pub async fn run( - params: Params, - source_client: impl SourceClient

, - target_client: impl TargetClient

, - metrics_params: MetricsParams, - exit_signal: impl Future + Send + 'static, -) -> Result<(), relay_utils::Error> { - let exit_signal = exit_signal.shared(); - relay_utils::relay_loop(source_client, target_client) - .reconnect_delay(params.reconnect_delay) - .with_metrics(metrics_params) - .loop_metric(MessageLaneLoopMetrics::new(Some(&metrics_prefix::

(¶ms.lane)))?)? - .expose() - .await? - .run(metrics_prefix::

(¶ms.lane), move |source_client, target_client, metrics| { - run_until_connection_lost( - params.clone(), - source_client, - target_client, - metrics, - exit_signal.clone(), - ) - }) - .await -} - -/// Run one-way message delivery loop until connection with target or source node is lost, or exit -/// signal is received. -async fn run_until_connection_lost< - P: MessageLane, - Strategy: RelayStrategy, - SC: SourceClient

, - TC: TargetClient

, ->( - params: Params, - source_client: SC, - target_client: TC, - metrics_msg: Option, - exit_signal: impl Future, -) -> Result<(), FailedClient> { - let mut source_retry_backoff = retry_backoff(); - let mut source_client_is_online = false; - let mut source_state_required = true; - let source_state = source_client.state().fuse(); - let source_go_offline_future = futures::future::Fuse::terminated(); - let source_tick_stream = interval(params.source_tick).fuse(); - - let mut target_retry_backoff = retry_backoff(); - let mut target_client_is_online = false; - let mut target_state_required = true; - let target_state = target_client.state().fuse(); - let target_go_offline_future = futures::future::Fuse::terminated(); - let target_tick_stream = interval(params.target_tick).fuse(); - - let ( - (delivery_source_state_sender, delivery_source_state_receiver), - (delivery_target_state_sender, delivery_target_state_receiver), - ) = (unbounded(), unbounded()); - let delivery_race_loop = run_message_delivery_race( - source_client.clone(), - delivery_source_state_receiver, - target_client.clone(), - delivery_target_state_receiver, - params.stall_timeout, - metrics_msg.clone(), - params.delivery_params, - ) - .fuse(); - - let ( - (receiving_source_state_sender, receiving_source_state_receiver), - (receiving_target_state_sender, receiving_target_state_receiver), - ) = (unbounded(), unbounded()); - let receiving_race_loop = run_message_receiving_race( - source_client.clone(), - receiving_source_state_receiver, - target_client.clone(), - receiving_target_state_receiver, - params.stall_timeout, - metrics_msg.clone(), - ) - .fuse(); - - let exit_signal = exit_signal.fuse(); - - futures::pin_mut!( - source_state, - source_go_offline_future, - source_tick_stream, - target_state, - target_go_offline_future, - target_tick_stream, - delivery_race_loop, - receiving_race_loop, - exit_signal - ); - - loop { - futures::select! { - new_source_state = source_state => { - source_state_required = false; - - source_client_is_online = process_future_result( - new_source_state, - &mut source_retry_backoff, - |new_source_state| { - log::debug!( - target: "bridge", - "Received state from {} node: {:?}", - P::SOURCE_NAME, - new_source_state, - ); - let _ = delivery_source_state_sender.unbounded_send(new_source_state.clone()); - let _ = receiving_source_state_sender.unbounded_send(new_source_state.clone()); - - if let Some(metrics_msg) = metrics_msg.as_ref() { - metrics_msg.update_source_state::

(new_source_state); - } - }, - &mut source_go_offline_future, - async_std::task::sleep, - || format!("Error retrieving state from {} node", P::SOURCE_NAME), - ).fail_if_connection_error(FailedClient::Source)?; - }, - _ = source_go_offline_future => { - source_client_is_online = true; - }, - _ = source_tick_stream.next() => { - source_state_required = true; - }, - new_target_state = target_state => { - target_state_required = false; - - target_client_is_online = process_future_result( - new_target_state, - &mut target_retry_backoff, - |new_target_state| { - log::debug!( - target: "bridge", - "Received state from {} node: {:?}", - P::TARGET_NAME, - new_target_state, - ); - let _ = delivery_target_state_sender.unbounded_send(new_target_state.clone()); - let _ = receiving_target_state_sender.unbounded_send(new_target_state.clone()); - - if let Some(metrics_msg) = metrics_msg.as_ref() { - metrics_msg.update_target_state::

(new_target_state); - } - }, - &mut target_go_offline_future, - async_std::task::sleep, - || format!("Error retrieving state from {} node", P::TARGET_NAME), - ).fail_if_connection_error(FailedClient::Target)?; - }, - _ = target_go_offline_future => { - target_client_is_online = true; - }, - _ = target_tick_stream.next() => { - target_state_required = true; - }, - - delivery_error = delivery_race_loop => { - match delivery_error { - Ok(_) => unreachable!("only ends with error; qed"), - Err(err) => return Err(err), - } - }, - receiving_error = receiving_race_loop => { - match receiving_error { - Ok(_) => unreachable!("only ends with error; qed"), - Err(err) => return Err(err), - } - }, - - () = exit_signal => { - return Ok(()); - } - } - - if source_client_is_online && source_state_required { - log::debug!(target: "bridge", "Asking {} node about its state", P::SOURCE_NAME); - source_state.set(source_client.state().fuse()); - source_client_is_online = false; - } - - if target_client_is_online && target_state_required { - log::debug!(target: "bridge", "Asking {} node about its state", P::TARGET_NAME); - target_state.set(target_client.state().fuse()); - target_client_is_online = false; - } - } -} - -#[cfg(test)] -pub(crate) mod tests { - use std::sync::Arc; - - use futures::stream::StreamExt; - use parking_lot::Mutex; - - use relay_utils::{HeaderId, MaybeConnectionError}; - - use crate::relay_strategy::AltruisticStrategy; - - use super::*; - - pub fn header_id(number: TestSourceHeaderNumber) -> TestSourceHeaderId { - HeaderId(number, number) - } - - pub const CONFIRMATION_TRANSACTION_COST: TestSourceChainBalance = 1; - pub const BASE_MESSAGE_DELIVERY_TRANSACTION_COST: TestSourceChainBalance = 1; - - pub type TestSourceChainBalance = u64; - pub type TestSourceHeaderId = HeaderId; - pub type TestTargetHeaderId = HeaderId; - - pub type TestMessagesProof = (RangeInclusive, Option); - pub type TestMessagesReceivingProof = MessageNonce; - - pub type TestSourceHeaderNumber = u64; - pub type TestSourceHeaderHash = u64; - - pub type TestTargetHeaderNumber = u64; - pub type TestTargetHeaderHash = u64; - - #[derive(Debug)] - pub struct TestError; - - impl MaybeConnectionError for TestError { - fn is_connection_error(&self) -> bool { - true - } - } - - #[derive(Clone)] - pub struct TestMessageLane; - - impl MessageLane for TestMessageLane { - type MessagesProof = TestMessagesProof; - type MessagesReceivingProof = TestMessagesReceivingProof; - type SourceChainBalance = TestSourceChainBalance; - type SourceHeaderHash = TestSourceHeaderHash; - type SourceHeaderNumber = TestSourceHeaderNumber; - type TargetHeaderHash = TestTargetHeaderHash; - type TargetHeaderNumber = TestTargetHeaderNumber; - - const SOURCE_NAME: &'static str = "TestSource"; - const TARGET_NAME: &'static str = "TestTarget"; - } - - #[derive(Debug, Default, Clone)] - pub struct TestClientData { - is_source_fails: bool, - is_source_reconnected: bool, - source_state: SourceClientState, - source_latest_generated_nonce: MessageNonce, - source_latest_confirmed_received_nonce: MessageNonce, - submitted_messages_receiving_proofs: Vec, - is_target_fails: bool, - is_target_reconnected: bool, - target_state: SourceClientState, - target_latest_received_nonce: MessageNonce, - target_latest_confirmed_received_nonce: MessageNonce, - submitted_messages_proofs: Vec, - target_to_source_header_required: Option, - target_to_source_header_requirements: Vec, - source_to_target_header_required: Option, - source_to_target_header_requirements: Vec, - } - - #[derive(Clone)] - pub struct TestSourceClient { - data: Arc>, - tick: Arc, - } - - impl Default for TestSourceClient { - fn default() -> Self { - TestSourceClient { - data: Arc::new(Mutex::new(TestClientData::default())), - tick: Arc::new(|_| {}), - } - } - } - - #[async_trait] - impl RelayClient for TestSourceClient { - type Error = TestError; - - async fn reconnect(&mut self) -> Result<(), TestError> { - { - let mut data = self.data.lock(); - (self.tick)(&mut *data); - data.is_source_reconnected = true; - } - Ok(()) - } - } - - #[async_trait] - impl SourceClient for TestSourceClient { - async fn state(&self) -> Result, TestError> { - let mut data = self.data.lock(); - (self.tick)(&mut *data); - if data.is_source_fails { - return Err(TestError); - } - Ok(data.source_state.clone()) - } - - async fn latest_generated_nonce( - &self, - id: SourceHeaderIdOf, - ) -> Result<(SourceHeaderIdOf, MessageNonce), TestError> { - let mut data = self.data.lock(); - (self.tick)(&mut *data); - if data.is_source_fails { - return Err(TestError); - } - Ok((id, data.source_latest_generated_nonce)) - } - - async fn latest_confirmed_received_nonce( - &self, - id: SourceHeaderIdOf, - ) -> Result<(SourceHeaderIdOf, MessageNonce), TestError> { - let mut data = self.data.lock(); - (self.tick)(&mut *data); - Ok((id, data.source_latest_confirmed_received_nonce)) - } - - async fn generated_message_details( - &self, - _id: SourceHeaderIdOf, - nonces: RangeInclusive, - ) -> Result, TestError> { - Ok(nonces - .map(|nonce| { - ( - nonce, - MessageDetails { - dispatch_weight: 1, - size: 1, - reward: 1, - dispatch_fee_payment: DispatchFeePayment::AtSourceChain, - }, - ) - }) - .collect()) - } - - async fn prove_messages( - &self, - id: SourceHeaderIdOf, - nonces: RangeInclusive, - proof_parameters: MessageProofParameters, - ) -> Result< - (SourceHeaderIdOf, RangeInclusive, TestMessagesProof), - TestError, - > { - let mut data = self.data.lock(); - (self.tick)(&mut *data); - Ok(( - id, - nonces.clone(), - ( - nonces, - if proof_parameters.outbound_state_proof_required { - Some(data.source_latest_confirmed_received_nonce) - } else { - None - }, - ), - )) - } - - async fn submit_messages_receiving_proof( - &self, - _generated_at_block: TargetHeaderIdOf, - proof: TestMessagesReceivingProof, - ) -> Result<(), TestError> { - let mut data = self.data.lock(); - (self.tick)(&mut *data); - data.source_state.best_self = - HeaderId(data.source_state.best_self.0 + 1, data.source_state.best_self.1 + 1); - data.source_state.best_finalized_self = data.source_state.best_self; - data.submitted_messages_receiving_proofs.push(proof); - data.source_latest_confirmed_received_nonce = proof; - Ok(()) - } - - async fn require_target_header_on_source(&self, id: TargetHeaderIdOf) { - let mut data = self.data.lock(); - data.target_to_source_header_required = Some(id); - data.target_to_source_header_requirements.push(id); - (self.tick)(&mut *data); - } - - async fn estimate_confirmation_transaction(&self) -> TestSourceChainBalance { - CONFIRMATION_TRANSACTION_COST - } - } - - #[derive(Clone)] - pub struct TestTargetClient { - data: Arc>, - tick: Arc, - } - - impl Default for TestTargetClient { - fn default() -> Self { - TestTargetClient { - data: Arc::new(Mutex::new(TestClientData::default())), - tick: Arc::new(|_| {}), - } - } - } - - #[async_trait] - impl RelayClient for TestTargetClient { - type Error = TestError; - - async fn reconnect(&mut self) -> Result<(), TestError> { - { - let mut data = self.data.lock(); - (self.tick)(&mut *data); - data.is_target_reconnected = true; - } - Ok(()) - } - } - - #[async_trait] - impl TargetClient for TestTargetClient { - async fn state(&self) -> Result, TestError> { - let mut data = self.data.lock(); - (self.tick)(&mut *data); - if data.is_target_fails { - return Err(TestError); - } - Ok(data.target_state.clone()) - } - - async fn latest_received_nonce( - &self, - id: TargetHeaderIdOf, - ) -> Result<(TargetHeaderIdOf, MessageNonce), TestError> { - let mut data = self.data.lock(); - (self.tick)(&mut *data); - if data.is_target_fails { - return Err(TestError); - } - Ok((id, data.target_latest_received_nonce)) - } - - async fn unrewarded_relayers_state( - &self, - id: TargetHeaderIdOf, - ) -> Result<(TargetHeaderIdOf, UnrewardedRelayersState), TestError> { - Ok(( - id, - UnrewardedRelayersState { - unrewarded_relayer_entries: 0, - messages_in_oldest_entry: 0, - total_messages: 0, - }, - )) - } - - async fn latest_confirmed_received_nonce( - &self, - id: TargetHeaderIdOf, - ) -> Result<(TargetHeaderIdOf, MessageNonce), TestError> { - let mut data = self.data.lock(); - (self.tick)(&mut *data); - if data.is_target_fails { - return Err(TestError); - } - Ok((id, data.target_latest_confirmed_received_nonce)) - } - - async fn prove_messages_receiving( - &self, - id: TargetHeaderIdOf, - ) -> Result<(TargetHeaderIdOf, TestMessagesReceivingProof), TestError> { - Ok((id, self.data.lock().target_latest_received_nonce)) - } - - async fn submit_messages_proof( - &self, - _generated_at_header: SourceHeaderIdOf, - nonces: RangeInclusive, - proof: TestMessagesProof, - ) -> Result, TestError> { - let mut data = self.data.lock(); - (self.tick)(&mut *data); - if data.is_target_fails { - return Err(TestError); - } - data.target_state.best_self = - HeaderId(data.target_state.best_self.0 + 1, data.target_state.best_self.1 + 1); - data.target_state.best_finalized_self = data.target_state.best_self; - data.target_latest_received_nonce = *proof.0.end(); - if let Some(target_latest_confirmed_received_nonce) = proof.1 { - data.target_latest_confirmed_received_nonce = - target_latest_confirmed_received_nonce; - } - data.submitted_messages_proofs.push(proof); - Ok(nonces) - } - - async fn require_source_header_on_target(&self, id: SourceHeaderIdOf) { - let mut data = self.data.lock(); - data.source_to_target_header_required = Some(id); - data.source_to_target_header_requirements.push(id); - (self.tick)(&mut *data); - } - - async fn estimate_delivery_transaction_in_source_tokens( - &self, - nonces: RangeInclusive, - _total_prepaid_nonces: MessageNonce, - total_dispatch_weight: Weight, - total_size: u32, - ) -> Result { - Ok(BASE_MESSAGE_DELIVERY_TRANSACTION_COST * (nonces.end() - nonces.start() + 1) - + total_dispatch_weight - + total_size as TestSourceChainBalance) - } - } - - fn run_loop_test( - data: TestClientData, - source_tick: Arc, - target_tick: Arc, - exit_signal: impl Future + 'static + Send, - ) -> TestClientData { - async_std::task::block_on(async { - let data = Arc::new(Mutex::new(data)); - - let source_client = TestSourceClient { data: data.clone(), tick: source_tick }; - let target_client = TestTargetClient { data: data.clone(), tick: target_tick }; - let _ = run( - Params { - lane: [0, 0, 0, 0], - source_tick: Duration::from_millis(100), - target_tick: Duration::from_millis(100), - reconnect_delay: Duration::from_millis(0), - stall_timeout: Duration::from_millis(60 * 1000), - delivery_params: MessageDeliveryParams { - max_unrewarded_relayer_entries_at_target: 4, - max_unconfirmed_nonces_at_target: 4, - max_messages_in_single_batch: 4, - max_messages_weight_in_single_batch: 4, - max_messages_size_in_single_batch: 4, - relay_strategy: AltruisticStrategy, - }, - }, - source_client, - target_client, - MetricsParams::disabled(), - exit_signal, - ) - .await; - let result = data.lock().clone(); - result - }) - } - - #[test] - fn message_lane_loop_is_able_to_recover_from_connection_errors() { - // with this configuration, source client will return Err, making source client - // reconnect. Then the target client will fail with Err + reconnect. Then we finally - // able to deliver messages. - let (exit_sender, exit_receiver) = unbounded(); - let result = run_loop_test( - TestClientData { - is_source_fails: true, - source_state: ClientState { - best_self: HeaderId(0, 0), - best_finalized_self: HeaderId(0, 0), - best_finalized_peer_at_best_self: HeaderId(0, 0), - actual_best_finalized_peer_at_best_self: HeaderId(0, 0), - }, - source_latest_generated_nonce: 1, - target_state: ClientState { - best_self: HeaderId(0, 0), - best_finalized_self: HeaderId(0, 0), - best_finalized_peer_at_best_self: HeaderId(0, 0), - actual_best_finalized_peer_at_best_self: HeaderId(0, 0), - }, - target_latest_received_nonce: 0, - ..Default::default() - }, - Arc::new(|data: &mut TestClientData| { - if data.is_source_reconnected { - data.is_source_fails = false; - data.is_target_fails = true; - } - }), - Arc::new(move |data: &mut TestClientData| { - if data.is_target_reconnected { - data.is_target_fails = false; - } - if data.target_state.best_finalized_peer_at_best_self.0 < 10 { - data.target_state.best_finalized_peer_at_best_self = HeaderId( - data.target_state.best_finalized_peer_at_best_self.0 + 1, - data.target_state.best_finalized_peer_at_best_self.0 + 1, - ); - } - if !data.submitted_messages_proofs.is_empty() { - exit_sender.unbounded_send(()).unwrap(); - } - }), - exit_receiver.into_future().map(|(_, _)| ()), - ); - - assert_eq!(result.submitted_messages_proofs, vec![(1..=1, None)],); - } - - #[test] - fn message_lane_loop_works() { - let (exit_sender, exit_receiver) = unbounded(); - let result = run_loop_test( - TestClientData { - source_state: ClientState { - best_self: HeaderId(10, 10), - best_finalized_self: HeaderId(10, 10), - best_finalized_peer_at_best_self: HeaderId(0, 0), - actual_best_finalized_peer_at_best_self: HeaderId(0, 0), - }, - source_latest_generated_nonce: 10, - target_state: ClientState { - best_self: HeaderId(0, 0), - best_finalized_self: HeaderId(0, 0), - best_finalized_peer_at_best_self: HeaderId(0, 0), - actual_best_finalized_peer_at_best_self: HeaderId(0, 0), - }, - target_latest_received_nonce: 0, - ..Default::default() - }, - Arc::new(|data: &mut TestClientData| { - // blocks are produced on every tick - data.source_state.best_self = - HeaderId(data.source_state.best_self.0 + 1, data.source_state.best_self.1 + 1); - data.source_state.best_finalized_self = data.source_state.best_self; - // headers relay must only be started when we need new target headers at source node - if data.target_to_source_header_required.is_some() { - assert!( - data.source_state.best_finalized_peer_at_best_self.0 - < data.target_state.best_self.0 - ); - data.target_to_source_header_required = None; - } - // syncing target headers -> source chain - if let Some(last_requirement) = data.target_to_source_header_requirements.last() { - if *last_requirement != data.source_state.best_finalized_peer_at_best_self { - data.source_state.best_finalized_peer_at_best_self = *last_requirement; - } - } - }), - Arc::new(move |data: &mut TestClientData| { - // blocks are produced on every tick - data.target_state.best_self = - HeaderId(data.target_state.best_self.0 + 1, data.target_state.best_self.1 + 1); - data.target_state.best_finalized_self = data.target_state.best_self; - // headers relay must only be started when we need new source headers at target node - if data.source_to_target_header_required.is_some() { - assert!( - data.target_state.best_finalized_peer_at_best_self.0 - < data.source_state.best_self.0 - ); - data.source_to_target_header_required = None; - } - // syncing source headers -> target chain - if let Some(last_requirement) = data.source_to_target_header_requirements.last() { - if *last_requirement != data.target_state.best_finalized_peer_at_best_self { - data.target_state.best_finalized_peer_at_best_self = *last_requirement; - } - } - // if source has received all messages receiving confirmations => stop - if data.source_latest_confirmed_received_nonce == 10 { - exit_sender.unbounded_send(()).unwrap(); - } - }), - exit_receiver.into_future().map(|(_, _)| ()), - ); - - // there are no strict restrictions on when reward confirmation should come - // (because `max_unconfirmed_nonces_at_target` is `100` in tests and this confirmation - // depends on the state of both clients) - // => we do not check it here - assert_eq!(result.submitted_messages_proofs[0].0, 1..=4); - assert_eq!(result.submitted_messages_proofs[1].0, 5..=8); - assert_eq!(result.submitted_messages_proofs[2].0, 9..=10); - assert!(!result.submitted_messages_receiving_proofs.is_empty()); - - // check that we have at least once required new source->target or target->source headers - assert!(!result.target_to_source_header_requirements.is_empty()); - assert!(!result.source_to_target_header_requirements.is_empty()); - } -} diff --git a/relays/messages/src/message_race_delivery.rs b/relays/messages/src/message_race_delivery.rs deleted file mode 100644 index 896e37075..000000000 --- a/relays/messages/src/message_race_delivery.rs +++ /dev/null @@ -1,1071 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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. - -//! Message delivery race delivers proof-of-messages from "lane.source" to "lane.target". - -use std::{collections::VecDeque, marker::PhantomData, ops::RangeInclusive, time::Duration}; - -use async_trait::async_trait; -use futures::stream::FusedStream; - -use bp_messages::{MessageNonce, UnrewardedRelayersState, Weight}; -use relay_utils::FailedClient; - -use crate::{ - message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf}, - message_lane_loop::{ - MessageDeliveryParams, MessageDetailsMap, MessageProofParameters, - SourceClient as MessageLaneSourceClient, SourceClientState, - TargetClient as MessageLaneTargetClient, TargetClientState, - }, - message_race_loop::{ - MessageRace, NoncesRange, RaceState, RaceStrategy, SourceClient, SourceClientNonces, - TargetClient, TargetClientNonces, - }, - message_race_strategy::BasicStrategy, - metrics::MessageLaneLoopMetrics, - relay_strategy::{EnforcementStrategy, RelayMessagesBatchReference, RelayStrategy}, -}; - -/// Run message delivery race. -pub async fn run( - source_client: impl MessageLaneSourceClient

, - source_state_updates: impl FusedStream>, - target_client: impl MessageLaneTargetClient

, - target_state_updates: impl FusedStream>, - stall_timeout: Duration, - metrics_msg: Option, - params: MessageDeliveryParams, -) -> Result<(), FailedClient> { - crate::message_race_loop::run( - MessageDeliveryRaceSource { - client: source_client.clone(), - metrics_msg: metrics_msg.clone(), - _phantom: Default::default(), - }, - source_state_updates, - MessageDeliveryRaceTarget { - client: target_client.clone(), - metrics_msg, - _phantom: Default::default(), - }, - target_state_updates, - stall_timeout, - MessageDeliveryStrategy:: { - lane_source_client: source_client, - lane_target_client: target_client, - max_unrewarded_relayer_entries_at_target: params - .max_unrewarded_relayer_entries_at_target, - max_unconfirmed_nonces_at_target: params.max_unconfirmed_nonces_at_target, - max_messages_in_single_batch: params.max_messages_in_single_batch, - max_messages_weight_in_single_batch: params.max_messages_weight_in_single_batch, - max_messages_size_in_single_batch: params.max_messages_size_in_single_batch, - relay_strategy: params.relay_strategy, - latest_confirmed_nonces_at_source: VecDeque::new(), - target_nonces: None, - strategy: BasicStrategy::new(), - }, - ) - .await -} - -/// Message delivery race. -struct MessageDeliveryRace

(std::marker::PhantomData

); - -impl MessageRace for MessageDeliveryRace

{ - type MessageNonce = MessageNonce; - type Proof = P::MessagesProof; - type SourceHeaderId = SourceHeaderIdOf

; - type TargetHeaderId = TargetHeaderIdOf

; - - fn source_name() -> String { - format!("{}::MessagesDelivery", P::SOURCE_NAME) - } - - fn target_name() -> String { - format!("{}::MessagesDelivery", P::TARGET_NAME) - } -} - -/// Message delivery race source, which is a source of the lane. -struct MessageDeliveryRaceSource { - client: C, - metrics_msg: Option, - _phantom: PhantomData

, -} - -#[async_trait] -impl SourceClient> for MessageDeliveryRaceSource -where - P: MessageLane, - C: MessageLaneSourceClient

, -{ - type Error = C::Error; - type NoncesRange = MessageDetailsMap; - type ProofParameters = MessageProofParameters; - - async fn nonces( - &self, - at_block: SourceHeaderIdOf

, - prev_latest_nonce: MessageNonce, - ) -> Result<(SourceHeaderIdOf

, SourceClientNonces), Self::Error> { - let (at_block, latest_generated_nonce) = - self.client.latest_generated_nonce(at_block).await?; - let (at_block, latest_confirmed_nonce) = - self.client.latest_confirmed_received_nonce(at_block).await?; - - if let Some(metrics_msg) = self.metrics_msg.as_ref() { - metrics_msg.update_source_latest_generated_nonce::

(latest_generated_nonce); - metrics_msg.update_source_latest_confirmed_nonce::

(latest_confirmed_nonce); - } - - let new_nonces = if latest_generated_nonce > prev_latest_nonce { - self.client - .generated_message_details( - at_block.clone(), - prev_latest_nonce + 1..=latest_generated_nonce, - ) - .await? - } else { - MessageDetailsMap::new() - }; - - Ok(( - at_block, - SourceClientNonces { new_nonces, confirmed_nonce: Some(latest_confirmed_nonce) }, - )) - } - - async fn generate_proof( - &self, - at_block: SourceHeaderIdOf

, - nonces: RangeInclusive, - proof_parameters: Self::ProofParameters, - ) -> Result<(SourceHeaderIdOf

, RangeInclusive, P::MessagesProof), Self::Error> - { - self.client.prove_messages(at_block, nonces, proof_parameters).await - } -} - -/// Message delivery race target, which is a target of the lane. -struct MessageDeliveryRaceTarget { - client: C, - metrics_msg: Option, - _phantom: PhantomData

, -} - -#[async_trait] -impl TargetClient> for MessageDeliveryRaceTarget -where - P: MessageLane, - C: MessageLaneTargetClient

, -{ - type Error = C::Error; - type TargetNoncesData = DeliveryRaceTargetNoncesData; - - async fn require_source_header(&self, id: SourceHeaderIdOf

) { - self.client.require_source_header_on_target(id).await - } - - async fn nonces( - &self, - at_block: TargetHeaderIdOf

, - update_metrics: bool, - ) -> Result<(TargetHeaderIdOf

, TargetClientNonces), Self::Error> - { - let (at_block, latest_received_nonce) = self.client.latest_received_nonce(at_block).await?; - let (at_block, latest_confirmed_nonce) = - self.client.latest_confirmed_received_nonce(at_block).await?; - let (at_block, unrewarded_relayers) = - self.client.unrewarded_relayers_state(at_block).await?; - - if update_metrics { - if let Some(metrics_msg) = self.metrics_msg.as_ref() { - metrics_msg.update_target_latest_received_nonce::

(latest_received_nonce); - metrics_msg.update_target_latest_confirmed_nonce::

(latest_confirmed_nonce); - } - } - - Ok(( - at_block, - TargetClientNonces { - latest_nonce: latest_received_nonce, - nonces_data: DeliveryRaceTargetNoncesData { - confirmed_nonce: latest_confirmed_nonce, - unrewarded_relayers, - }, - }, - )) - } - - async fn submit_proof( - &self, - generated_at_block: SourceHeaderIdOf

, - nonces: RangeInclusive, - proof: P::MessagesProof, - ) -> Result, Self::Error> { - self.client.submit_messages_proof(generated_at_block, nonces, proof).await - } -} - -/// Additional nonces data from the target client used by message delivery race. -#[derive(Debug, Clone)] -struct DeliveryRaceTargetNoncesData { - /// The latest nonce that we know: (1) has been delivered to us (2) has been confirmed - /// back to the source node (by confirmations race) and (3) relayer has received - /// reward for (and this has been confirmed by the message delivery race). - confirmed_nonce: MessageNonce, - /// State of the unrewarded relayers set at the target node. - unrewarded_relayers: UnrewardedRelayersState, -} - -/// Messages delivery strategy. -struct MessageDeliveryStrategy { - /// The client that is connected to the message lane source node. - lane_source_client: SC, - /// The client that is connected to the message lane target node. - lane_target_client: TC, - /// Maximal unrewarded relayer entries at target client. - max_unrewarded_relayer_entries_at_target: MessageNonce, - /// Maximal unconfirmed nonces at target client. - max_unconfirmed_nonces_at_target: MessageNonce, - /// Maximal number of messages in the single delivery transaction. - max_messages_in_single_batch: MessageNonce, - /// Maximal cumulative messages weight in the single delivery transaction. - max_messages_weight_in_single_batch: Weight, - /// Maximal messages size in the single delivery transaction. - max_messages_size_in_single_batch: u32, - /// Relayer operating mode. - relay_strategy: Strategy, - /// Latest confirmed nonces at the source client + the header id where we have first met this - /// nonce. - latest_confirmed_nonces_at_source: VecDeque<(SourceHeaderIdOf

, MessageNonce)>, - /// Target nonces from the source client. - target_nonces: Option>, - /// Basic delivery strategy. - strategy: MessageDeliveryStrategyBase

, -} - -type MessageDeliveryStrategyBase

= BasicStrategy< -

::SourceHeaderNumber, -

::SourceHeaderHash, -

::TargetHeaderNumber, -

::TargetHeaderHash, - MessageDetailsMap<

::SourceChainBalance>, -

::MessagesProof, ->; - -impl std::fmt::Debug - for MessageDeliveryStrategy -{ - fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { - fmt.debug_struct("MessageDeliveryStrategy") - .field( - "max_unrewarded_relayer_entries_at_target", - &self.max_unrewarded_relayer_entries_at_target, - ) - .field("max_unconfirmed_nonces_at_target", &self.max_unconfirmed_nonces_at_target) - .field("max_messages_in_single_batch", &self.max_messages_in_single_batch) - .field("max_messages_weight_in_single_batch", &self.max_messages_weight_in_single_batch) - .field("max_messages_size_in_single_batch", &self.max_messages_size_in_single_batch) - .field("latest_confirmed_nonces_at_source", &self.latest_confirmed_nonces_at_source) - .field("target_nonces", &self.target_nonces) - .field("strategy", &self.strategy) - .finish() - } -} - -impl MessageDeliveryStrategy { - /// Returns total weight of all undelivered messages. - fn total_queued_dispatch_weight(&self) -> Weight { - self.strategy - .source_queue() - .iter() - .flat_map(|(_, range)| range.values().map(|details| details.dispatch_weight)) - .fold(0, |total, weight| total.saturating_add(weight)) - } -} - -#[async_trait] -impl - RaceStrategy, TargetHeaderIdOf

, P::MessagesProof> - for MessageDeliveryStrategy -where - P: MessageLane, - SC: MessageLaneSourceClient

, - TC: MessageLaneTargetClient

, -{ - type ProofParameters = MessageProofParameters; - type SourceNoncesRange = MessageDetailsMap; - type TargetNoncesData = DeliveryRaceTargetNoncesData; - - fn is_empty(&self) -> bool { - self.strategy.is_empty() - } - - fn required_source_header_at_target( - &self, - current_best: &SourceHeaderIdOf

, - ) -> Option> { - let header_required_for_messages_delivery = - self.strategy.required_source_header_at_target(current_best); - let header_required_for_reward_confirmations_delivery = - self.latest_confirmed_nonces_at_source.back().map(|(id, _)| id.clone()); - match ( - header_required_for_messages_delivery, - header_required_for_reward_confirmations_delivery, - ) { - (Some(id1), Some(id2)) => Some(if id1.0 > id2.0 { id1 } else { id2 }), - (a, b) => a.or(b), - } - } - - fn best_at_source(&self) -> Option { - self.strategy.best_at_source() - } - - fn best_at_target(&self) -> Option { - self.strategy.best_at_target() - } - - fn source_nonces_updated( - &mut self, - at_block: SourceHeaderIdOf

, - nonces: SourceClientNonces, - ) { - if let Some(confirmed_nonce) = nonces.confirmed_nonce { - let is_confirmed_nonce_updated = self - .latest_confirmed_nonces_at_source - .back() - .map(|(_, prev_nonce)| *prev_nonce != confirmed_nonce) - .unwrap_or(true); - if is_confirmed_nonce_updated { - self.latest_confirmed_nonces_at_source - .push_back((at_block.clone(), confirmed_nonce)); - } - } - self.strategy.source_nonces_updated(at_block, nonces) - } - - fn best_target_nonces_updated( - &mut self, - nonces: TargetClientNonces, - race_state: &mut RaceState, TargetHeaderIdOf

, P::MessagesProof>, - ) { - // best target nonces must always be ge than finalized target nonces - let mut target_nonces = self.target_nonces.take().unwrap_or_else(|| nonces.clone()); - target_nonces.nonces_data = nonces.nonces_data.clone(); - target_nonces.latest_nonce = std::cmp::max(target_nonces.latest_nonce, nonces.latest_nonce); - self.target_nonces = Some(target_nonces); - - self.strategy.best_target_nonces_updated( - TargetClientNonces { latest_nonce: nonces.latest_nonce, nonces_data: () }, - race_state, - ) - } - - fn finalized_target_nonces_updated( - &mut self, - nonces: TargetClientNonces, - race_state: &mut RaceState, TargetHeaderIdOf

, P::MessagesProof>, - ) { - if let Some(ref best_finalized_source_header_id_at_best_target) = - race_state.best_finalized_source_header_id_at_best_target - { - let oldest_header_number_to_keep = best_finalized_source_header_id_at_best_target.0; - while self - .latest_confirmed_nonces_at_source - .front() - .map(|(id, _)| id.0 < oldest_header_number_to_keep) - .unwrap_or(false) - { - self.latest_confirmed_nonces_at_source.pop_front(); - } - } - - if let Some(ref mut target_nonces) = self.target_nonces { - target_nonces.latest_nonce = - std::cmp::max(target_nonces.latest_nonce, nonces.latest_nonce); - } - - self.strategy.finalized_target_nonces_updated( - TargetClientNonces { latest_nonce: nonces.latest_nonce, nonces_data: () }, - race_state, - ) - } - - async fn select_nonces_to_deliver( - &mut self, - race_state: RaceState, TargetHeaderIdOf

, P::MessagesProof>, - ) -> Option<(RangeInclusive, Self::ProofParameters)> { - let best_finalized_source_header_id_at_best_target = - race_state.best_finalized_source_header_id_at_best_target.clone()?; - let latest_confirmed_nonce_at_source = self - .latest_confirmed_nonces_at_source - .iter() - .take_while(|(id, _)| id.0 <= best_finalized_source_header_id_at_best_target.0) - .last() - .map(|(_, nonce)| *nonce)?; - let target_nonces = self.target_nonces.as_ref()?; - - // There's additional condition in the message delivery race: target would reject messages - // if there are too much unconfirmed messages at the inbound lane. - - // The receiving race is responsible to deliver confirmations back to the source chain. So - // if there's a lot of unconfirmed messages, let's wait until it'll be able to do its job. - let latest_received_nonce_at_target = target_nonces.latest_nonce; - let confirmations_missing = - latest_received_nonce_at_target.checked_sub(latest_confirmed_nonce_at_source); - match confirmations_missing { - Some(confirmations_missing) - if confirmations_missing >= self.max_unconfirmed_nonces_at_target => - { - log::debug!( - target: "bridge", - "Cannot deliver any more messages from {} to {}. Too many unconfirmed nonces \ - at target: target.latest_received={:?}, source.latest_confirmed={:?}, max={:?}", - MessageDeliveryRace::

::source_name(), - MessageDeliveryRace::

::target_name(), - latest_received_nonce_at_target, - latest_confirmed_nonce_at_source, - self.max_unconfirmed_nonces_at_target, - ); - - return None; - }, - _ => (), - } - - // Ok - we may have new nonces to deliver. But target may still reject new messages, because - // we haven't notified it that (some) messages have been confirmed. So we may want to - // include updated `source.latest_confirmed` in the proof. - // - // Important note: we're including outbound state lane proof whenever there are unconfirmed - // nonces on the target chain. Other strategy is to include it only if it's absolutely - // necessary. - let latest_confirmed_nonce_at_target = target_nonces.nonces_data.confirmed_nonce; - let outbound_state_proof_required = - latest_confirmed_nonce_at_target < latest_confirmed_nonce_at_source; - - // The target node would also reject messages if there are too many entries in the - // "unrewarded relayers" set. If we are unable to prove new rewards to the target node, then - // we should wait for confirmations race. - let unrewarded_relayer_entries_limit_reached = - target_nonces.nonces_data.unrewarded_relayers.unrewarded_relayer_entries - >= self.max_unrewarded_relayer_entries_at_target; - if unrewarded_relayer_entries_limit_reached { - // so there are already too many unrewarded relayer entries in the set - // - // => check if we can prove enough rewards. If not, we should wait for more rewards to - // be paid - let number_of_rewards_being_proved = - latest_confirmed_nonce_at_source.saturating_sub(latest_confirmed_nonce_at_target); - let enough_rewards_being_proved = number_of_rewards_being_proved - >= target_nonces.nonces_data.unrewarded_relayers.messages_in_oldest_entry; - if !enough_rewards_being_proved { - return None; - } - } - - // If we're here, then the confirmations race did its job && sending side now knows that - // messages have been delivered. Now let's select nonces that we want to deliver. - // - // We may deliver at most: - // - // max_unconfirmed_nonces_at_target - (latest_received_nonce_at_target - - // latest_confirmed_nonce_at_target) - // - // messages in the batch. But since we're including outbound state proof in the batch, then - // it may be increased to: - // - // max_unconfirmed_nonces_at_target - (latest_received_nonce_at_target - - // latest_confirmed_nonce_at_source) - let future_confirmed_nonce_at_target = if outbound_state_proof_required { - latest_confirmed_nonce_at_source - } else { - latest_confirmed_nonce_at_target - }; - let max_nonces = latest_received_nonce_at_target - .checked_sub(future_confirmed_nonce_at_target) - .and_then(|diff| self.max_unconfirmed_nonces_at_target.checked_sub(diff)) - .unwrap_or_default(); - let max_nonces = std::cmp::min(max_nonces, self.max_messages_in_single_batch); - let max_messages_weight_in_single_batch = self.max_messages_weight_in_single_batch; - let max_messages_size_in_single_batch = self.max_messages_size_in_single_batch; - let lane_source_client = self.lane_source_client.clone(); - let lane_target_client = self.lane_target_client.clone(); - - let maximal_source_queue_index = - self.strategy.maximal_available_source_queue_index(race_state)?; - let previous_total_dispatch_weight = self.total_queued_dispatch_weight(); - let source_queue = self.strategy.source_queue(); - - let reference = RelayMessagesBatchReference { - max_messages_in_this_batch: max_nonces, - max_messages_weight_in_single_batch, - max_messages_size_in_single_batch, - lane_source_client: lane_source_client.clone(), - lane_target_client: lane_target_client.clone(), - nonces_queue: source_queue.clone(), - nonces_queue_range: 0..maximal_source_queue_index + 1, - }; - - let mut strategy = EnforcementStrategy::new(self.relay_strategy.clone()); - let range_end = strategy.decide(reference).await?; - - let range_begin = source_queue[0].1.begin(); - let selected_nonces = range_begin..=range_end; - self.strategy.remove_le_nonces_from_source_queue(range_end); - - let new_total_dispatch_weight = self.total_queued_dispatch_weight(); - let dispatch_weight = previous_total_dispatch_weight - new_total_dispatch_weight; - - Some(( - selected_nonces, - MessageProofParameters { outbound_state_proof_required, dispatch_weight }, - )) - } -} - -impl NoncesRange for MessageDetailsMap { - fn begin(&self) -> MessageNonce { - self.keys().next().cloned().unwrap_or_default() - } - - fn end(&self) -> MessageNonce { - self.keys().next_back().cloned().unwrap_or_default() - } - - fn greater_than(mut self, nonce: MessageNonce) -> Option { - let gte = self.split_off(&(nonce + 1)); - if gte.is_empty() { - None - } else { - Some(gte) - } - } -} - -#[cfg(test)] -mod tests { - use bp_runtime::messages::DispatchFeePayment; - - use crate::{ - message_lane_loop::{ - tests::{ - header_id, TestMessageLane, TestMessagesProof, TestSourceChainBalance, - TestSourceClient, TestSourceHeaderId, TestTargetClient, TestTargetHeaderId, - BASE_MESSAGE_DELIVERY_TRANSACTION_COST, CONFIRMATION_TRANSACTION_COST, - }, - MessageDetails, RelayerMode, - }, - relay_strategy::MixStrategy, - }; - - use super::*; - - const DEFAULT_DISPATCH_WEIGHT: Weight = 1; - const DEFAULT_SIZE: u32 = 1; - const DEFAULT_REWARD: TestSourceChainBalance = CONFIRMATION_TRANSACTION_COST - + BASE_MESSAGE_DELIVERY_TRANSACTION_COST - + DEFAULT_DISPATCH_WEIGHT - + (DEFAULT_SIZE as TestSourceChainBalance); - - type TestRaceState = RaceState; - type TestStrategy = - MessageDeliveryStrategy; - - fn source_nonces( - new_nonces: RangeInclusive, - confirmed_nonce: MessageNonce, - reward: TestSourceChainBalance, - dispatch_fee_payment: DispatchFeePayment, - ) -> SourceClientNonces> { - SourceClientNonces { - new_nonces: new_nonces - .into_iter() - .map(|nonce| { - ( - nonce, - MessageDetails { - dispatch_weight: DEFAULT_DISPATCH_WEIGHT, - size: DEFAULT_SIZE, - reward, - dispatch_fee_payment, - }, - ) - }) - .into_iter() - .collect(), - confirmed_nonce: Some(confirmed_nonce), - } - } - - fn prepare_strategy() -> (TestRaceState, TestStrategy) { - let mut race_state = RaceState { - best_finalized_source_header_id_at_source: Some(header_id(1)), - best_finalized_source_header_id_at_best_target: Some(header_id(1)), - best_target_header_id: Some(header_id(1)), - best_finalized_target_header_id: Some(header_id(1)), - nonces_to_submit: None, - nonces_submitted: None, - }; - - let mut race_strategy = TestStrategy { - max_unrewarded_relayer_entries_at_target: 4, - max_unconfirmed_nonces_at_target: 4, - max_messages_in_single_batch: 4, - max_messages_weight_in_single_batch: 4, - max_messages_size_in_single_batch: 4, - latest_confirmed_nonces_at_source: vec![(header_id(1), 19)].into_iter().collect(), - lane_source_client: TestSourceClient::default(), - lane_target_client: TestTargetClient::default(), - target_nonces: Some(TargetClientNonces { - latest_nonce: 19, - nonces_data: DeliveryRaceTargetNoncesData { - confirmed_nonce: 19, - unrewarded_relayers: UnrewardedRelayersState { - unrewarded_relayer_entries: 0, - messages_in_oldest_entry: 0, - total_messages: 0, - }, - }, - }), - strategy: BasicStrategy::new(), - relay_strategy: MixStrategy::new(RelayerMode::Altruistic), - }; - - race_strategy.strategy.source_nonces_updated( - header_id(1), - source_nonces(20..=23, 19, DEFAULT_REWARD, DispatchFeePayment::AtSourceChain), - ); - - let target_nonces = TargetClientNonces { latest_nonce: 19, nonces_data: () }; - race_strategy.strategy.best_target_nonces_updated(target_nonces.clone(), &mut race_state); - race_strategy.strategy.finalized_target_nonces_updated(target_nonces, &mut race_state); - - (race_state, race_strategy) - } - - fn proof_parameters(state_required: bool, weight: Weight) -> MessageProofParameters { - MessageProofParameters { - outbound_state_proof_required: state_required, - dispatch_weight: weight, - } - } - - #[test] - fn weights_map_works_as_nonces_range() { - fn build_map( - range: RangeInclusive, - ) -> MessageDetailsMap { - range - .map(|idx| { - ( - idx, - MessageDetails { - dispatch_weight: idx, - size: idx as _, - reward: idx as _, - dispatch_fee_payment: DispatchFeePayment::AtSourceChain, - }, - ) - }) - .collect() - } - - let map = build_map(20..=30); - - assert_eq!(map.begin(), 20); - assert_eq!(map.end(), 30); - assert_eq!(map.clone().greater_than(10), Some(build_map(20..=30))); - assert_eq!(map.clone().greater_than(19), Some(build_map(20..=30))); - assert_eq!(map.clone().greater_than(20), Some(build_map(21..=30))); - assert_eq!(map.clone().greater_than(25), Some(build_map(26..=30))); - assert_eq!(map.clone().greater_than(29), Some(build_map(30..=30))); - assert_eq!(map.greater_than(30), None); - } - - #[async_std::test] - async fn message_delivery_strategy_selects_messages_to_deliver() { - let (state, mut strategy) = prepare_strategy(); - - // both sides are ready to relay new messages - assert_eq!( - strategy.select_nonces_to_deliver(state).await, - Some(((20..=23), proof_parameters(false, 4))) - ); - } - - #[async_std::test] - async fn message_delivery_strategy_selects_nothing_if_too_many_confirmations_missing() { - let (state, mut strategy) = prepare_strategy(); - - // if there are already `max_unconfirmed_nonces_at_target` messages on target, - // we need to wait until confirmations will be delivered by receiving race - strategy.latest_confirmed_nonces_at_source = vec![( - header_id(1), - strategy.target_nonces.as_ref().unwrap().latest_nonce - - strategy.max_unconfirmed_nonces_at_target, - )] - .into_iter() - .collect(); - assert_eq!(strategy.select_nonces_to_deliver(state).await, None); - } - - #[async_std::test] - async fn message_delivery_strategy_includes_outbound_state_proof_when_new_nonces_are_available() - { - let (state, mut strategy) = prepare_strategy(); - - // if there are new confirmed nonces on source, we want to relay this information - // to target to prune rewards queue - let prev_confirmed_nonce_at_source = - strategy.latest_confirmed_nonces_at_source.back().unwrap().1; - strategy.target_nonces.as_mut().unwrap().nonces_data.confirmed_nonce = - prev_confirmed_nonce_at_source - 1; - assert_eq!( - strategy.select_nonces_to_deliver(state).await, - Some(((20..=23), proof_parameters(true, 4))) - ); - } - - #[async_std::test] - async fn message_delivery_strategy_selects_nothing_if_there_are_too_many_unrewarded_relayers() { - let (state, mut strategy) = prepare_strategy(); - - // if there are already `max_unrewarded_relayer_entries_at_target` entries at target, - // we need to wait until rewards will be paid - { - let mut unrewarded_relayers = - &mut strategy.target_nonces.as_mut().unwrap().nonces_data.unrewarded_relayers; - unrewarded_relayers.unrewarded_relayer_entries = - strategy.max_unrewarded_relayer_entries_at_target; - unrewarded_relayers.messages_in_oldest_entry = 4; - } - assert_eq!(strategy.select_nonces_to_deliver(state).await, None); - } - - #[async_std::test] - async fn message_delivery_strategy_selects_nothing_if_proved_rewards_is_not_enough_to_remove_oldest_unrewarded_entry( - ) { - let (state, mut strategy) = prepare_strategy(); - - // if there are already `max_unrewarded_relayer_entries_at_target` entries at target, - // we need to prove at least `messages_in_oldest_entry` rewards - let prev_confirmed_nonce_at_source = - strategy.latest_confirmed_nonces_at_source.back().unwrap().1; - { - let mut nonces_data = &mut strategy.target_nonces.as_mut().unwrap().nonces_data; - nonces_data.confirmed_nonce = prev_confirmed_nonce_at_source - 1; - let mut unrewarded_relayers = &mut nonces_data.unrewarded_relayers; - unrewarded_relayers.unrewarded_relayer_entries = - strategy.max_unrewarded_relayer_entries_at_target; - unrewarded_relayers.messages_in_oldest_entry = 4; - } - assert_eq!(strategy.select_nonces_to_deliver(state).await, None); - } - - #[async_std::test] - async fn message_delivery_strategy_includes_outbound_state_proof_if_proved_rewards_is_enough() { - let (state, mut strategy) = prepare_strategy(); - - // if there are already `max_unrewarded_relayer_entries_at_target` entries at target, - // we need to prove at least `messages_in_oldest_entry` rewards - let prev_confirmed_nonce_at_source = - strategy.latest_confirmed_nonces_at_source.back().unwrap().1; - { - let mut nonces_data = &mut strategy.target_nonces.as_mut().unwrap().nonces_data; - nonces_data.confirmed_nonce = prev_confirmed_nonce_at_source - 3; - let mut unrewarded_relayers = &mut nonces_data.unrewarded_relayers; - unrewarded_relayers.unrewarded_relayer_entries = - strategy.max_unrewarded_relayer_entries_at_target; - unrewarded_relayers.messages_in_oldest_entry = 3; - } - assert_eq!( - strategy.select_nonces_to_deliver(state).await, - Some(((20..=23), proof_parameters(true, 4))) - ); - } - - #[async_std::test] - async fn message_delivery_strategy_limits_batch_by_messages_weight() { - let (state, mut strategy) = prepare_strategy(); - - // not all queued messages may fit in the batch, because batch has max weight - strategy.max_messages_weight_in_single_batch = 3; - assert_eq!( - strategy.select_nonces_to_deliver(state).await, - Some(((20..=22), proof_parameters(false, 3))) - ); - } - - #[async_std::test] - async fn message_delivery_strategy_accepts_single_message_even_if_its_weight_overflows_maximal_weight( - ) { - let (state, mut strategy) = prepare_strategy(); - - // first message doesn't fit in the batch, because it has weight (10) that overflows max - // weight (4) - strategy.strategy.source_queue_mut()[0].1.get_mut(&20).unwrap().dispatch_weight = 10; - assert_eq!( - strategy.select_nonces_to_deliver(state).await, - Some(((20..=20), proof_parameters(false, 10))) - ); - } - - #[async_std::test] - async fn message_delivery_strategy_limits_batch_by_messages_size() { - let (state, mut strategy) = prepare_strategy(); - - // not all queued messages may fit in the batch, because batch has max weight - strategy.max_messages_size_in_single_batch = 3; - assert_eq!( - strategy.select_nonces_to_deliver(state).await, - Some(((20..=22), proof_parameters(false, 3))) - ); - } - - #[async_std::test] - async fn message_delivery_strategy_accepts_single_message_even_if_its_weight_overflows_maximal_size( - ) { - let (state, mut strategy) = prepare_strategy(); - - // first message doesn't fit in the batch, because it has weight (10) that overflows max - // weight (4) - strategy.strategy.source_queue_mut()[0].1.get_mut(&20).unwrap().size = 10; - assert_eq!( - strategy.select_nonces_to_deliver(state).await, - Some(((20..=20), proof_parameters(false, 1))) - ); - } - - #[async_std::test] - async fn message_delivery_strategy_limits_batch_by_messages_count_when_there_is_upper_limit() { - let (state, mut strategy) = prepare_strategy(); - - // not all queued messages may fit in the batch, because batch has max number of messages - // limit - strategy.max_messages_in_single_batch = 3; - assert_eq!( - strategy.select_nonces_to_deliver(state).await, - Some(((20..=22), proof_parameters(false, 3))) - ); - } - - #[async_std::test] - async fn message_delivery_strategy_limits_batch_by_messages_count_when_there_are_unconfirmed_nonces( - ) { - let (state, mut strategy) = prepare_strategy(); - - // 1 delivery confirmation from target to source is still missing, so we may only - // relay 3 new messages - let prev_confirmed_nonce_at_source = - strategy.latest_confirmed_nonces_at_source.back().unwrap().1; - strategy.latest_confirmed_nonces_at_source = - vec![(header_id(1), prev_confirmed_nonce_at_source - 1)].into_iter().collect(); - strategy.target_nonces.as_mut().unwrap().nonces_data.confirmed_nonce = - prev_confirmed_nonce_at_source - 1; - assert_eq!( - strategy.select_nonces_to_deliver(state).await, - Some(((20..=22), proof_parameters(false, 3))) - ); - } - - #[async_std::test] - async fn message_delivery_strategy_waits_for_confirmed_nonce_header_to_appear_on_target() { - // 1 delivery confirmation from target to source is still missing, so we may deliver - // reward confirmation with our message delivery transaction. But the problem is that - // the reward has been paid at header 2 && this header is still unknown to target node. - // - // => so we can't deliver more than 3 messages - let (mut state, mut strategy) = prepare_strategy(); - let prev_confirmed_nonce_at_source = - strategy.latest_confirmed_nonces_at_source.back().unwrap().1; - strategy.latest_confirmed_nonces_at_source = vec![ - (header_id(1), prev_confirmed_nonce_at_source - 1), - (header_id(2), prev_confirmed_nonce_at_source), - ] - .into_iter() - .collect(); - strategy.target_nonces.as_mut().unwrap().nonces_data.confirmed_nonce = - prev_confirmed_nonce_at_source - 1; - state.best_finalized_source_header_id_at_best_target = Some(header_id(1)); - assert_eq!( - strategy.select_nonces_to_deliver(state).await, - Some(((20..=22), proof_parameters(false, 3))) - ); - - // the same situation, but the header 2 is known to the target node, so we may deliver - // reward confirmation - let (mut state, mut strategy) = prepare_strategy(); - let prev_confirmed_nonce_at_source = - strategy.latest_confirmed_nonces_at_source.back().unwrap().1; - strategy.latest_confirmed_nonces_at_source = vec![ - (header_id(1), prev_confirmed_nonce_at_source - 1), - (header_id(2), prev_confirmed_nonce_at_source), - ] - .into_iter() - .collect(); - strategy.target_nonces.as_mut().unwrap().nonces_data.confirmed_nonce = - prev_confirmed_nonce_at_source - 1; - state.best_finalized_source_header_id_at_source = Some(header_id(2)); - state.best_finalized_source_header_id_at_best_target = Some(header_id(2)); - assert_eq!( - strategy.select_nonces_to_deliver(state).await, - Some(((20..=23), proof_parameters(true, 4))) - ); - } - - #[async_std::test] - async fn source_header_is_required_when_confirmations_are_required() { - // let's prepare situation when: - // - all messages [20; 23] have been generated at source block#1; - let (mut state, mut strategy) = prepare_strategy(); - // - // - messages [20; 21] have been delivered, but messages [11; 20] can't be delivered because - // of unrewarded relayers vector capacity; - strategy.max_unconfirmed_nonces_at_target = 2; - assert_eq!( - strategy.select_nonces_to_deliver(state.clone()).await, - Some(((20..=21), proof_parameters(false, 2))) - ); - strategy.finalized_target_nonces_updated( - TargetClientNonces { - latest_nonce: 21, - nonces_data: DeliveryRaceTargetNoncesData { - confirmed_nonce: 19, - unrewarded_relayers: UnrewardedRelayersState { - unrewarded_relayer_entries: 2, - messages_in_oldest_entry: 2, - total_messages: 2, - }, - }, - }, - &mut state, - ); - assert_eq!(strategy.select_nonces_to_deliver(state).await, None); - // - // - messages [1; 10] receiving confirmation has been delivered at source block#2; - strategy.source_nonces_updated( - header_id(2), - SourceClientNonces { new_nonces: MessageDetailsMap::new(), confirmed_nonce: Some(21) }, - ); - // - // - so now we'll need to relay source block#11 to be able to accept messages [11; 20]. - assert_eq!(strategy.required_source_header_at_target(&header_id(1)), Some(header_id(2))); - } - - #[async_std::test] - async fn rational_relayer_is_delivering_messages_if_cost_is_equal_to_reward() { - let (state, mut strategy) = prepare_strategy(); - strategy.relay_strategy = MixStrategy::new(RelayerMode::Rational); - - // so now we have: - // - 20..=23 with reward = cost - // => strategy shall select all 20..=23 - assert_eq!( - strategy.select_nonces_to_deliver(state).await, - Some(((20..=23), proof_parameters(false, 4))) - ); - } - - #[async_std::test] - async fn rational_relayer_is_not_delivering_messages_if_cost_is_larger_than_reward() { - let (mut state, mut strategy) = prepare_strategy(); - let nonces = source_nonces( - 24..=25, - 19, - DEFAULT_REWARD - BASE_MESSAGE_DELIVERY_TRANSACTION_COST, - DispatchFeePayment::AtSourceChain, - ); - strategy.strategy.source_nonces_updated(header_id(2), nonces); - state.best_finalized_source_header_id_at_best_target = Some(header_id(2)); - strategy.relay_strategy = MixStrategy::new(RelayerMode::Rational); - - // so now we have: - // - 20..=23 with reward = cost - // - 24..=25 with reward less than cost - // => strategy shall only select 20..=23 - assert_eq!( - strategy.select_nonces_to_deliver(state).await, - Some(((20..=23), proof_parameters(false, 4))) - ); - } - - #[async_std::test] - async fn rational_relayer_is_delivering_unpaid_messages() { - async fn test_with_dispatch_fee_payment( - dispatch_fee_payment: DispatchFeePayment, - ) -> Option<(RangeInclusive, MessageProofParameters)> { - let (mut state, mut strategy) = prepare_strategy(); - let nonces = source_nonces( - 24..=24, - 19, - DEFAULT_REWARD - DEFAULT_DISPATCH_WEIGHT, - dispatch_fee_payment, - ); - strategy.strategy.source_nonces_updated(header_id(2), nonces); - state.best_finalized_source_header_id_at_best_target = Some(header_id(2)); - strategy.max_unrewarded_relayer_entries_at_target = 100; - strategy.max_unconfirmed_nonces_at_target = 100; - strategy.max_messages_in_single_batch = 100; - strategy.max_messages_weight_in_single_batch = 100; - strategy.max_messages_size_in_single_batch = 100; - strategy.relay_strategy = MixStrategy::new(RelayerMode::Rational); - - // so now we have: - // - 20..=23 with reward = cost - // - 24..=24 with reward less than cost, but we're deducting `DEFAULT_DISPATCH_WEIGHT` - // from the cost, so it should be fine; - // => when MSG#24 fee is paid at the target chain, strategy shall select all 20..=24 - // => when MSG#25 fee is paid at the source chain, strategy shall only select 20..=23 - strategy.select_nonces_to_deliver(state).await - } - - assert_eq!( - test_with_dispatch_fee_payment(DispatchFeePayment::AtTargetChain).await, - Some(((20..=24), proof_parameters(false, 5))) - ); - assert_eq!( - test_with_dispatch_fee_payment(DispatchFeePayment::AtSourceChain).await, - Some(((20..=23), proof_parameters(false, 4))) - ); - } - - #[async_std::test] - async fn relayer_uses_flattened_view_of_the_source_queue_to_select_nonces() { - // Real scenario that has happened on test deployments: - // 1) relayer witnessed M1 at block 1 => it has separate entry in the `source_queue` - // 2) relayer witnessed M2 at block 2 => it has separate entry in the `source_queue` - // 3) if block 2 is known to the target node, then both M1 and M2 are selected for single - // delivery, even though weight(M1+M2) > larger than largest allowed weight - // - // This was happening because selector (`select_nonces_for_delivery_transaction`) has been - // called for every `source_queue` entry separately without preserving any context. - let (mut state, mut strategy) = prepare_strategy(); - let nonces = source_nonces(24..=25, 19, DEFAULT_REWARD, DispatchFeePayment::AtSourceChain); - strategy.strategy.source_nonces_updated(header_id(2), nonces); - strategy.max_unrewarded_relayer_entries_at_target = 100; - strategy.max_unconfirmed_nonces_at_target = 100; - strategy.max_messages_in_single_batch = 5; - strategy.max_messages_weight_in_single_batch = 100; - strategy.max_messages_size_in_single_batch = 100; - state.best_finalized_source_header_id_at_best_target = Some(header_id(2)); - - assert_eq!( - strategy.select_nonces_to_deliver(state).await, - Some(((20..=24), proof_parameters(false, 5))) - ); - } -} diff --git a/relays/messages/src/message_race_loop.rs b/relays/messages/src/message_race_loop.rs deleted file mode 100644 index 314008daa..000000000 --- a/relays/messages/src/message_race_loop.rs +++ /dev/null @@ -1,631 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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. - -//! Loop that is serving single race within message lane. This could be -//! message delivery race, receiving confirmations race or processing -//! confirmations race. -//! -//! The idea of the race is simple - we have `nonce`-s on source and target -//! nodes. We're trying to prove that the source node has this nonce (and -//! associated data - like messages, lane state, etc) to the target node by -//! generating and submitting proof. - -use crate::message_lane_loop::ClientState; - -use async_trait::async_trait; -use bp_messages::MessageNonce; -use futures::{ - future::FutureExt, - stream::{FusedStream, StreamExt}, -}; -use relay_utils::{process_future_result, retry_backoff, FailedClient, MaybeConnectionError}; -use std::{ - fmt::Debug, - ops::RangeInclusive, - time::{Duration, Instant}, -}; - -/// One of races within lane. -pub trait MessageRace { - /// Header id of the race source. - type SourceHeaderId: Debug + Clone + PartialEq; - /// Header id of the race source. - type TargetHeaderId: Debug + Clone + PartialEq; - - /// Message nonce used in the race. - type MessageNonce: Debug + Clone; - /// Proof that is generated and delivered in this race. - type Proof: Debug + Clone; - - /// Name of the race source. - fn source_name() -> String; - /// Name of the race target. - fn target_name() -> String; -} - -/// State of race source client. -type SourceClientState

= - ClientState<

::SourceHeaderId,

::TargetHeaderId>; - -/// State of race target client. -type TargetClientState

= - ClientState<

::TargetHeaderId,

::SourceHeaderId>; - -/// Inclusive nonces range. -pub trait NoncesRange: Debug + Sized { - /// Get begin of the range. - fn begin(&self) -> MessageNonce; - /// Get end of the range. - fn end(&self) -> MessageNonce; - /// Returns new range with current range nonces that are greater than the passed `nonce`. - /// If there are no such nonces, `None` is returned. - fn greater_than(self, nonce: MessageNonce) -> Option; -} - -/// Nonces on the race source client. -#[derive(Debug, Clone)] -pub struct SourceClientNonces { - /// New nonces range known to the client. `New` here means all nonces generated after - /// `prev_latest_nonce` passed to the `SourceClient::nonces` method. - pub new_nonces: NoncesRange, - /// The latest nonce that is confirmed to the bridged client. This nonce only makes - /// sense in some races. In other races it is `None`. - pub confirmed_nonce: Option, -} - -/// Nonces on the race target client. -#[derive(Debug, Clone)] -pub struct TargetClientNonces { - /// The latest nonce that is known to the target client. - pub latest_nonce: MessageNonce, - /// Additional data from target node that may be used by the race. - pub nonces_data: TargetNoncesData, -} - -/// One of message lane clients, which is source client for the race. -#[async_trait] -pub trait SourceClient { - /// Type of error these clients returns. - type Error: std::fmt::Debug + MaybeConnectionError; - /// Type of nonces range returned by the source client. - type NoncesRange: NoncesRange; - /// Additional proof parameters required to generate proof. - type ProofParameters; - - /// Return nonces that are known to the source client. - async fn nonces( - &self, - at_block: P::SourceHeaderId, - prev_latest_nonce: MessageNonce, - ) -> Result<(P::SourceHeaderId, SourceClientNonces), Self::Error>; - /// Generate proof for delivering to the target client. - async fn generate_proof( - &self, - at_block: P::SourceHeaderId, - nonces: RangeInclusive, - proof_parameters: Self::ProofParameters, - ) -> Result<(P::SourceHeaderId, RangeInclusive, P::Proof), Self::Error>; -} - -/// One of message lane clients, which is target client for the race. -#[async_trait] -pub trait TargetClient { - /// Type of error these clients returns. - type Error: std::fmt::Debug + MaybeConnectionError; - /// Type of the additional data from the target client, used by the race. - type TargetNoncesData: std::fmt::Debug; - - /// Ask headers relay to relay finalized headers up to (and including) given header - /// from race source to race target. - async fn require_source_header(&self, id: P::SourceHeaderId); - - /// Return nonces that are known to the target client. - async fn nonces( - &self, - at_block: P::TargetHeaderId, - update_metrics: bool, - ) -> Result<(P::TargetHeaderId, TargetClientNonces), Self::Error>; - /// Submit proof to the target client. - async fn submit_proof( - &self, - generated_at_block: P::SourceHeaderId, - nonces: RangeInclusive, - proof: P::Proof, - ) -> Result, Self::Error>; -} - -/// Race strategy. -#[async_trait] -pub trait RaceStrategy: Debug { - /// Type of nonces range expected from the source client. - type SourceNoncesRange: NoncesRange; - /// Additional proof parameters required to generate proof. - type ProofParameters; - /// Additional data expected from the target client. - type TargetNoncesData; - - /// Should return true if nothing has to be synced. - fn is_empty(&self) -> bool; - /// Return id of source header that is required to be on target to continue synchronization. - fn required_source_header_at_target( - &self, - current_best: &SourceHeaderId, - ) -> Option; - /// Return the best nonce at source node. - /// - /// `Some` is returned only if we are sure that the value is greater or equal - /// than the result of `best_at_target`. - fn best_at_source(&self) -> Option; - /// Return the best nonce at target node. - /// - /// May return `None` if value is yet unknown. - fn best_at_target(&self) -> Option; - - /// Called when nonces are updated at source node of the race. - fn source_nonces_updated( - &mut self, - at_block: SourceHeaderId, - nonces: SourceClientNonces, - ); - /// Called when best nonces are updated at target node of the race. - fn best_target_nonces_updated( - &mut self, - nonces: TargetClientNonces, - race_state: &mut RaceState, - ); - /// Called when finalized nonces are updated at target node of the race. - fn finalized_target_nonces_updated( - &mut self, - nonces: TargetClientNonces, - race_state: &mut RaceState, - ); - /// Should return `Some(nonces)` if we need to deliver proof of `nonces` (and associated - /// data) from source to target node. - /// Additionally, parameters required to generate proof are returned. - async fn select_nonces_to_deliver( - &mut self, - race_state: RaceState, - ) -> Option<(RangeInclusive, Self::ProofParameters)>; -} - -/// State of the race. -#[derive(Debug, Clone)] -pub struct RaceState { - /// Best finalized source header id at the source client. - pub best_finalized_source_header_id_at_source: Option, - /// Best finalized source header id at the best block on the target - /// client (at the `best_finalized_source_header_id_at_best_target`). - pub best_finalized_source_header_id_at_best_target: Option, - /// The best header id at the target client. - pub best_target_header_id: Option, - /// Best finalized header id at the target client. - pub best_finalized_target_header_id: Option, - /// Range of nonces that we have selected to submit. - pub nonces_to_submit: Option<(SourceHeaderId, RangeInclusive, Proof)>, - /// Range of nonces that is currently submitted. - pub nonces_submitted: Option>, -} - -/// Run race loop until connection with target or source node is lost. -pub async fn run, TC: TargetClient

>( - race_source: SC, - race_source_updated: impl FusedStream>, - race_target: TC, - race_target_updated: impl FusedStream>, - stall_timeout: Duration, - mut strategy: impl RaceStrategy< - P::SourceHeaderId, - P::TargetHeaderId, - P::Proof, - SourceNoncesRange = SC::NoncesRange, - ProofParameters = SC::ProofParameters, - TargetNoncesData = TC::TargetNoncesData, - >, -) -> Result<(), FailedClient> { - let mut progress_context = Instant::now(); - let mut race_state = RaceState::default(); - let mut stall_countdown = Instant::now(); - - let mut source_retry_backoff = retry_backoff(); - let mut source_client_is_online = true; - let mut source_nonces_required = false; - let source_nonces = futures::future::Fuse::terminated(); - let source_generate_proof = futures::future::Fuse::terminated(); - let source_go_offline_future = futures::future::Fuse::terminated(); - - let mut target_retry_backoff = retry_backoff(); - let mut target_client_is_online = true; - let mut target_best_nonces_required = false; - let mut target_finalized_nonces_required = false; - let target_best_nonces = futures::future::Fuse::terminated(); - let target_finalized_nonces = futures::future::Fuse::terminated(); - let target_submit_proof = futures::future::Fuse::terminated(); - let target_go_offline_future = futures::future::Fuse::terminated(); - - futures::pin_mut!( - race_source_updated, - source_nonces, - source_generate_proof, - source_go_offline_future, - race_target_updated, - target_best_nonces, - target_finalized_nonces, - target_submit_proof, - target_go_offline_future, - ); - - loop { - futures::select! { - // when headers ids are updated - source_state = race_source_updated.next() => { - if let Some(source_state) = source_state { - let is_source_state_updated = race_state.best_finalized_source_header_id_at_source.as_ref() - != Some(&source_state.best_finalized_self); - if is_source_state_updated { - source_nonces_required = true; - race_state.best_finalized_source_header_id_at_source = Some(source_state.best_finalized_self); - } - } - }, - target_state = race_target_updated.next() => { - if let Some(target_state) = target_state { - let is_target_best_state_updated = race_state.best_target_header_id.as_ref() - != Some(&target_state.best_self); - - if is_target_best_state_updated { - target_best_nonces_required = true; - race_state.best_target_header_id = Some(target_state.best_self); - race_state.best_finalized_source_header_id_at_best_target - = Some(target_state.best_finalized_peer_at_best_self); - } - - let is_target_finalized_state_updated = race_state.best_finalized_target_header_id.as_ref() - != Some(&target_state.best_finalized_self); - if is_target_finalized_state_updated { - target_finalized_nonces_required = true; - race_state.best_finalized_target_header_id = Some(target_state.best_finalized_self); - } - } - }, - - // when nonces are updated - nonces = source_nonces => { - source_nonces_required = false; - - source_client_is_online = process_future_result( - nonces, - &mut source_retry_backoff, - |(at_block, nonces)| { - log::debug!( - target: "bridge", - "Received nonces from {}: {:?}", - P::source_name(), - nonces, - ); - - strategy.source_nonces_updated(at_block, nonces); - }, - &mut source_go_offline_future, - async_std::task::sleep, - || format!("Error retrieving nonces from {}", P::source_name()), - ).fail_if_connection_error(FailedClient::Source)?; - - // ask for more headers if we have nonces to deliver and required headers are missing - let required_source_header_id = race_state - .best_finalized_source_header_id_at_best_target - .as_ref() - .and_then(|best|strategy.required_source_header_at_target(best)); - if let Some(required_source_header_id) = required_source_header_id { - race_target.require_source_header(required_source_header_id).await; - } - }, - nonces = target_best_nonces => { - target_best_nonces_required = false; - - target_client_is_online = process_future_result( - nonces, - &mut target_retry_backoff, - |(_, nonces)| { - log::debug!( - target: "bridge", - "Received best nonces from {}: {:?}", - P::target_name(), - nonces, - ); - - let prev_best_at_target = strategy.best_at_target(); - strategy.best_target_nonces_updated(nonces, &mut race_state); - if strategy.best_at_target() != prev_best_at_target { - stall_countdown = Instant::now(); - } - }, - &mut target_go_offline_future, - async_std::task::sleep, - || format!("Error retrieving best nonces from {}", P::target_name()), - ).fail_if_connection_error(FailedClient::Target)?; - }, - nonces = target_finalized_nonces => { - target_finalized_nonces_required = false; - - target_client_is_online = process_future_result( - nonces, - &mut target_retry_backoff, - |(_, nonces)| { - log::debug!( - target: "bridge", - "Received finalized nonces from {}: {:?}", - P::target_name(), - nonces, - ); - - strategy.finalized_target_nonces_updated(nonces, &mut race_state); - }, - &mut target_go_offline_future, - async_std::task::sleep, - || format!("Error retrieving finalized nonces from {}", P::target_name()), - ).fail_if_connection_error(FailedClient::Target)?; - }, - - // proof generation and submission - proof = source_generate_proof => { - source_client_is_online = process_future_result( - proof, - &mut source_retry_backoff, - |(at_block, nonces_range, proof)| { - log::debug!( - target: "bridge", - "Received proof for nonces in range {:?} from {}", - nonces_range, - P::source_name(), - ); - - race_state.nonces_to_submit = Some((at_block, nonces_range, proof)); - }, - &mut source_go_offline_future, - async_std::task::sleep, - || format!("Error generating proof at {}", P::source_name()), - ).fail_if_connection_error(FailedClient::Source)?; - }, - proof_submit_result = target_submit_proof => { - target_client_is_online = process_future_result( - proof_submit_result, - &mut target_retry_backoff, - |nonces_range| { - log::debug!( - target: "bridge", - "Successfully submitted proof of nonces {:?} to {}", - nonces_range, - P::target_name(), - ); - - race_state.nonces_to_submit = None; - race_state.nonces_submitted = Some(nonces_range); - stall_countdown = Instant::now(); - }, - &mut target_go_offline_future, - async_std::task::sleep, - || format!("Error submitting proof {}", P::target_name()), - ).fail_if_connection_error(FailedClient::Target)?; - }, - - // when we're ready to retry request - _ = source_go_offline_future => { - source_client_is_online = true; - }, - _ = target_go_offline_future => { - target_client_is_online = true; - }, - } - - progress_context = print_race_progress::(progress_context, &strategy); - - if stall_countdown.elapsed() > stall_timeout { - log::warn!( - target: "bridge", - "{} -> {} race has stalled. State: {:?}. Strategy: {:?}", - P::source_name(), - P::target_name(), - race_state, - strategy, - ); - - return Err(FailedClient::Both); - } else if race_state.nonces_to_submit.is_none() - && race_state.nonces_submitted.is_none() - && strategy.is_empty() - { - stall_countdown = Instant::now(); - } - - if source_client_is_online { - source_client_is_online = false; - - let nonces_to_deliver = - select_nonces_to_deliver(race_state.clone(), &mut strategy).await; - let best_at_source = strategy.best_at_source(); - - if let Some((at_block, nonces_range, proof_parameters)) = nonces_to_deliver { - log::debug!( - target: "bridge", - "Asking {} to prove nonces in range {:?} at block {:?}", - P::source_name(), - nonces_range, - at_block, - ); - source_generate_proof.set( - race_source.generate_proof(at_block, nonces_range, proof_parameters).fuse(), - ); - } else if source_nonces_required && best_at_source.is_some() { - log::debug!(target: "bridge", "Asking {} about message nonces", P::source_name()); - let at_block = race_state - .best_finalized_source_header_id_at_source - .as_ref() - .expect( - "source_nonces_required is only true when\ - best_finalized_source_header_id_at_source is Some; qed", - ) - .clone(); - source_nonces.set( - race_source - .nonces(at_block, best_at_source.expect("guaranteed by if condition; qed")) - .fuse(), - ); - } else { - source_client_is_online = true; - } - } - - if target_client_is_online { - target_client_is_online = false; - - if let Some((at_block, nonces_range, proof)) = race_state.nonces_to_submit.as_ref() { - log::debug!( - target: "bridge", - "Going to submit proof of messages in range {:?} to {} node", - nonces_range, - P::target_name(), - ); - target_submit_proof.set( - race_target - .submit_proof(at_block.clone(), nonces_range.clone(), proof.clone()) - .fuse(), - ); - } else if target_best_nonces_required { - log::debug!(target: "bridge", "Asking {} about best message nonces", P::target_name()); - let at_block = race_state - .best_target_header_id - .as_ref() - .expect("target_best_nonces_required is only true when best_target_header_id is Some; qed") - .clone(); - target_best_nonces.set(race_target.nonces(at_block, false).fuse()); - } else if target_finalized_nonces_required { - log::debug!(target: "bridge", "Asking {} about finalized message nonces", P::target_name()); - let at_block = race_state - .best_finalized_target_header_id - .as_ref() - .expect( - "target_finalized_nonces_required is only true when\ - best_finalized_target_header_id is Some; qed", - ) - .clone(); - target_finalized_nonces.set(race_target.nonces(at_block, true).fuse()); - } else { - target_client_is_online = true; - } - } - } -} - -impl Default - for RaceState -{ - fn default() -> Self { - RaceState { - best_finalized_source_header_id_at_source: None, - best_finalized_source_header_id_at_best_target: None, - best_target_header_id: None, - best_finalized_target_header_id: None, - nonces_to_submit: None, - nonces_submitted: None, - } - } -} - -/// Print race progress. -fn print_race_progress(prev_time: Instant, strategy: &S) -> Instant -where - P: MessageRace, - S: RaceStrategy, -{ - let now_time = Instant::now(); - - let need_update = now_time.saturating_duration_since(prev_time) > Duration::from_secs(10); - if !need_update { - return prev_time; - } - - let now_best_nonce_at_source = strategy.best_at_source(); - let now_best_nonce_at_target = strategy.best_at_target(); - log::info!( - target: "bridge", - "Synced {:?} of {:?} nonces in {} -> {} race", - now_best_nonce_at_target, - now_best_nonce_at_source, - P::source_name(), - P::target_name(), - ); - now_time -} - -async fn select_nonces_to_deliver( - race_state: RaceState, - strategy: &mut Strategy, -) -> Option<(SourceHeaderId, RangeInclusive, Strategy::ProofParameters)> -where - SourceHeaderId: Clone, - Strategy: RaceStrategy, -{ - let best_finalized_source_header_id_at_best_target = - race_state.best_finalized_source_header_id_at_best_target.clone()?; - strategy.select_nonces_to_deliver(race_state).await.map(|(nonces_range, proof_parameters)| { - (best_finalized_source_header_id_at_best_target, nonces_range, proof_parameters) - }) -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::message_race_strategy::BasicStrategy; - use relay_utils::HeaderId; - - #[async_std::test] - async fn proof_is_generated_at_best_block_known_to_target_node() { - const GENERATED_AT: u64 = 6; - const BEST_AT_SOURCE: u64 = 10; - const BEST_AT_TARGET: u64 = 8; - - // target node only knows about source' BEST_AT_TARGET block - // source node has BEST_AT_SOURCE > BEST_AT_TARGET block - let mut race_state = RaceState::<_, _, ()> { - best_finalized_source_header_id_at_source: Some(HeaderId( - BEST_AT_SOURCE, - BEST_AT_SOURCE, - )), - best_finalized_source_header_id_at_best_target: Some(HeaderId( - BEST_AT_TARGET, - BEST_AT_TARGET, - )), - best_target_header_id: Some(HeaderId(0, 0)), - best_finalized_target_header_id: Some(HeaderId(0, 0)), - nonces_to_submit: None, - nonces_submitted: None, - }; - - // we have some nonces to deliver and they're generated at GENERATED_AT < BEST_AT_SOURCE - let mut strategy = BasicStrategy::new(); - strategy.source_nonces_updated( - HeaderId(GENERATED_AT, GENERATED_AT), - SourceClientNonces { new_nonces: 0..=10, confirmed_nonce: None }, - ); - strategy.best_target_nonces_updated( - TargetClientNonces { latest_nonce: 5u64, nonces_data: () }, - &mut race_state, - ); - - // the proof will be generated on source, but using BEST_AT_TARGET block - assert_eq!( - select_nonces_to_deliver(race_state, &mut strategy).await, - Some((HeaderId(BEST_AT_TARGET, BEST_AT_TARGET), 6..=10, (),)) - ); - } -} diff --git a/relays/messages/src/message_race_receiving.rs b/relays/messages/src/message_race_receiving.rs deleted file mode 100644 index a23add589..000000000 --- a/relays/messages/src/message_race_receiving.rs +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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. - -//! Message receiving race delivers proof-of-messages-delivery from "lane.target" to "lane.source". - -use crate::{ - message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf}, - message_lane_loop::{ - SourceClient as MessageLaneSourceClient, SourceClientState, - TargetClient as MessageLaneTargetClient, TargetClientState, - }, - message_race_loop::{ - MessageRace, NoncesRange, SourceClient, SourceClientNonces, TargetClient, - TargetClientNonces, - }, - message_race_strategy::BasicStrategy, - metrics::MessageLaneLoopMetrics, -}; - -use async_trait::async_trait; -use bp_messages::MessageNonce; -use futures::stream::FusedStream; -use relay_utils::FailedClient; -use std::{marker::PhantomData, ops::RangeInclusive, time::Duration}; - -/// Message receiving confirmations delivery strategy. -type ReceivingConfirmationsBasicStrategy

= BasicStrategy< -

::TargetHeaderNumber, -

::TargetHeaderHash, -

::SourceHeaderNumber, -

::SourceHeaderHash, - RangeInclusive, -

::MessagesReceivingProof, ->; - -/// Run receiving confirmations race. -pub async fn run( - source_client: impl MessageLaneSourceClient

, - source_state_updates: impl FusedStream>, - target_client: impl MessageLaneTargetClient

, - target_state_updates: impl FusedStream>, - stall_timeout: Duration, - metrics_msg: Option, -) -> Result<(), FailedClient> { - crate::message_race_loop::run( - ReceivingConfirmationsRaceSource { - client: target_client, - metrics_msg: metrics_msg.clone(), - _phantom: Default::default(), - }, - target_state_updates, - ReceivingConfirmationsRaceTarget { - client: source_client, - metrics_msg, - _phantom: Default::default(), - }, - source_state_updates, - stall_timeout, - ReceivingConfirmationsBasicStrategy::

::new(), - ) - .await -} - -/// Messages receiving confirmations race. -struct ReceivingConfirmationsRace

(std::marker::PhantomData

); - -impl MessageRace for ReceivingConfirmationsRace

{ - type MessageNonce = MessageNonce; - type Proof = P::MessagesReceivingProof; - type SourceHeaderId = TargetHeaderIdOf

; - type TargetHeaderId = SourceHeaderIdOf

; - - fn source_name() -> String { - format!("{}::ReceivingConfirmationsDelivery", P::TARGET_NAME) - } - - fn target_name() -> String { - format!("{}::ReceivingConfirmationsDelivery", P::SOURCE_NAME) - } -} - -/// Message receiving confirmations race source, which is a target of the lane. -struct ReceivingConfirmationsRaceSource { - client: C, - metrics_msg: Option, - _phantom: PhantomData

, -} - -#[async_trait] -impl SourceClient> for ReceivingConfirmationsRaceSource -where - P: MessageLane, - C: MessageLaneTargetClient

, -{ - type Error = C::Error; - type NoncesRange = RangeInclusive; - type ProofParameters = (); - - async fn nonces( - &self, - at_block: TargetHeaderIdOf

, - prev_latest_nonce: MessageNonce, - ) -> Result<(TargetHeaderIdOf

, SourceClientNonces), Self::Error> { - let (at_block, latest_received_nonce) = self.client.latest_received_nonce(at_block).await?; - if let Some(metrics_msg) = self.metrics_msg.as_ref() { - metrics_msg.update_target_latest_received_nonce::

(latest_received_nonce); - } - Ok(( - at_block, - SourceClientNonces { - new_nonces: prev_latest_nonce + 1..=latest_received_nonce, - confirmed_nonce: None, - }, - )) - } - - #[allow(clippy::unit_arg)] - async fn generate_proof( - &self, - at_block: TargetHeaderIdOf

, - nonces: RangeInclusive, - _proof_parameters: Self::ProofParameters, - ) -> Result< - (TargetHeaderIdOf

, RangeInclusive, P::MessagesReceivingProof), - Self::Error, - > { - self.client - .prove_messages_receiving(at_block) - .await - .map(|(at_block, proof)| (at_block, nonces, proof)) - } -} - -/// Message receiving confirmations race target, which is a source of the lane. -struct ReceivingConfirmationsRaceTarget { - client: C, - metrics_msg: Option, - _phantom: PhantomData

, -} - -#[async_trait] -impl TargetClient> for ReceivingConfirmationsRaceTarget -where - P: MessageLane, - C: MessageLaneSourceClient

, -{ - type Error = C::Error; - type TargetNoncesData = (); - - async fn require_source_header(&self, id: TargetHeaderIdOf

) { - self.client.require_target_header_on_source(id).await - } - - async fn nonces( - &self, - at_block: SourceHeaderIdOf

, - update_metrics: bool, - ) -> Result<(SourceHeaderIdOf

, TargetClientNonces<()>), Self::Error> { - let (at_block, latest_confirmed_nonce) = - self.client.latest_confirmed_received_nonce(at_block).await?; - if update_metrics { - if let Some(metrics_msg) = self.metrics_msg.as_ref() { - metrics_msg.update_source_latest_confirmed_nonce::

(latest_confirmed_nonce); - } - } - Ok((at_block, TargetClientNonces { latest_nonce: latest_confirmed_nonce, nonces_data: () })) - } - - async fn submit_proof( - &self, - generated_at_block: TargetHeaderIdOf

, - nonces: RangeInclusive, - proof: P::MessagesReceivingProof, - ) -> Result, Self::Error> { - self.client.submit_messages_receiving_proof(generated_at_block, proof).await?; - Ok(nonces) - } -} - -impl NoncesRange for RangeInclusive { - fn begin(&self) -> MessageNonce { - *RangeInclusive::::start(self) - } - - fn end(&self) -> MessageNonce { - *RangeInclusive::::end(self) - } - - fn greater_than(self, nonce: MessageNonce) -> Option { - let next_nonce = nonce + 1; - let end = *self.end(); - if next_nonce > end { - None - } else { - Some(std::cmp::max(self.begin(), next_nonce)..=end) - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn range_inclusive_works_as_nonces_range() { - let range = 20..=30; - - assert_eq!(NoncesRange::begin(&range), 20); - assert_eq!(NoncesRange::end(&range), 30); - assert_eq!(range.clone().greater_than(10), Some(20..=30)); - assert_eq!(range.clone().greater_than(19), Some(20..=30)); - assert_eq!(range.clone().greater_than(20), Some(21..=30)); - assert_eq!(range.clone().greater_than(25), Some(26..=30)); - assert_eq!(range.clone().greater_than(29), Some(30..=30)); - assert_eq!(range.greater_than(30), None); - } -} diff --git a/relays/messages/src/message_race_strategy.rs b/relays/messages/src/message_race_strategy.rs deleted file mode 100644 index b660c5f11..000000000 --- a/relays/messages/src/message_race_strategy.rs +++ /dev/null @@ -1,517 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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. - -//! Basic delivery strategy. The strategy selects nonces if: -//! -//! 1) there are more nonces on the source side than on the target side; -//! 2) new nonces may be proved to target node (i.e. they have appeared at the -//! block, which is known to the target node). - -use crate::message_race_loop::{ - NoncesRange, RaceState, RaceStrategy, SourceClientNonces, TargetClientNonces, -}; - -use async_trait::async_trait; -use bp_messages::MessageNonce; -use relay_utils::HeaderId; -use std::{collections::VecDeque, fmt::Debug, marker::PhantomData, ops::RangeInclusive}; - -/// Queue of nonces known to the source node. -pub type SourceRangesQueue = - VecDeque<(HeaderId, SourceNoncesRange)>; - -/// Nonces delivery strategy. -#[derive(Debug)] -pub struct BasicStrategy< - SourceHeaderNumber, - SourceHeaderHash, - TargetHeaderNumber, - TargetHeaderHash, - SourceNoncesRange, - Proof, -> { - /// All queued nonces. - source_queue: SourceRangesQueue, - /// The best nonce known to target node (at its best block). `None` if it has not been received - /// yet. - best_target_nonce: Option, - /// Unused generic types dump. - _phantom: PhantomData<(TargetHeaderNumber, TargetHeaderHash, Proof)>, -} - -impl< - SourceHeaderNumber, - SourceHeaderHash, - TargetHeaderNumber, - TargetHeaderHash, - SourceNoncesRange, - Proof, - > - BasicStrategy< - SourceHeaderNumber, - SourceHeaderHash, - TargetHeaderNumber, - TargetHeaderHash, - SourceNoncesRange, - Proof, - > where - SourceHeaderHash: Clone, - SourceHeaderNumber: Clone + Ord, - SourceNoncesRange: NoncesRange, -{ - /// Create new delivery strategy. - pub fn new() -> Self { - BasicStrategy { - source_queue: VecDeque::new(), - best_target_nonce: None, - _phantom: Default::default(), - } - } - - /// Reference to source queue. - pub(crate) fn source_queue( - &self, - ) -> &VecDeque<(HeaderId, SourceNoncesRange)> { - &self.source_queue - } - - /// Mutable reference to source queue to use in tests. - #[cfg(test)] - pub(crate) fn source_queue_mut( - &mut self, - ) -> &mut VecDeque<(HeaderId, SourceNoncesRange)> { - &mut self.source_queue - } - - /// Returns index of the latest source queue entry, that may be delivered to the target node. - /// - /// Returns `None` if no entries may be delivered. All entries before and including the - /// `Some(_)` index are guaranteed to be witnessed at source blocks that are known to be - /// finalized at the target node. - pub fn maximal_available_source_queue_index( - &self, - race_state: RaceState< - HeaderId, - HeaderId, - Proof, - >, - ) -> Option { - // if we do not know best nonce at target node, we can't select anything - let _ = self.best_target_nonce?; - - // if we have already selected nonces that we want to submit, do nothing - if race_state.nonces_to_submit.is_some() { - return None; - } - - // if we already submitted some nonces, do nothing - if race_state.nonces_submitted.is_some() { - return None; - } - - // 1) we want to deliver all nonces, starting from `target_nonce + 1` - // 2) we can't deliver new nonce until header, that has emitted this nonce, is finalized - // by target client - // 3) selector is used for more complicated logic - // - // => let's first select range of entries inside deque that are already finalized at - // the target client and pass this range to the selector - let best_header_at_target = race_state.best_finalized_source_header_id_at_best_target?; - self.source_queue - .iter() - .enumerate() - .take_while(|(_, (queued_at, _))| queued_at.0 <= best_header_at_target.0) - .map(|(index, _)| index) - .last() - } - - /// Remove all nonces that are less than or equal to given nonce from the source queue. - pub fn remove_le_nonces_from_source_queue(&mut self, nonce: MessageNonce) { - while let Some((queued_at, queued_range)) = self.source_queue.pop_front() { - if let Some(range_to_requeue) = queued_range.greater_than(nonce) { - self.source_queue.push_front((queued_at, range_to_requeue)); - break; - } - } - } -} - -#[async_trait] -impl< - SourceHeaderNumber, - SourceHeaderHash, - TargetHeaderNumber, - TargetHeaderHash, - SourceNoncesRange, - Proof, - > - RaceStrategy< - HeaderId, - HeaderId, - Proof, - > - for BasicStrategy< - SourceHeaderNumber, - SourceHeaderHash, - TargetHeaderNumber, - TargetHeaderHash, - SourceNoncesRange, - Proof, - > where - SourceHeaderHash: Clone + Debug + Send, - SourceHeaderNumber: Clone + Ord + Debug + Send, - SourceNoncesRange: NoncesRange + Debug + Send, - TargetHeaderHash: Debug + Send, - TargetHeaderNumber: Debug + Send, - Proof: Debug + Send, -{ - type ProofParameters = (); - type SourceNoncesRange = SourceNoncesRange; - type TargetNoncesData = (); - - fn is_empty(&self) -> bool { - self.source_queue.is_empty() - } - - fn required_source_header_at_target( - &self, - current_best: &HeaderId, - ) -> Option> { - self.source_queue - .back() - .and_then(|(h, _)| if h.0 > current_best.0 { Some(h.clone()) } else { None }) - } - - fn best_at_source(&self) -> Option { - let best_in_queue = self.source_queue.back().map(|(_, range)| range.end()); - match (best_in_queue, self.best_target_nonce) { - (Some(best_in_queue), Some(best_target_nonce)) if best_in_queue > best_target_nonce => - Some(best_in_queue), - (_, Some(best_target_nonce)) => Some(best_target_nonce), - (_, None) => None, - } - } - - fn best_at_target(&self) -> Option { - self.best_target_nonce - } - - fn source_nonces_updated( - &mut self, - at_block: HeaderId, - nonces: SourceClientNonces, - ) { - let best_in_queue = self - .source_queue - .back() - .map(|(_, range)| range.end()) - .or(self.best_target_nonce) - .unwrap_or_default(); - self.source_queue.extend( - nonces - .new_nonces - .greater_than(best_in_queue) - .into_iter() - .map(move |range| (at_block.clone(), range)), - ) - } - - fn best_target_nonces_updated( - &mut self, - nonces: TargetClientNonces<()>, - race_state: &mut RaceState< - HeaderId, - HeaderId, - Proof, - >, - ) { - let nonce = nonces.latest_nonce; - - if let Some(best_target_nonce) = self.best_target_nonce { - if nonce < best_target_nonce { - return; - } - } - - while let Some(true) = self.source_queue.front().map(|(_, range)| range.begin() <= nonce) { - let maybe_subrange = self.source_queue.pop_front().and_then(|(at_block, range)| { - range.greater_than(nonce).map(|subrange| (at_block, subrange)) - }); - if let Some((at_block, subrange)) = maybe_subrange { - self.source_queue.push_front((at_block, subrange)); - break; - } - } - - let need_to_select_new_nonces = race_state - .nonces_to_submit - .as_ref() - .map(|(_, nonces, _)| *nonces.end() <= nonce) - .unwrap_or(false); - if need_to_select_new_nonces { - race_state.nonces_to_submit = None; - } - - let need_new_nonces_to_submit = race_state - .nonces_submitted - .as_ref() - .map(|nonces| *nonces.end() <= nonce) - .unwrap_or(false); - if need_new_nonces_to_submit { - race_state.nonces_submitted = None; - } - - self.best_target_nonce = - Some(std::cmp::max(self.best_target_nonce.unwrap_or(nonces.latest_nonce), nonce)); - } - - fn finalized_target_nonces_updated( - &mut self, - nonces: TargetClientNonces<()>, - _race_state: &mut RaceState< - HeaderId, - HeaderId, - Proof, - >, - ) { - self.best_target_nonce = Some(std::cmp::max( - self.best_target_nonce.unwrap_or(nonces.latest_nonce), - nonces.latest_nonce, - )); - } - - async fn select_nonces_to_deliver( - &mut self, - race_state: RaceState< - HeaderId, - HeaderId, - Proof, - >, - ) -> Option<(RangeInclusive, Self::ProofParameters)> { - let maximal_source_queue_index = self.maximal_available_source_queue_index(race_state)?; - let range_begin = self.source_queue[0].1.begin(); - let range_end = self.source_queue[maximal_source_queue_index].1.end(); - self.remove_le_nonces_from_source_queue(range_end); - Some((range_begin..=range_end, ())) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::{ - message_lane::MessageLane, - message_lane_loop::tests::{ - header_id, TestMessageLane, TestMessagesProof, TestSourceHeaderHash, - TestSourceHeaderNumber, - }, - }; - - type SourceNoncesRange = RangeInclusive; - - type BasicStrategy

= super::BasicStrategy< -

::SourceHeaderNumber, -

::SourceHeaderHash, -

::TargetHeaderNumber, -

::TargetHeaderHash, - SourceNoncesRange, -

::MessagesProof, - >; - - fn source_nonces(new_nonces: SourceNoncesRange) -> SourceClientNonces { - SourceClientNonces { new_nonces, confirmed_nonce: None } - } - - fn target_nonces(latest_nonce: MessageNonce) -> TargetClientNonces<()> { - TargetClientNonces { latest_nonce, nonces_data: () } - } - - #[test] - fn strategy_is_empty_works() { - let mut strategy = BasicStrategy::::new(); - assert!(strategy.is_empty()); - strategy.source_nonces_updated(header_id(1), source_nonces(1..=1)); - assert!(!strategy.is_empty()); - } - - #[test] - fn best_at_source_is_never_lower_than_target_nonce() { - let mut strategy = BasicStrategy::::new(); - assert_eq!(strategy.best_at_source(), None); - strategy.source_nonces_updated(header_id(1), source_nonces(1..=5)); - assert_eq!(strategy.best_at_source(), None); - strategy.best_target_nonces_updated(target_nonces(10), &mut Default::default()); - assert_eq!(strategy.source_queue, vec![]); - assert_eq!(strategy.best_at_source(), Some(10)); - } - - #[test] - fn source_nonce_is_never_lower_than_known_target_nonce() { - let mut strategy = BasicStrategy::::new(); - strategy.best_target_nonces_updated(target_nonces(10), &mut Default::default()); - strategy.source_nonces_updated(header_id(1), source_nonces(1..=5)); - assert_eq!(strategy.source_queue, vec![]); - } - - #[test] - fn source_nonce_is_never_lower_than_latest_known_source_nonce() { - let mut strategy = BasicStrategy::::new(); - strategy.source_nonces_updated(header_id(1), source_nonces(1..=5)); - strategy.source_nonces_updated(header_id(2), source_nonces(1..=3)); - strategy.source_nonces_updated(header_id(2), source_nonces(1..=5)); - assert_eq!(strategy.source_queue, vec![(header_id(1), 1..=5)]); - } - - #[test] - fn target_nonce_is_never_lower_than_latest_known_target_nonce() { - let mut strategy = BasicStrategy::::new(); - assert_eq!(strategy.best_target_nonce, None); - strategy.best_target_nonces_updated(target_nonces(10), &mut Default::default()); - assert_eq!(strategy.best_target_nonce, Some(10)); - strategy.best_target_nonces_updated(target_nonces(5), &mut Default::default()); - assert_eq!(strategy.best_target_nonce, Some(10)); - } - - #[test] - fn updated_target_nonce_removes_queued_entries() { - let mut strategy = BasicStrategy::::new(); - strategy.source_nonces_updated(header_id(1), source_nonces(1..=5)); - strategy.source_nonces_updated(header_id(2), source_nonces(6..=10)); - strategy.source_nonces_updated(header_id(3), source_nonces(11..=15)); - strategy.source_nonces_updated(header_id(4), source_nonces(16..=20)); - strategy.best_target_nonces_updated(target_nonces(15), &mut Default::default()); - assert_eq!(strategy.source_queue, vec![(header_id(4), 16..=20)]); - strategy.best_target_nonces_updated(target_nonces(17), &mut Default::default()); - assert_eq!(strategy.source_queue, vec![(header_id(4), 18..=20)]); - } - - #[test] - fn selected_nonces_are_dropped_on_target_nonce_update() { - let mut state = RaceState::default(); - let mut strategy = BasicStrategy::::new(); - state.nonces_to_submit = Some((header_id(1), 5..=10, (5..=10, None))); - strategy.best_target_nonces_updated(target_nonces(7), &mut state); - assert!(state.nonces_to_submit.is_some()); - strategy.best_target_nonces_updated(target_nonces(10), &mut state); - assert!(state.nonces_to_submit.is_none()); - } - - #[test] - fn submitted_nonces_are_dropped_on_target_nonce_update() { - let mut state = RaceState::default(); - let mut strategy = BasicStrategy::::new(); - state.nonces_submitted = Some(5..=10); - strategy.best_target_nonces_updated(target_nonces(7), &mut state); - assert!(state.nonces_submitted.is_some()); - strategy.best_target_nonces_updated(target_nonces(10), &mut state); - assert!(state.nonces_submitted.is_none()); - } - - #[async_std::test] - async fn nothing_is_selected_if_something_is_already_selected() { - let mut state = RaceState::default(); - let mut strategy = BasicStrategy::::new(); - state.nonces_to_submit = Some((header_id(1), 1..=10, (1..=10, None))); - strategy.best_target_nonces_updated(target_nonces(0), &mut state); - strategy.source_nonces_updated(header_id(1), source_nonces(1..=10)); - assert_eq!(strategy.select_nonces_to_deliver(state.clone()).await, None); - } - - #[async_std::test] - async fn nothing_is_selected_if_something_is_already_submitted() { - let mut state = RaceState::default(); - let mut strategy = BasicStrategy::::new(); - state.nonces_submitted = Some(1..=10); - strategy.best_target_nonces_updated(target_nonces(0), &mut state); - strategy.source_nonces_updated(header_id(1), source_nonces(1..=10)); - assert_eq!(strategy.select_nonces_to_deliver(state.clone()).await, None); - } - - #[async_std::test] - async fn select_nonces_to_deliver_works() { - let mut state = RaceState::<_, _, TestMessagesProof>::default(); - let mut strategy = BasicStrategy::::new(); - strategy.best_target_nonces_updated(target_nonces(0), &mut state); - strategy.source_nonces_updated(header_id(1), source_nonces(1..=1)); - strategy.source_nonces_updated(header_id(2), source_nonces(2..=2)); - strategy.source_nonces_updated(header_id(3), source_nonces(3..=6)); - strategy.source_nonces_updated(header_id(5), source_nonces(7..=8)); - - state.best_finalized_source_header_id_at_best_target = Some(header_id(4)); - assert_eq!(strategy.select_nonces_to_deliver(state.clone()).await, Some((1..=6, ()))); - strategy.best_target_nonces_updated(target_nonces(6), &mut state); - assert_eq!(strategy.select_nonces_to_deliver(state.clone()).await, None); - - state.best_finalized_source_header_id_at_best_target = Some(header_id(5)); - assert_eq!(strategy.select_nonces_to_deliver(state.clone()).await, Some((7..=8, ()))); - strategy.best_target_nonces_updated(target_nonces(8), &mut state); - assert_eq!(strategy.select_nonces_to_deliver(state.clone()).await, None); - } - - #[test] - fn maximal_available_source_queue_index_works() { - let mut state = RaceState::<_, _, TestMessagesProof>::default(); - let mut strategy = BasicStrategy::::new(); - strategy.best_target_nonces_updated(target_nonces(0), &mut state); - strategy.source_nonces_updated(header_id(1), source_nonces(1..=3)); - strategy.source_nonces_updated(header_id(2), source_nonces(4..=6)); - strategy.source_nonces_updated(header_id(3), source_nonces(7..=9)); - - state.best_finalized_source_header_id_at_best_target = Some(header_id(0)); - assert_eq!(strategy.maximal_available_source_queue_index(state.clone()), None); - - state.best_finalized_source_header_id_at_best_target = Some(header_id(1)); - assert_eq!(strategy.maximal_available_source_queue_index(state.clone()), Some(0)); - - state.best_finalized_source_header_id_at_best_target = Some(header_id(2)); - assert_eq!(strategy.maximal_available_source_queue_index(state.clone()), Some(1)); - - state.best_finalized_source_header_id_at_best_target = Some(header_id(3)); - assert_eq!(strategy.maximal_available_source_queue_index(state.clone()), Some(2)); - - state.best_finalized_source_header_id_at_best_target = Some(header_id(4)); - assert_eq!(strategy.maximal_available_source_queue_index(state), Some(2)); - } - - #[test] - fn remove_le_nonces_from_source_queue_works() { - let mut state = RaceState::<_, _, TestMessagesProof>::default(); - let mut strategy = BasicStrategy::::new(); - strategy.best_target_nonces_updated(target_nonces(0), &mut state); - strategy.source_nonces_updated(header_id(1), source_nonces(1..=3)); - strategy.source_nonces_updated(header_id(2), source_nonces(4..=6)); - strategy.source_nonces_updated(header_id(3), source_nonces(7..=9)); - - fn source_queue_nonces( - source_queue: &SourceRangesQueue< - TestSourceHeaderHash, - TestSourceHeaderNumber, - SourceNoncesRange, - >, - ) -> Vec { - source_queue.iter().flat_map(|(_, range)| range.clone()).collect() - } - - strategy.remove_le_nonces_from_source_queue(1); - assert_eq!(source_queue_nonces(&strategy.source_queue), vec![2, 3, 4, 5, 6, 7, 8, 9],); - - strategy.remove_le_nonces_from_source_queue(5); - assert_eq!(source_queue_nonces(&strategy.source_queue), vec![6, 7, 8, 9],); - - strategy.remove_le_nonces_from_source_queue(9); - assert_eq!(source_queue_nonces(&strategy.source_queue), Vec::::new(),); - - strategy.remove_le_nonces_from_source_queue(100); - assert_eq!(source_queue_nonces(&strategy.source_queue), Vec::::new(),); - } -} diff --git a/relays/messages/src/metrics.rs b/relays/messages/src/metrics.rs deleted file mode 100644 index db300b477..000000000 --- a/relays/messages/src/metrics.rs +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Metrics for message lane relay loop. - -use crate::{ - message_lane::MessageLane, - message_lane_loop::{SourceClientState, TargetClientState}, -}; - -use bp_messages::MessageNonce; -use finality_relay::SyncLoopMetrics; -use relay_utils::metrics::{ - metric_name, register, GaugeVec, Metric, Opts, PrometheusError, Registry, U64, -}; - -/// Message lane relay metrics. -/// -/// Cloning only clones references. -#[derive(Clone)] -pub struct MessageLaneLoopMetrics { - /// Best finalized block numbers - "source", "source_at_target", "target_at_source". - source_to_target_finality_metrics: SyncLoopMetrics, - /// Best finalized block numbers - "source", "target", "source_at_target", "target_at_source". - target_to_source_finality_metrics: SyncLoopMetrics, - /// Lane state nonces: "source_latest_generated", "source_latest_confirmed", - /// "target_latest_received", "target_latest_confirmed". - lane_state_nonces: GaugeVec, -} - -impl MessageLaneLoopMetrics { - /// Create and register messages loop metrics. - pub fn new(prefix: Option<&str>) -> Result { - Ok(MessageLaneLoopMetrics { - source_to_target_finality_metrics: SyncLoopMetrics::new( - prefix, - "source", - "source_at_target", - )?, - target_to_source_finality_metrics: SyncLoopMetrics::new( - prefix, - "target", - "target_at_source", - )?, - lane_state_nonces: GaugeVec::new( - Opts::new(metric_name(prefix, "lane_state_nonces"), "Nonces of the lane state"), - &["type"], - )?, - }) - } - - /// Update source client state metrics. - pub fn update_source_state(&self, source_client_state: SourceClientState

) { - self.source_to_target_finality_metrics - .update_best_block_at_source(source_client_state.best_self.0.into()); - self.target_to_source_finality_metrics.update_best_block_at_target( - source_client_state.best_finalized_peer_at_best_self.0.into(), - ); - self.target_to_source_finality_metrics.update_using_same_fork( - source_client_state.best_finalized_peer_at_best_self.1 - == source_client_state.actual_best_finalized_peer_at_best_self.1, - ); - } - - /// Update target client state metrics. - pub fn update_target_state(&self, target_client_state: TargetClientState

) { - self.target_to_source_finality_metrics - .update_best_block_at_source(target_client_state.best_self.0.into()); - self.source_to_target_finality_metrics.update_best_block_at_target( - target_client_state.best_finalized_peer_at_best_self.0.into(), - ); - self.source_to_target_finality_metrics.update_using_same_fork( - target_client_state.best_finalized_peer_at_best_self.1 - == target_client_state.actual_best_finalized_peer_at_best_self.1, - ); - } - - /// Update latest generated nonce at source. - pub fn update_source_latest_generated_nonce( - &self, - source_latest_generated_nonce: MessageNonce, - ) { - self.lane_state_nonces - .with_label_values(&["source_latest_generated"]) - .set(source_latest_generated_nonce); - } - - /// Update the latest confirmed nonce at source. - pub fn update_source_latest_confirmed_nonce( - &self, - source_latest_confirmed_nonce: MessageNonce, - ) { - self.lane_state_nonces - .with_label_values(&["source_latest_confirmed"]) - .set(source_latest_confirmed_nonce); - } - - /// Update the latest received nonce at target. - pub fn update_target_latest_received_nonce( - &self, - target_latest_generated_nonce: MessageNonce, - ) { - self.lane_state_nonces - .with_label_values(&["target_latest_received"]) - .set(target_latest_generated_nonce); - } - - /// Update the latest confirmed nonce at target. - pub fn update_target_latest_confirmed_nonce( - &self, - target_latest_confirmed_nonce: MessageNonce, - ) { - self.lane_state_nonces - .with_label_values(&["target_latest_confirmed"]) - .set(target_latest_confirmed_nonce); - } -} - -impl Metric for MessageLaneLoopMetrics { - fn register(&self, registry: &Registry) -> Result<(), PrometheusError> { - self.source_to_target_finality_metrics.register(registry)?; - self.target_to_source_finality_metrics.register(registry)?; - register(self.lane_state_nonces.clone(), registry)?; - Ok(()) - } -} diff --git a/relays/messages/src/relay_strategy/altruistic_strategy.rs b/relays/messages/src/relay_strategy/altruistic_strategy.rs deleted file mode 100644 index d6fec7f12..000000000 --- a/relays/messages/src/relay_strategy/altruistic_strategy.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Altruistic relay strategy - -use async_trait::async_trait; - -use crate::{ - message_lane::MessageLane, - message_lane_loop::{ - SourceClient as MessageLaneSourceClient, TargetClient as MessageLaneTargetClient, - }, - relay_strategy::{RelayReference, RelayStrategy}, -}; - -/// The relayer doesn't care about rewards. -#[derive(Clone)] -pub struct AltruisticStrategy; - -#[async_trait] -impl RelayStrategy for AltruisticStrategy { - async fn decide< - P: MessageLane, - SourceClient: MessageLaneSourceClient

, - TargetClient: MessageLaneTargetClient

, - >( - &mut self, - _reference: &mut RelayReference, - ) -> bool { - true - } -} diff --git a/relays/messages/src/relay_strategy/enforcement_strategy.rs b/relays/messages/src/relay_strategy/enforcement_strategy.rs deleted file mode 100644 index def6665be..000000000 --- a/relays/messages/src/relay_strategy/enforcement_strategy.rs +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! enforcement strategy - -use num_traits::Zero; - -use bp_messages::{MessageNonce, Weight}; -use bp_runtime::messages::DispatchFeePayment; - -use crate::{ - message_lane::MessageLane, - message_lane_loop::{ - MessageDetails, SourceClient as MessageLaneSourceClient, - TargetClient as MessageLaneTargetClient, - }, - message_race_loop::NoncesRange, - relay_strategy::{RelayMessagesBatchReference, RelayReference, RelayStrategy}, -}; - -/// Do hard check and run soft check strategy -#[derive(Clone)] -pub struct EnforcementStrategy { - strategy: Strategy, -} - -impl EnforcementStrategy { - pub fn new(strategy: Strategy) -> Self { - Self { strategy } - } -} - -impl EnforcementStrategy { - pub async fn decide< - P: MessageLane, - SourceClient: MessageLaneSourceClient

, - TargetClient: MessageLaneTargetClient

, - >( - &mut self, - reference: RelayMessagesBatchReference, - ) -> Option { - let mut hard_selected_count = 0; - let mut soft_selected_count = 0; - - let mut selected_weight: Weight = 0; - let mut selected_count: MessageNonce = 0; - - let hard_selected_begin_nonce = - reference.nonces_queue[reference.nonces_queue_range.start].1.begin(); - - // relay reference - let mut relay_reference = RelayReference { - lane_source_client: reference.lane_source_client.clone(), - lane_target_client: reference.lane_target_client.clone(), - - selected_reward: P::SourceChainBalance::zero(), - selected_cost: P::SourceChainBalance::zero(), - selected_size: 0, - - total_reward: P::SourceChainBalance::zero(), - total_confirmations_cost: P::SourceChainBalance::zero(), - total_cost: P::SourceChainBalance::zero(), - - hard_selected_begin_nonce, - selected_prepaid_nonces: 0, - selected_unpaid_weight: 0, - - index: 0, - nonce: 0, - details: MessageDetails { - dispatch_weight: 0, - size: 0, - reward: P::SourceChainBalance::zero(), - dispatch_fee_payment: DispatchFeePayment::AtSourceChain, - }, - }; - - let all_ready_nonces = reference - .nonces_queue - .range(reference.nonces_queue_range.clone()) - .flat_map(|(_, ready_nonces)| ready_nonces.iter()) - .enumerate(); - for (index, (nonce, details)) in all_ready_nonces { - relay_reference.index = index; - relay_reference.nonce = *nonce; - relay_reference.details = *details; - - // Since we (hopefully) have some reserves in `max_messages_weight_in_single_batch` - // and `max_messages_size_in_single_batch`, we may still try to submit transaction - // with single message if message overflows these limits. The worst case would be if - // transaction will be rejected by the target runtime, but at least we have tried. - - // limit messages in the batch by weight - let new_selected_weight = match selected_weight.checked_add(details.dispatch_weight) { - Some(new_selected_weight) - if new_selected_weight <= reference.max_messages_weight_in_single_batch => - new_selected_weight, - new_selected_weight if selected_count == 0 => { - log::warn!( - target: "bridge", - "Going to submit message delivery transaction with declared dispatch \ - weight {:?} that overflows maximal configured weight {}", - new_selected_weight, - reference.max_messages_weight_in_single_batch, - ); - new_selected_weight.unwrap_or(Weight::MAX) - }, - _ => break, - }; - - // limit messages in the batch by size - let new_selected_size = match relay_reference.selected_size.checked_add(details.size) { - Some(new_selected_size) - if new_selected_size <= reference.max_messages_size_in_single_batch => - new_selected_size, - new_selected_size if selected_count == 0 => { - log::warn!( - target: "bridge", - "Going to submit message delivery transaction with message \ - size {:?} that overflows maximal configured size {}", - new_selected_size, - reference.max_messages_size_in_single_batch, - ); - new_selected_size.unwrap_or(u32::MAX) - }, - _ => break, - }; - - // limit number of messages in the batch - let new_selected_count = selected_count + 1; - if new_selected_count > reference.max_messages_in_this_batch { - break; - } - relay_reference.selected_size = new_selected_size; - - // If dispatch fee has been paid at the source chain, it means that it is **relayer** - // who's paying for dispatch at the target chain AND reward must cover this dispatch - // fee. - // - // If dispatch fee is paid at the target chain, it means that it'll be withdrawn from - // the dispatch origin account AND reward is not covering this fee. - // - // So in the latter case we're not adding the dispatch weight to the delivery - // transaction weight. - let mut new_selected_prepaid_nonces = relay_reference.selected_prepaid_nonces; - let new_selected_unpaid_weight = match details.dispatch_fee_payment { - DispatchFeePayment::AtSourceChain => { - new_selected_prepaid_nonces += 1; - relay_reference.selected_unpaid_weight.saturating_add(details.dispatch_weight) - }, - DispatchFeePayment::AtTargetChain => relay_reference.selected_unpaid_weight, - }; - relay_reference.selected_prepaid_nonces = new_selected_prepaid_nonces; - relay_reference.selected_unpaid_weight = new_selected_unpaid_weight; - - // now the message has passed all 'strong' checks, and we CAN deliver it. But do we WANT - // to deliver it? It depends on the relayer strategy. - if self.strategy.decide(&mut relay_reference).await { - soft_selected_count = index + 1; - } - - hard_selected_count = index + 1; - selected_weight = new_selected_weight; - selected_count = new_selected_count; - } - - if hard_selected_count != soft_selected_count { - let hard_selected_end_nonce = - hard_selected_begin_nonce + hard_selected_count as MessageNonce - 1; - let soft_selected_begin_nonce = hard_selected_begin_nonce; - let soft_selected_end_nonce = - soft_selected_begin_nonce + soft_selected_count as MessageNonce - 1; - log::warn!( - target: "bridge", - "Relayer may deliver nonces [{:?}; {:?}], but because of its strategy it has selected \ - nonces [{:?}; {:?}].", - hard_selected_begin_nonce, - hard_selected_end_nonce, - soft_selected_begin_nonce, - soft_selected_end_nonce, - ); - - hard_selected_count = soft_selected_count; - } - - if hard_selected_count != 0 { - if relay_reference.selected_reward != P::SourceChainBalance::zero() - && relay_reference.selected_cost != P::SourceChainBalance::zero() - { - log::trace!( - target: "bridge", - "Expected reward from delivering nonces [{:?}; {:?}] is: {:?} - {:?} = {:?}", - hard_selected_begin_nonce, - hard_selected_begin_nonce + hard_selected_count as MessageNonce - 1, - &relay_reference.selected_reward, - &relay_reference.selected_cost, - relay_reference.selected_reward - relay_reference.selected_cost, - ); - } - - Some(hard_selected_begin_nonce + hard_selected_count as MessageNonce - 1) - } else { - None - } - } -} diff --git a/relays/messages/src/relay_strategy/mix_strategy.rs b/relays/messages/src/relay_strategy/mix_strategy.rs deleted file mode 100644 index 4ac7fe1d0..000000000 --- a/relays/messages/src/relay_strategy/mix_strategy.rs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Adapter for using `enum RelayerMode` in a context which requires `RelayStrategy`. - -use async_trait::async_trait; - -use crate::{ - message_lane::MessageLane, - message_lane_loop::{ - RelayerMode, SourceClient as MessageLaneSourceClient, - TargetClient as MessageLaneTargetClient, - }, - relay_strategy::{AltruisticStrategy, RationalStrategy, RelayReference, RelayStrategy}, -}; - -/// `RelayerMode` adapter. -#[derive(Clone)] -pub struct MixStrategy { - relayer_mode: RelayerMode, -} - -impl MixStrategy { - /// Create mix strategy instance - pub fn new(relayer_mode: RelayerMode) -> Self { - Self { relayer_mode } - } -} - -#[async_trait] -impl RelayStrategy for MixStrategy { - async fn decide< - P: MessageLane, - SourceClient: MessageLaneSourceClient

, - TargetClient: MessageLaneTargetClient

, - >( - &mut self, - reference: &mut RelayReference, - ) -> bool { - match self.relayer_mode { - RelayerMode::Altruistic => AltruisticStrategy.decide(reference).await, - RelayerMode::Rational => RationalStrategy.decide(reference).await, - } - } -} diff --git a/relays/messages/src/relay_strategy/mod.rs b/relays/messages/src/relay_strategy/mod.rs deleted file mode 100644 index d902bd93e..000000000 --- a/relays/messages/src/relay_strategy/mod.rs +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Relayer strategy - -use std::ops::Range; - -use async_trait::async_trait; - -use bp_messages::{MessageNonce, Weight}; - -use crate::{ - message_lane::MessageLane, - message_lane_loop::{ - MessageDetails, MessageDetailsMap, SourceClient as MessageLaneSourceClient, - TargetClient as MessageLaneTargetClient, - }, - message_race_strategy::SourceRangesQueue, -}; - -pub(crate) use self::enforcement_strategy::*; -pub use self::{altruistic_strategy::*, mix_strategy::*, rational_strategy::*}; - -mod altruistic_strategy; -mod enforcement_strategy; -mod mix_strategy; -mod rational_strategy; - -/// Relayer strategy trait -#[async_trait] -pub trait RelayStrategy: 'static + Clone + Send + Sync { - /// The relayer decide how to process nonce by reference. - /// From given set of source nonces, that are ready to be delivered, select nonces - /// to fit into single delivery transaction. - /// - /// The function returns last nonce that must be delivered to the target chain. - async fn decide< - P: MessageLane, - SourceClient: MessageLaneSourceClient

, - TargetClient: MessageLaneTargetClient

, - >( - &mut self, - reference: &mut RelayReference, - ) -> bool; -} - -/// Reference data for participating in relay -pub struct RelayReference< - P: MessageLane, - SourceClient: MessageLaneSourceClient

, - TargetClient: MessageLaneTargetClient

, -> { - /// The client that is connected to the message lane source node. - pub lane_source_client: SourceClient, - /// The client that is connected to the message lane target node. - pub lane_target_client: TargetClient, - /// Current block reward summary - pub selected_reward: P::SourceChainBalance, - /// Current block cost summary - pub selected_cost: P::SourceChainBalance, - /// Messages size summary - pub selected_size: u32, - - /// Current block reward summary - pub total_reward: P::SourceChainBalance, - /// All confirmations cost - pub total_confirmations_cost: P::SourceChainBalance, - /// Current block cost summary - pub total_cost: P::SourceChainBalance, - - /// Hard check begin nonce - pub hard_selected_begin_nonce: MessageNonce, - /// Count prepaid nonces - pub selected_prepaid_nonces: MessageNonce, - /// Unpaid nonces weight summary - pub selected_unpaid_weight: Weight, - - /// Index by all ready nonces - pub index: usize, - /// Current nonce - pub nonce: MessageNonce, - /// Current nonce details - pub details: MessageDetails, -} - -/// Relay reference data -pub struct RelayMessagesBatchReference< - P: MessageLane, - SourceClient: MessageLaneSourceClient

, - TargetClient: MessageLaneTargetClient

, -> { - /// Maximal number of relayed messages in single delivery transaction. - pub max_messages_in_this_batch: MessageNonce, - /// Maximal cumulative dispatch weight of relayed messages in single delivery transaction. - pub max_messages_weight_in_single_batch: Weight, - /// Maximal cumulative size of relayed messages in single delivery transaction. - pub max_messages_size_in_single_batch: u32, - /// The client that is connected to the message lane source node. - pub lane_source_client: SourceClient, - /// The client that is connected to the message lane target node. - pub lane_target_client: TargetClient, - /// Source queue. - pub nonces_queue: SourceRangesQueue< - P::SourceHeaderHash, - P::SourceHeaderNumber, - MessageDetailsMap, - >, - /// Source queue range - pub nonces_queue_range: Range, -} diff --git a/relays/messages/src/relay_strategy/rational_strategy.rs b/relays/messages/src/relay_strategy/rational_strategy.rs deleted file mode 100644 index ea4f39d0a..000000000 --- a/relays/messages/src/relay_strategy/rational_strategy.rs +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Rational relay strategy - -use async_trait::async_trait; -use num_traits::SaturatingAdd; - -use bp_messages::MessageNonce; - -use crate::{ - message_lane::MessageLane, - message_lane_loop::{ - SourceClient as MessageLaneSourceClient, TargetClient as MessageLaneTargetClient, - }, - relay_strategy::{RelayReference, RelayStrategy}, -}; - -/// The relayer will deliver all messages and confirmations as long as he's not losing any -/// funds. -#[derive(Clone)] -pub struct RationalStrategy; - -#[async_trait] -impl RelayStrategy for RationalStrategy { - async fn decide< - P: MessageLane, - SourceClient: MessageLaneSourceClient

, - TargetClient: MessageLaneTargetClient

, - >( - &mut self, - reference: &mut RelayReference, - ) -> bool { - // technically, multiple confirmations will be delivered in a single transaction, - // meaning less loses for relayer. But here we don't know the final relayer yet, so - // we're adding a separate transaction for every message. Normally, this cost is covered - // by the message sender. Probably reconsider this? - let confirmation_transaction_cost = - reference.lane_source_client.estimate_confirmation_transaction().await; - - let delivery_transaction_cost = match reference - .lane_target_client - .estimate_delivery_transaction_in_source_tokens( - reference.hard_selected_begin_nonce - ..=(reference.hard_selected_begin_nonce + reference.index as MessageNonce), - reference.selected_prepaid_nonces, - reference.selected_unpaid_weight, - reference.selected_size as u32, - ) - .await - { - Ok(v) => v, - Err(err) => { - log::debug!( - target: "bridge", - "Failed to estimate delivery transaction cost: {:?}. No nonces selected for delivery", - err, - ); - return false; - }, - }; - - // if it is the first message that makes reward less than cost, let's log it - // if this message makes batch profitable again, let's log it - let is_total_reward_less_than_cost = reference.total_reward < reference.total_cost; - let prev_total_cost = reference.total_cost; - let prev_total_reward = reference.total_reward; - reference.total_confirmations_cost = - reference.total_confirmations_cost.saturating_add(&confirmation_transaction_cost); - reference.total_reward = reference.total_reward.saturating_add(&reference.details.reward); - reference.total_cost = - reference.total_confirmations_cost.saturating_add(&delivery_transaction_cost); - if !is_total_reward_less_than_cost && reference.total_reward < reference.total_cost { - log::debug!( - target: "bridge", - "Message with nonce {} (reward = {:?}) changes total cost {:?}->{:?} and makes it larger than \ - total reward {:?}->{:?}", - reference.nonce, - reference.details.reward, - prev_total_cost, - reference.total_cost, - prev_total_reward, - reference.total_reward, - ); - } else if is_total_reward_less_than_cost && reference.total_reward >= reference.total_cost { - log::debug!( - target: "bridge", - "Message with nonce {} (reward = {:?}) changes total cost {:?}->{:?} and makes it less than or \ - equal to the total reward {:?}->{:?} (again)", - reference.nonce, - reference.details.reward, - prev_total_cost, - reference.total_cost, - prev_total_reward, - reference.total_reward, - ); - } - - // Rational relayer never want to lose his funds - if reference.total_reward >= reference.total_cost { - reference.selected_reward = reference.total_reward; - reference.selected_cost = reference.total_cost; - return true; - } - - false - } -} diff --git a/relays/utils/Cargo.toml b/relays/utils/Cargo.toml deleted file mode 100644 index bb69849da..000000000 --- a/relays/utils/Cargo.toml +++ /dev/null @@ -1,32 +0,0 @@ -[package] -name = "relay-utils" -version = "0.1.0" -authors = ["Parity Technologies "] -edition = "2021" -license = "GPL-3.0-or-later WITH Classpath-exception-2.0" - -[dependencies] -ansi_term = "0.12" -anyhow = "1.0" -async-std = "1.6.5" -async-trait = "0.1.40" -backoff = "0.2" -isahc = "1.2" -env_logger = "0.8.2" -futures = "0.3.5" -jsonpath_lib = "0.2" -log = "0.4.11" -num-traits = "0.2" -serde_json = "1.0" -sysinfo = "0.15" -time = { version = "0.3", features = ["formatting", "local-offset", "std"] } -tokio = { version = "1.8", features = ["rt"] } -thiserror = "1.0.26" - -# Bridge dependencies - -bp-runtime = { path = "../../primitives/runtime" } - -# Substrate dependencies - -substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/relays/utils/src/error.rs b/relays/utils/src/error.rs deleted file mode 100644 index 26f1d0cac..000000000 --- a/relays/utils/src/error.rs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. -// Parity Bridges Common 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. -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -use std::net::AddrParseError; -use thiserror::Error; - -/// Result type used by relay utilities. -pub type Result = std::result::Result; - -/// Relay utilities errors. -#[derive(Error, Debug)] -pub enum Error { - /// Failed to request a float value from HTTP service. - #[error("Failed to fetch token price from remote server: {0}")] - FetchTokenPrice(#[source] anyhow::Error), - /// Failed to parse the response from HTTP service. - #[error("Failed to parse HTTP service response: {0:?}. Response: {1:?}")] - ParseHttp(serde_json::Error, String), - /// Failed to select response value from the Json response. - #[error("Failed to select value from response: {0:?}. Response: {1:?}")] - SelectResponseValue(jsonpath_lib::JsonPathError, String), - /// Failed to parse float value from the selected value. - #[error( - "Failed to parse float value {0:?} from response. It is assumed to be positive and normal" - )] - ParseFloat(f64), - /// Couldn't found value in the JSON response. - #[error("Missing required value from response: {0:?}")] - MissingResponseValue(String), - /// Invalid host address was used for exposing Prometheus metrics. - #[error("Invalid host {0} is used to expose Prometheus metrics: {1}")] - ExposingMetricsInvalidHost(String, AddrParseError), - /// Prometheus error. - #[error("{0}")] - Prometheus(#[from] substrate_prometheus_endpoint::prometheus::Error), -} diff --git a/relays/utils/src/initialize.rs b/relays/utils/src/initialize.rs deleted file mode 100644 index ad69a766e..000000000 --- a/relays/utils/src/initialize.rs +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Relayer initialization functions. - -use std::{cell::RefCell, fmt::Display, io::Write}; - -async_std::task_local! { - pub(crate) static LOOP_NAME: RefCell = RefCell::new(String::default()); -} - -/// Initialize relay environment. -pub fn initialize_relay() { - initialize_logger(true); -} - -/// Initialize Relay logger instance. -pub fn initialize_logger(with_timestamp: bool) { - let format = time::format_description::parse( - "[year]-[month]-[day] \ - [hour repr:24]:[minute]:[second] [offset_hour sign:mandatory]", - ) - .expect("static format string is valid"); - - let mut builder = env_logger::Builder::new(); - builder.filter_level(log::LevelFilter::Warn); - builder.filter_module("bridge", log::LevelFilter::Info); - builder.parse_default_env(); - if with_timestamp { - builder.format(move |buf, record| { - let timestamp = time::OffsetDateTime::now_local() - .unwrap_or_else(|_| time::OffsetDateTime::now_utc()); - let timestamp = timestamp.format(&format).unwrap_or_else(|_| timestamp.to_string()); - - let log_level = color_level(record.level()); - let log_target = color_target(record.target()); - let timestamp = if cfg!(windows) { - Either::Left(timestamp) - } else { - Either::Right(ansi_term::Colour::Fixed(8).bold().paint(timestamp)) - }; - - writeln!( - buf, - "{}{} {} {} {}", - loop_name_prefix(), - timestamp, - log_level, - log_target, - record.args(), - ) - }); - } else { - builder.format(move |buf, record| { - let log_level = color_level(record.level()); - let log_target = color_target(record.target()); - - writeln!(buf, "{}{} {} {}", loop_name_prefix(), log_level, log_target, record.args(),) - }); - } - - builder.init(); -} - -/// Initialize relay loop. Must only be called once per every loop task. -pub(crate) fn initialize_loop(loop_name: String) { - LOOP_NAME.with(|g_loop_name| *g_loop_name.borrow_mut() = loop_name); -} - -/// Returns loop name prefix to use in logs. The prefix is initialized with the `initialize_loop` -/// call. -fn loop_name_prefix() -> String { - // try_with to avoid panic outside of async-std task context - LOOP_NAME - .try_with(|loop_name| { - // using borrow is ok here, because loop is only initialized once (=> borrow_mut will - // only be called once) - let loop_name = loop_name.borrow(); - if loop_name.is_empty() { - String::new() - } else { - format!("[{}] ", loop_name) - } - }) - .unwrap_or_else(|_| String::new()) -} - -enum Either { - Left(A), - Right(B), -} -impl Display for Either { - fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { - match self { - Self::Left(a) => write!(fmt, "{}", a), - Self::Right(b) => write!(fmt, "{}", b), - } - } -} - -fn color_target(target: &str) -> impl Display + '_ { - if cfg!(windows) { - Either::Left(target) - } else { - Either::Right(ansi_term::Colour::Fixed(8).paint(target)) - } -} - -fn color_level(level: log::Level) -> impl Display { - if cfg!(windows) { - Either::Left(level) - } else { - let s = level.to_string(); - use ansi_term::Colour as Color; - Either::Right(match level { - log::Level::Error => Color::Fixed(9).bold().paint(s), - log::Level::Warn => Color::Fixed(11).bold().paint(s), - log::Level::Info => Color::Fixed(10).paint(s), - log::Level::Debug => Color::Fixed(14).paint(s), - log::Level::Trace => Color::Fixed(12).paint(s), - }) - } -} diff --git a/relays/utils/src/lib.rs b/relays/utils/src/lib.rs deleted file mode 100644 index a335be791..000000000 --- a/relays/utils/src/lib.rs +++ /dev/null @@ -1,273 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Utilities used by different relays. - -pub use bp_runtime::HeaderId; -pub use error::Error; -pub use relay_loop::{relay_loop, relay_metrics}; - -use backoff::{backoff::Backoff, ExponentialBackoff}; -use futures::future::FutureExt; -use std::time::Duration; -use thiserror::Error; - -/// Max delay after connection-unrelated error happened before we'll try the -/// same request again. -pub const MAX_BACKOFF_INTERVAL: Duration = Duration::from_secs(60); -/// Delay after connection-related error happened before we'll try -/// reconnection again. -pub const CONNECTION_ERROR_DELAY: Duration = Duration::from_secs(10); - -pub mod error; -pub mod initialize; -pub mod metrics; -pub mod relay_loop; - -/// Block number traits shared by all chains that relay is able to serve. -pub trait BlockNumberBase: - 'static - + From - + Into - + Ord - + Clone - + Copy - + Default - + Send - + Sync - + std::fmt::Debug - + std::fmt::Display - + std::hash::Hash - + std::ops::Add - + std::ops::Sub - + num_traits::CheckedSub - + num_traits::Saturating - + num_traits::Zero - + num_traits::One -{ -} - -impl BlockNumberBase for T where - T: 'static - + From - + Into - + Ord - + Clone - + Copy - + Default - + Send - + Sync - + std::fmt::Debug - + std::fmt::Display - + std::hash::Hash - + std::ops::Add - + std::ops::Sub - + num_traits::CheckedSub - + num_traits::Saturating - + num_traits::Zero - + num_traits::One -{ -} - -/// Macro that returns (client, Err(error)) tuple from function if result is Err(error). -#[macro_export] -macro_rules! bail_on_error { - ($result: expr) => { - match $result { - (client, Ok(result)) => (client, result), - (client, Err(error)) => return (client, Err(error)), - } - }; -} - -/// Macro that returns (client, Err(error)) tuple from function if result is Err(error). -#[macro_export] -macro_rules! bail_on_arg_error { - ($result: expr, $client: ident) => { - match $result { - Ok(result) => result, - Err(error) => return ($client, Err(error)), - } - }; -} - -/// Error type that can signal connection errors. -pub trait MaybeConnectionError { - /// Returns true if error (maybe) represents connection error. - fn is_connection_error(&self) -> bool; -} - -/// Stringified error that may be either connection-related or not. -#[derive(Error, Debug)] -pub enum StringifiedMaybeConnectionError { - /// The error is connection-related error. - #[error("{0}")] - Connection(String), - /// The error is connection-unrelated error. - #[error("{0}")] - NonConnection(String), -} - -impl StringifiedMaybeConnectionError { - /// Create new stringified connection error. - pub fn new(is_connection_error: bool, error: String) -> Self { - if is_connection_error { - StringifiedMaybeConnectionError::Connection(error) - } else { - StringifiedMaybeConnectionError::NonConnection(error) - } - } -} - -impl MaybeConnectionError for StringifiedMaybeConnectionError { - fn is_connection_error(&self) -> bool { - match *self { - StringifiedMaybeConnectionError::Connection(_) => true, - StringifiedMaybeConnectionError::NonConnection(_) => false, - } - } -} - -/// Exponential backoff for connection-unrelated errors retries. -pub fn retry_backoff() -> ExponentialBackoff { - ExponentialBackoff { - // we do not want relayer to stop - max_elapsed_time: None, - max_interval: MAX_BACKOFF_INTERVAL, - ..Default::default() - } -} - -/// Compact format of IDs vector. -pub fn format_ids(mut ids: impl ExactSizeIterator) -> String { - const NTH_PROOF: &str = "we have checked len; qed"; - match ids.len() { - 0 => "".into(), - 1 => format!("{:?}", ids.next().expect(NTH_PROOF)), - 2 => { - let id0 = ids.next().expect(NTH_PROOF); - let id1 = ids.next().expect(NTH_PROOF); - format!("[{:?}, {:?}]", id0, id1) - }, - len => { - let id0 = ids.next().expect(NTH_PROOF); - let id_last = ids.last().expect(NTH_PROOF); - format!("{}:[{:?} ... {:?}]", len, id0, id_last) - }, - } -} - -/// Stream that emits item every `timeout_ms` milliseconds. -pub fn interval(timeout: Duration) -> impl futures::Stream { - futures::stream::unfold((), move |_| async move { - async_std::task::sleep(timeout).await; - Some(((), ())) - }) -} - -/// Which client has caused error. -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum FailedClient { - /// It is the source client who has caused error. - Source, - /// It is the target client who has caused error. - Target, - /// Both clients are failing, or we just encountered some other error that - /// should be treated like that. - Both, -} - -/// Future process result. -#[derive(Debug, Clone, Copy)] -pub enum ProcessFutureResult { - /// Future has been processed successfully. - Success, - /// Future has failed with non-connection error. - Failed, - /// Future has failed with connection error. - ConnectionFailed, -} - -impl ProcessFutureResult { - /// Returns true if result is Success. - pub fn is_ok(self) -> bool { - match self { - ProcessFutureResult::Success => true, - ProcessFutureResult::Failed | ProcessFutureResult::ConnectionFailed => false, - } - } - - /// Returns Ok(true) if future has succeeded. - /// Returns Ok(false) if future has failed with non-connection error. - /// Returns Err if future is `ConnectionFailed`. - pub fn fail_if_connection_error( - self, - failed_client: FailedClient, - ) -> Result { - match self { - ProcessFutureResult::Success => Ok(true), - ProcessFutureResult::Failed => Ok(false), - ProcessFutureResult::ConnectionFailed => Err(failed_client), - } - } -} - -/// Process result of the future from a client. -pub fn process_future_result( - result: Result, - retry_backoff: &mut ExponentialBackoff, - on_success: impl FnOnce(TResult), - go_offline_future: &mut std::pin::Pin<&mut futures::future::Fuse>, - go_offline: impl FnOnce(Duration) -> TGoOfflineFuture, - error_pattern: impl FnOnce() -> String, -) -> ProcessFutureResult -where - TError: std::fmt::Debug + MaybeConnectionError, - TGoOfflineFuture: FutureExt, -{ - match result { - Ok(result) => { - on_success(result); - retry_backoff.reset(); - ProcessFutureResult::Success - }, - Err(error) if error.is_connection_error() => { - log::error!( - target: "bridge", - "{}: {:?}. Going to restart", - error_pattern(), - error, - ); - - retry_backoff.reset(); - go_offline_future.set(go_offline(CONNECTION_ERROR_DELAY).fuse()); - ProcessFutureResult::ConnectionFailed - }, - Err(error) => { - let retry_delay = retry_backoff.next_backoff().unwrap_or(CONNECTION_ERROR_DELAY); - log::error!( - target: "bridge", - "{}: {:?}. Retrying in {}", - error_pattern(), - error, - retry_delay.as_secs_f64(), - ); - - go_offline_future.set(go_offline(retry_delay).fuse()); - ProcessFutureResult::Failed - }, - } -} diff --git a/relays/utils/src/metrics.rs b/relays/utils/src/metrics.rs deleted file mode 100644 index 084f72e79..000000000 --- a/relays/utils/src/metrics.rs +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -pub use float_json_value::FloatJsonValueMetric; -pub use global::GlobalMetrics; -pub use substrate_prometheus_endpoint::{ - prometheus::core::{Atomic, Collector}, - register, Counter, CounterVec, Gauge, GaugeVec, Opts, PrometheusError, Registry, F64, I64, U64, -}; - -use async_std::sync::{Arc, RwLock}; -use async_trait::async_trait; -use std::{fmt::Debug, time::Duration}; - -mod float_json_value; -mod global; - -/// Shared reference to `f64` value that is updated by the metric. -pub type F64SharedRef = Arc>>; -/// Int gauge metric type. -pub type IntGauge = Gauge; - -/// Unparsed address that needs to be used to expose Prometheus metrics. -#[derive(Debug, Clone)] -pub struct MetricsAddress { - /// Serve HTTP requests at given host. - pub host: String, - /// Serve HTTP requests at given port. - pub port: u16, -} - -/// Prometheus endpoint MetricsParams. -#[derive(Debug, Clone)] -pub struct MetricsParams { - /// Interface and TCP port to be used when exposing Prometheus metrics. - pub address: Option, - /// Metrics registry. May be `Some(_)` if several components share the same endpoint. - pub registry: Registry, -} - -/// Metric API. -pub trait Metric: Clone + Send + Sync + 'static { - fn register(&self, registry: &Registry) -> Result<(), PrometheusError>; -} - -/// Standalone metric API. -/// -/// Metrics of this kind know how to update themselves, so we may just spawn and forget the -/// asynchronous self-update task. -#[async_trait] -pub trait StandaloneMetric: Metric { - /// Update metric values. - async fn update(&self); - - /// Metrics update interval. - fn update_interval(&self) -> Duration; - - /// Register and spawn metric. Metric is only spawned if it is registered for the first time. - fn register_and_spawn(self, registry: &Registry) -> Result<(), PrometheusError> { - match self.register(registry) { - Ok(()) => { - self.spawn(); - Ok(()) - }, - Err(PrometheusError::AlreadyReg) => Ok(()), - Err(e) => Err(e), - } - } - - /// Spawn the self update task that will keep update metric value at given intervals. - fn spawn(self) { - async_std::task::spawn(async move { - let update_interval = self.update_interval(); - loop { - self.update().await; - async_std::task::sleep(update_interval).await; - } - }); - } -} - -impl Default for MetricsAddress { - fn default() -> Self { - MetricsAddress { host: "127.0.0.1".into(), port: 9616 } - } -} - -impl MetricsParams { - /// Creates metrics params so that metrics are not exposed. - pub fn disabled() -> Self { - MetricsParams { address: None, registry: Registry::new() } - } - - /// Do not expose metrics. - pub fn disable(mut self) -> Self { - self.address = None; - self - } -} - -impl From> for MetricsParams { - fn from(address: Option) -> Self { - MetricsParams { address, registry: Registry::new() } - } -} - -/// Returns metric name optionally prefixed with given prefix. -pub fn metric_name(prefix: Option<&str>, name: &str) -> String { - if let Some(prefix) = prefix { - format!("{}_{}", prefix, name) - } else { - name.into() - } -} - -/// Set value of gauge metric. -/// -/// If value is `Ok(None)` or `Err(_)`, metric would have default value. -pub fn set_gauge_value, E: Debug>( - gauge: &Gauge, - value: Result, E>, -) { - gauge.set(match value { - Ok(Some(value)) => { - log::trace!( - target: "bridge-metrics", - "Updated value of metric '{:?}': {:?}", - gauge.desc().first().map(|d| &d.fq_name), - value, - ); - value - }, - Ok(None) => { - log::warn!( - target: "bridge-metrics", - "Failed to update metric '{:?}': value is empty", - gauge.desc().first().map(|d| &d.fq_name), - ); - Default::default() - }, - Err(error) => { - log::warn!( - target: "bridge-metrics", - "Failed to update metric '{:?}': {:?}", - gauge.desc().first().map(|d| &d.fq_name), - error, - ); - Default::default() - }, - }) -} diff --git a/relays/utils/src/metrics/float_json_value.rs b/relays/utils/src/metrics/float_json_value.rs deleted file mode 100644 index 569acc429..000000000 --- a/relays/utils/src/metrics/float_json_value.rs +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -use crate::{ - error::{self, Error}, - metrics::{ - metric_name, register, F64SharedRef, Gauge, Metric, PrometheusError, Registry, - StandaloneMetric, F64, - }, -}; - -use async_std::sync::{Arc, RwLock}; -use async_trait::async_trait; -use std::time::Duration; - -/// Value update interval. -const UPDATE_INTERVAL: Duration = Duration::from_secs(60); - -/// Metric that represents float value received from HTTP service as float gauge. -/// -/// The float value returned by the service is assumed to be normal (`f64::is_normal` -/// should return `true`) and strictly positive. -#[derive(Debug, Clone)] -pub struct FloatJsonValueMetric { - url: String, - json_path: String, - metric: Gauge, - shared_value_ref: F64SharedRef, -} - -impl FloatJsonValueMetric { - /// Create new metric instance with given name and help. - pub fn new( - url: String, - json_path: String, - name: String, - help: String, - ) -> Result { - let shared_value_ref = Arc::new(RwLock::new(None)); - Ok(FloatJsonValueMetric { - url, - json_path, - metric: Gauge::new(metric_name(None, &name), help)?, - shared_value_ref, - }) - } - - /// Get shared reference to metric value. - pub fn shared_value_ref(&self) -> F64SharedRef { - self.shared_value_ref.clone() - } - - /// Request value from HTTP service. - async fn request_value(&self) -> anyhow::Result { - use isahc::{AsyncReadResponseExt, HttpClient, Request}; - - let request = Request::get(&self.url).header("Accept", "application/json").body(())?; - let raw_response = HttpClient::new()?.send_async(request).await?.text().await?; - Ok(raw_response) - } - - /// Read value from HTTP service. - async fn read_value(&self) -> error::Result { - let raw_response = self.request_value().await.map_err(Error::FetchTokenPrice)?; - parse_service_response(&self.json_path, &raw_response) - } -} - -impl Metric for FloatJsonValueMetric { - fn register(&self, registry: &Registry) -> Result<(), PrometheusError> { - register(self.metric.clone(), registry).map(drop) - } -} - -#[async_trait] -impl StandaloneMetric for FloatJsonValueMetric { - fn update_interval(&self) -> Duration { - UPDATE_INTERVAL - } - - async fn update(&self) { - let value = self.read_value().await; - let maybe_ok = value.as_ref().ok().copied(); - crate::metrics::set_gauge_value(&self.metric, value.map(Some)); - *self.shared_value_ref.write().await = maybe_ok; - } -} - -/// Parse HTTP service response. -fn parse_service_response(json_path: &str, response: &str) -> error::Result { - let json = - serde_json::from_str(response).map_err(|err| Error::ParseHttp(err, response.to_owned()))?; - - let mut selector = jsonpath_lib::selector(&json); - let maybe_selected_value = - selector(json_path).map_err(|err| Error::SelectResponseValue(err, response.to_owned()))?; - let selected_value = maybe_selected_value - .first() - .and_then(|v| v.as_f64()) - .ok_or_else(|| Error::MissingResponseValue(response.to_owned()))?; - if !selected_value.is_normal() || selected_value < 0.0 { - return Err(Error::ParseFloat(selected_value)); - } - - Ok(selected_value) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn parse_service_response_works() { - assert_eq!( - parse_service_response("$.kusama.usd", r#"{"kusama":{"usd":433.05}}"#).map_err(drop), - Ok(433.05), - ); - } - - #[test] - fn parse_service_response_rejects_negative_numbers() { - assert!(parse_service_response("$.kusama.usd", r#"{"kusama":{"usd":-433.05}}"#).is_err()); - } - - #[test] - fn parse_service_response_rejects_zero_numbers() { - assert!(parse_service_response("$.kusama.usd", r#"{"kusama":{"usd":0.0}}"#).is_err()); - } - - #[test] - fn parse_service_response_rejects_nan() { - assert!(parse_service_response("$.kusama.usd", r#"{"kusama":{"usd":NaN}}"#).is_err()); - } -} diff --git a/relays/utils/src/metrics/global.rs b/relays/utils/src/metrics/global.rs deleted file mode 100644 index df90a2c48..000000000 --- a/relays/utils/src/metrics/global.rs +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -//! Global system-wide Prometheus metrics exposed by relays. - -use crate::metrics::{ - metric_name, register, Gauge, GaugeVec, Metric, Opts, PrometheusError, Registry, - StandaloneMetric, F64, U64, -}; - -use async_std::sync::{Arc, Mutex}; -use async_trait::async_trait; -use std::time::Duration; -use sysinfo::{ProcessExt, RefreshKind, System, SystemExt}; - -/// Global metrics update interval. -const UPDATE_INTERVAL: Duration = Duration::from_secs(10); - -/// Global Prometheus metrics. -#[derive(Debug, Clone)] -pub struct GlobalMetrics { - system: Arc>, - system_average_load: GaugeVec, - process_cpu_usage_percentage: Gauge, - process_memory_usage_bytes: Gauge, -} - -impl GlobalMetrics { - /// Create and register global metrics. - pub fn new() -> Result { - Ok(GlobalMetrics { - system: Arc::new(Mutex::new(System::new_with_specifics(RefreshKind::everything()))), - system_average_load: GaugeVec::new( - Opts::new(metric_name(None, "system_average_load"), "System load average"), - &["over"], - )?, - process_cpu_usage_percentage: Gauge::new( - metric_name(None, "process_cpu_usage_percentage"), - "Process CPU usage", - )?, - process_memory_usage_bytes: Gauge::new( - metric_name(None, "process_memory_usage_bytes"), - "Process memory (resident set size) usage", - )?, - }) - } -} - -impl Metric for GlobalMetrics { - fn register(&self, registry: &Registry) -> Result<(), PrometheusError> { - register(self.system_average_load.clone(), registry)?; - register(self.process_cpu_usage_percentage.clone(), registry)?; - register(self.process_memory_usage_bytes.clone(), registry)?; - Ok(()) - } -} - -#[async_trait] -impl StandaloneMetric for GlobalMetrics { - async fn update(&self) { - // update system-wide metrics - let mut system = self.system.lock().await; - let load = system.get_load_average(); - self.system_average_load.with_label_values(&["1min"]).set(load.one); - self.system_average_load.with_label_values(&["5min"]).set(load.five); - self.system_average_load.with_label_values(&["15min"]).set(load.fifteen); - - // update process-related metrics - let pid = sysinfo::get_current_pid().expect( - "only fails where pid is unavailable (os=unknown || arch=wasm32);\ - relay is not supposed to run in such MetricsParamss;\ - qed", - ); - let is_process_refreshed = system.refresh_process(pid); - match (is_process_refreshed, system.get_process(pid)) { - (true, Some(process_info)) => { - let cpu_usage = process_info.cpu_usage() as f64; - let memory_usage = process_info.memory() * 1024; - log::trace!( - target: "bridge-metrics", - "Refreshed process metrics: CPU={}, memory={}", - cpu_usage, - memory_usage, - ); - - self.process_cpu_usage_percentage.set(if cpu_usage.is_finite() { - cpu_usage - } else { - 0f64 - }); - self.process_memory_usage_bytes.set(memory_usage); - }, - _ => { - log::warn!( - target: "bridge-metrics", - "Failed to refresh process information. Metrics may show obsolete values", - ); - }, - } - } - - fn update_interval(&self) -> Duration { - UPDATE_INTERVAL - } -} diff --git a/relays/utils/src/relay_loop.rs b/relays/utils/src/relay_loop.rs deleted file mode 100644 index bf2ea2e45..000000000 --- a/relays/utils/src/relay_loop.rs +++ /dev/null @@ -1,268 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - -use crate::{ - error::Error, - metrics::{Metric, MetricsAddress, MetricsParams}, - FailedClient, MaybeConnectionError, -}; - -use async_trait::async_trait; -use std::{fmt::Debug, future::Future, net::SocketAddr, time::Duration}; -use substrate_prometheus_endpoint::{init_prometheus, Registry}; - -/// Default pause between reconnect attempts. -pub const RECONNECT_DELAY: Duration = Duration::from_secs(10); - -/// Basic blockchain client from relay perspective. -#[async_trait] -pub trait Client: 'static + Clone + Send + Sync { - /// Type of error these clients returns. - type Error: 'static + Debug + MaybeConnectionError + Send + Sync; - - /// Try to reconnect to source node. - async fn reconnect(&mut self) -> Result<(), Self::Error>; -} - -#[async_trait] -impl Client for () { - type Error = crate::StringifiedMaybeConnectionError; - - async fn reconnect(&mut self) -> Result<(), Self::Error> { - Ok(()) - } -} - -/// Returns generic loop that may be customized and started. -pub fn relay_loop(source_client: SC, target_client: TC) -> Loop { - Loop { reconnect_delay: RECONNECT_DELAY, source_client, target_client, loop_metric: None } -} - -/// Returns generic relay loop metrics that may be customized and used in one or several relay -/// loops. -pub fn relay_metrics(params: MetricsParams) -> LoopMetrics<(), (), ()> { - LoopMetrics { - relay_loop: Loop { - reconnect_delay: RECONNECT_DELAY, - source_client: (), - target_client: (), - loop_metric: None, - }, - address: params.address, - registry: params.registry, - loop_metric: None, - } -} - -/// Generic relay loop. -pub struct Loop { - reconnect_delay: Duration, - source_client: SC, - target_client: TC, - loop_metric: Option, -} - -/// Relay loop metrics builder. -pub struct LoopMetrics { - relay_loop: Loop, - address: Option, - registry: Registry, - loop_metric: Option, -} - -impl Loop { - /// Customize delay between reconnect attempts. - pub fn reconnect_delay(mut self, reconnect_delay: Duration) -> Self { - self.reconnect_delay = reconnect_delay; - self - } - - /// Start building loop metrics using given prefix. - pub fn with_metrics(self, params: MetricsParams) -> LoopMetrics { - LoopMetrics { - relay_loop: Loop { - reconnect_delay: self.reconnect_delay, - source_client: self.source_client, - target_client: self.target_client, - loop_metric: None, - }, - address: params.address, - registry: params.registry, - loop_metric: None, - } - } - - /// Run relay loop. - /// - /// This function represents an outer loop, which in turn calls provided `run_loop` function to - /// do actual job. When `run_loop` returns, this outer loop reconnects to failed client (source, - /// target or both) and calls `run_loop` again. - pub async fn run(mut self, loop_name: String, run_loop: R) -> Result<(), Error> - where - R: 'static + Send + Fn(SC, TC, Option) -> F, - F: 'static + Send + Future>, - SC: 'static + Client, - TC: 'static + Client, - LM: 'static + Send + Clone, - { - let run_loop_task = async move { - crate::initialize::initialize_loop(loop_name); - - loop { - let loop_metric = self.loop_metric.clone(); - let future_result = - run_loop(self.source_client.clone(), self.target_client.clone(), loop_metric); - let result = future_result.await; - - match result { - Ok(()) => break, - Err(failed_client) => - reconnect_failed_client( - failed_client, - self.reconnect_delay, - &mut self.source_client, - &mut self.target_client, - ) - .await, - } - - log::debug!(target: "bridge", "Restarting relay loop"); - } - - Ok(()) - }; - - async_std::task::spawn(run_loop_task).await - } -} - -impl LoopMetrics { - /// Add relay loop metrics. - /// - /// Loop metrics will be passed to the loop callback. - pub fn loop_metric( - self, - metric: NewLM, - ) -> Result, Error> { - metric.register(&self.registry)?; - - Ok(LoopMetrics { - relay_loop: self.relay_loop, - address: self.address, - registry: self.registry, - loop_metric: Some(metric), - }) - } - - /// Convert into `MetricsParams` structure so that metrics registry may be extended later. - pub fn into_params(self) -> MetricsParams { - MetricsParams { address: self.address, registry: self.registry } - } - - /// Expose metrics using address passed at creation. - /// - /// If passed `address` is `None`, metrics are not exposed. - pub async fn expose(self) -> Result, Error> { - if let Some(address) = self.address { - let socket_addr = SocketAddr::new( - address - .host - .parse() - .map_err(|err| Error::ExposingMetricsInvalidHost(address.host.clone(), err))?, - address.port, - ); - - let registry = self.registry; - async_std::task::spawn(async move { - let runtime = - match tokio::runtime::Builder::new_current_thread().enable_all().build() { - Ok(runtime) => runtime, - Err(err) => { - log::trace!( - target: "bridge-metrics", - "Failed to create tokio runtime. Prometheus meterics are not available: {:?}", - err, - ); - return; - }, - }; - - let _ = runtime.block_on(async move { - log::trace!( - target: "bridge-metrics", - "Starting prometheus endpoint at: {:?}", - socket_addr, - ); - let result = init_prometheus(socket_addr, registry).await; - log::trace!( - target: "bridge-metrics", - "Prometheus endpoint has exited with result: {:?}", - result, - ); - }); - }); - } - - Ok(Loop { - reconnect_delay: self.relay_loop.reconnect_delay, - source_client: self.relay_loop.source_client, - target_client: self.relay_loop.target_client, - loop_metric: self.loop_metric, - }) - } -} - -/// Deal with the client who has returned connection error. -pub async fn reconnect_failed_client( - failed_client: FailedClient, - reconnect_delay: Duration, - source_client: &mut impl Client, - target_client: &mut impl Client, -) { - loop { - async_std::task::sleep(reconnect_delay).await; - if failed_client == FailedClient::Both || failed_client == FailedClient::Source { - match source_client.reconnect().await { - Ok(()) => (), - Err(error) => { - log::warn!( - target: "bridge", - "Failed to reconnect to source client. Going to retry in {}s: {:?}", - reconnect_delay.as_secs(), - error, - ); - continue; - }, - } - } - if failed_client == FailedClient::Both || failed_client == FailedClient::Target { - match target_client.reconnect().await { - Ok(()) => (), - Err(error) => { - log::warn!( - target: "bridge", - "Failed to reconnect to target client. Going to retry in {}s: {:?}", - reconnect_delay.as_secs(), - error, - ); - continue; - }, - } - } - - break; - } -}