From aea6ac104f401ec6d7af5691e3f08942cf91db6c Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sun, 26 Mar 2023 08:43:01 -0400 Subject: [PATCH] Remove Tendermint for GRANDPA Updates to polkadot-v0.9.40, with a variety of dependency updates accordingly. Substrate thankfully now uses k256 0.13, pathing the way for #256. We couldn't upgrade to polkadot-v0.9.40 without this due to polkadot-v0.9.40 having fundamental changes to syncing. While we could've updated tendermint, it's not worth the continued development effort given its inability to work with multiple validator sets. Purges sc-tendermint. Keeps tendermint-machine for #163. Closes #137, #148, #157, #171. #96 and #99 should be re-scoped/clarified. #134 and #159 also should be clarified. #169 is also no longer a priority since we're only considering temporal deployments of tendermint. #170 also isn't since we're looking at effectively sharded validator sets, so there should be no singular large set needing high performance. --- Cargo.lock | 837 ++++++++++++------ Cargo.toml | 7 +- README.md | 5 + deny.toml | 4 - deploy/serai/Dockerfile | 2 +- substrate/in-instructions/pallet/src/lib.rs | 5 +- substrate/node/Cargo.toml | 14 +- substrate/node/src/chain_spec.rs | 18 +- substrate/node/src/command.rs | 30 +- substrate/node/src/service.rs | 350 ++++---- substrate/runtime/Cargo.toml | 43 +- substrate/runtime/src/lib.rs | 205 ++++- substrate/serai/client/src/serai/mod.rs | 50 +- substrate/serai/client/tests/runner.rs | 2 +- substrate/serai/primitives/src/block.rs | 1 - substrate/tendermint/client/Cargo.toml | 46 - substrate/tendermint/client/LICENSE | 15 - .../tendermint/client/src/authority/gossip.rs | 67 -- .../client/src/authority/import_future.rs | 72 -- .../tendermint/client/src/authority/mod.rs | 494 ----------- .../tendermint/client/src/block_import.rs | 180 ---- substrate/tendermint/client/src/lib.rs | 163 ---- substrate/tendermint/client/src/tendermint.rs | 247 ------ substrate/tendermint/client/src/validators.rs | 191 ---- substrate/tendermint/pallet/Cargo.toml | 38 - substrate/tendermint/pallet/LICENSE | 15 - substrate/tendermint/pallet/src/lib.rs | 75 -- substrate/tendermint/primitives/Cargo.toml | 21 - substrate/tendermint/primitives/LICENSE | 15 - substrate/tendermint/primitives/src/lib.rs | 16 - substrate/tokens/pallet/src/lib.rs | 1 - substrate/validator-sets/pallet/src/lib.rs | 1 - .../machine => tendermint}/Cargo.toml | 2 +- .../tendermint/machine => tendermint}/LICENSE | 0 .../machine => tendermint}/README.md | 0 .../machine => tendermint}/src/block.rs | 0 .../machine => tendermint}/src/ext.rs | 0 .../machine => tendermint}/src/lib.rs | 0 .../machine => tendermint}/src/message_log.rs | 0 .../machine => tendermint}/src/round.rs | 0 .../machine => tendermint}/src/time.rs | 0 .../machine => tendermint}/tests/ext.rs | 0 42 files changed, 1089 insertions(+), 2143 deletions(-) delete mode 100644 substrate/tendermint/client/Cargo.toml delete mode 100644 substrate/tendermint/client/LICENSE delete mode 100644 substrate/tendermint/client/src/authority/gossip.rs delete mode 100644 substrate/tendermint/client/src/authority/import_future.rs delete mode 100644 substrate/tendermint/client/src/authority/mod.rs delete mode 100644 substrate/tendermint/client/src/block_import.rs delete mode 100644 substrate/tendermint/client/src/lib.rs delete mode 100644 substrate/tendermint/client/src/tendermint.rs delete mode 100644 substrate/tendermint/client/src/validators.rs delete mode 100644 substrate/tendermint/pallet/Cargo.toml delete mode 100644 substrate/tendermint/pallet/LICENSE delete mode 100644 substrate/tendermint/pallet/src/lib.rs delete mode 100644 substrate/tendermint/primitives/Cargo.toml delete mode 100644 substrate/tendermint/primitives/LICENSE delete mode 100644 substrate/tendermint/primitives/src/lib.rs rename {substrate/tendermint/machine => tendermint}/Cargo.toml (86%) rename {substrate/tendermint/machine => tendermint}/LICENSE (100%) rename {substrate/tendermint/machine => tendermint}/README.md (100%) rename {substrate/tendermint/machine => tendermint}/src/block.rs (100%) rename {substrate/tendermint/machine => tendermint}/src/ext.rs (100%) rename {substrate/tendermint/machine => tendermint}/src/lib.rs (100%) rename {substrate/tendermint/machine => tendermint}/src/message_log.rs (100%) rename {substrate/tendermint/machine => tendermint}/src/round.rs (100%) rename {substrate/tendermint/machine => tendermint}/src/time.rs (100%) rename {substrate/tendermint/machine => tendermint}/tests/ext.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 464b9015..51819d7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -324,6 +324,17 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e22d1f4b888c298a027c99dc9048015fac177587de20fc30232a057dfbe24a21" +[[package]] +name = "async-channel" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + [[package]] name = "async-io" version = "1.13.0" @@ -1581,9 +1592,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c00419335c41018365ddf7e4d5f1c12ee3659ddcf3e01974650ba1de73d038" +checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" dependencies = [ "cc", "cxxbridge-flags", @@ -1593,9 +1604,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb8307ad413a98fff033c8545ecf133e3257747b3bae935e7602aab8aa92d4ca" +checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" dependencies = [ "cc", "codespan-reporting", @@ -1608,15 +1619,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc52e2eb08915cb12596d29d55f0b5384f00d697a646dbd269b6ecb0fbd9d31" +checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" [[package]] name = "cxxbridge-macro" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "631569015d0d8d54e6c241733f944042623ab6df7bc3be7466874b05fcdb1c5f" +checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" dependencies = [ "proc-macro2", "quote", @@ -2607,6 +2618,19 @@ dependencies = [ "futures", ] +[[package]] +name = "expander" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f360349150728553f92e4c997a16af8915f418d3a0f21b440d34c5632f16ed84" +dependencies = [ + "blake2", + "fs-err", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "eyre" version = "0.6.8" @@ -2806,7 +2830,7 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fork-tree" version = "3.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "parity-scale-codec", ] @@ -2829,7 +2853,7 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "frame-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "frame-support", "frame-support-procedural", @@ -2854,7 +2878,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "Inflector", "array-bytes", @@ -2901,7 +2925,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "frame-support", "frame-system", @@ -2929,13 +2953,14 @@ dependencies = [ [[package]] name = "frame-support" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "bitflags", + "environmental", "frame-metadata", "frame-support-procedural", "impl-trait-for-tuples", - "k256 0.11.6", + "k256 0.13.0", "log", "once_cell", "parity-scale-codec", @@ -2961,7 +2986,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "Inflector", "cfg-expr", @@ -2976,7 +3001,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", @@ -2988,7 +3013,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "3.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "proc-macro2", "quote", @@ -2998,7 +3023,7 @@ dependencies = [ [[package]] name = "frame-system" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "frame-support", "log", @@ -3016,12 +3041,18 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "parity-scale-codec", "sp-api", ] +[[package]] +name = "fs-err" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541" + [[package]] name = "fs2" version = "0.4.3" @@ -3032,6 +3063,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "fs4" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea55201cc351fdb478217c0fb641b59813da9b4efe4c414a9d8f989a657d149" +dependencies = [ + "libc", + "rustix 0.35.13", + "winapi", +] + [[package]] name = "funty" version = "2.0.0" @@ -3362,9 +3404,9 @@ dependencies = [ [[package]] name = "hash-db" -version = "0.15.2" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" +checksum = "8e7d7786361d7425ae2fe4f9e407eb0efaa0840f5212d109cc018c40c35c6ab4" [[package]] name = "hash256-std-hasher" @@ -3844,6 +3886,12 @@ dependencies = [ "webrtc-util", ] +[[package]] +name = "io-lifetimes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ce5ef949d49ee85593fc4d3f3f95ad61657076395cbbce23e2121fc5542074" + [[package]] name = "io-lifetimes" version = "1.0.9" @@ -3886,7 +3934,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8687c819457e979cc940d09cb16e42a1bf70aa6b60a549de6d3a62a0ee90c69e" dependencies = [ "hermit-abi 0.3.1", - "io-lifetimes", + "io-lifetimes 1.0.9", "rustix 0.36.11", "windows-sys 0.45.0", ] @@ -4071,18 +4119,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "k256" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" -dependencies = [ - "cfg-if", - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2 0.10.6", -] - [[package]] name = "k256" version = "0.12.0" @@ -4155,15 +4191,15 @@ dependencies = [ [[package]] name = "lalrpop" -version = "0.19.8" +version = "0.19.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30455341b0e18f276fa64540aff54deafb54c589de6aca68659c63dd2d5d823" +checksum = "f34313ec00c2eb5c3c87ca6732ea02dcf3af99c3ff7a8fb622ffb99c9d860a87" dependencies = [ "ascii-canvas", - "atty", "bit-set", "diff", "ena", + "is-terminal", "itertools", "lalrpop-util", "petgraph", @@ -4178,9 +4214,9 @@ dependencies = [ [[package]] name = "lalrpop-util" -version = "0.19.8" +version = "0.19.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf796c978e9b4d983414f4caedc9273aa33ee214c5b887bd55fde84c85d2dc4" +checksum = "e5c1f7869c94d214466c5fd432dfed12c379fd87786768d36455892d46b18edd" dependencies = [ "regex", ] @@ -4785,6 +4821,12 @@ dependencies = [ "nalgebra", ] +[[package]] +name = "linux-raw-sys" +version = "0.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d" + [[package]] name = "linux-raw-sys" version = "0.1.4" @@ -4946,15 +4988,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "memoffset" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" -dependencies = [ - "autocfg", -] - [[package]] name = "memoffset" version = "0.8.0" @@ -4966,12 +4999,11 @@ dependencies = [ [[package]] name = "memory-db" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e0c7cba9ce19ac7ffd2053ac9f49843bbd3f4318feedfd74e85c19d5fb0ba66" +checksum = "808b50db46293432a45e63bc15ea51e0ab4c0a1647b8eb114e31a3e698dd6fbe" dependencies = [ "hash-db", - "hashbrown 0.12.3", ] [[package]] @@ -5056,9 +5088,9 @@ dependencies = [ [[package]] name = "mockall" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e4a1c770583dac7ab5e2f6c139153b783a53a1bbee9729613f193e59828326" +checksum = "4c84490118f2ee2d74570d114f3d0493cbf02790df303d2707606c3e14e07c96" dependencies = [ "cfg-if", "downcast", @@ -5071,9 +5103,9 @@ dependencies = [ [[package]] name = "mockall_derive" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "832663583d5fa284ca8810bf7015e46c9fff9622d3cf34bd1eea5003fec06dd0" +checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb" dependencies = [ "cfg-if", "proc-macro2", @@ -5460,20 +5492,6 @@ dependencies = [ "memoffset 0.6.5", ] -[[package]] -name = "nix" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" -dependencies = [ - "bitflags", - "cfg-if", - "libc", - "memoffset 0.7.1", - "pin-utils", - "static_assertions", -] - [[package]] name = "nohash-hasher" version = "0.2.0" @@ -5775,7 +5793,7 @@ dependencies = [ [[package]] name = "pallet-assets" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "frame-benchmarking", "frame-support", @@ -5787,10 +5805,64 @@ dependencies = [ "sp-std 5.0.0", ] +[[package]] +name = "pallet-authority-discovery" +version = "4.0.0-dev" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" +dependencies = [ + "frame-support", + "frame-system", + "pallet-session", + "parity-scale-codec", + "scale-info", + "sp-application-crypto", + "sp-authority-discovery", + "sp-runtime", + "sp-std 5.0.0", +] + +[[package]] +name = "pallet-authorship" +version = "4.0.0-dev" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" +dependencies = [ + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "parity-scale-codec", + "scale-info", + "sp-runtime", + "sp-std 5.0.0", +] + +[[package]] +name = "pallet-babe" +version = "4.0.0-dev" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-authorship", + "pallet-session", + "pallet-timestamp", + "parity-scale-codec", + "scale-info", + "sp-application-crypto", + "sp-consensus-babe", + "sp-consensus-vrf", + "sp-io", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std 5.0.0", +] + [[package]] name = "pallet-balances" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "frame-benchmarking", "frame-support", @@ -5802,10 +5874,33 @@ dependencies = [ "sp-std 5.0.0", ] +[[package]] +name = "pallet-grandpa" +version = "4.0.0-dev" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-authorship", + "pallet-session", + "parity-scale-codec", + "scale-info", + "sp-application-crypto", + "sp-consensus-grandpa", + "sp-core", + "sp-io", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std 5.0.0", +] + [[package]] name = "pallet-session" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "frame-support", "frame-system", @@ -5823,23 +5918,10 @@ dependencies = [ "sp-trie", ] -[[package]] -name = "pallet-tendermint" -version = "0.1.0" -dependencies = [ - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-application-crypto", - "sp-core", - "sp-std 5.0.0", -] - [[package]] name = "pallet-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "frame-benchmarking", "frame-support", @@ -5857,7 +5939,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "frame-support", "frame-system", @@ -5873,7 +5955,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -5889,7 +5971,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -6454,9 +6536,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.53" +version = "1.0.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73" +checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534" dependencies = [ "unicode-ident", ] @@ -7081,7 +7163,7 @@ dependencies = [ "log", "netlink-packet-route", "netlink-proto", - "nix 0.24.3", + "nix", "thiserror", "tokio", ] @@ -7146,6 +7228,20 @@ dependencies = [ "nom", ] +[[package]] +name = "rustix" +version = "0.35.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727a1a6d65f786ec22df8a81ca3121107f235970dc1705ed681d3e6e8b9cd5f9" +dependencies = [ + "bitflags", + "errno 0.2.8", + "io-lifetimes 0.7.5", + "libc", + "linux-raw-sys 0.0.46", + "windows-sys 0.42.0", +] + [[package]] name = "rustix" version = "0.36.11" @@ -7154,7 +7250,7 @@ checksum = "db4165c9963ab29e422d6c26fbc1d37f15bace6b2810221f9d925023480fcf0e" dependencies = [ "bitflags", "errno 0.2.8", - "io-lifetimes", + "io-lifetimes 1.0.9", "libc", "linux-raw-sys 0.1.4", "windows-sys 0.45.0", @@ -7168,7 +7264,7 @@ checksum = "62b24138615de35e32031d041a09032ef3487a616d901ca4db224e7d557efae2" dependencies = [ "bitflags", "errno 0.3.0", - "io-lifetimes", + "io-lifetimes 1.0.9", "libc", "linux-raw-sys 0.3.0", "windows-sys 0.45.0", @@ -7273,7 +7369,7 @@ dependencies = [ [[package]] name = "sc-allocator" version = "4.1.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "log", "sp-core", @@ -7281,10 +7377,38 @@ dependencies = [ "thiserror", ] +[[package]] +name = "sc-authority-discovery" +version = "0.10.0-dev" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" +dependencies = [ + "async-trait", + "futures", + "futures-timer", + "ip_network", + "libp2p", + "log", + "parity-scale-codec", + "prost", + "prost-build", + "rand 0.8.5", + "sc-client-api", + "sc-network", + "sc-network-common", + "sp-api", + "sp-authority-discovery", + "sp-blockchain", + "sp-core", + "sp-keystore", + "sp-runtime", + "substrate-prometheus-endpoint", + "thiserror", +] + [[package]] name = "sc-basic-authorship" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "futures", "futures-timer", @@ -7307,7 +7431,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -7317,28 +7441,31 @@ dependencies = [ "sp-core", "sp-inherents", "sp-runtime", - "sp-state-machine", ] [[package]] name = "sc-chain-spec" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "memmap2", "sc-chain-spec-derive", - "sc-network-common", + "sc-client-api", + "sc-executor", + "sc-network", "sc-telemetry", "serde", "serde_json", + "sp-blockchain", "sp-core", "sp-runtime", + "sp-state-machine", ] [[package]] name = "sc-chain-spec-derive" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -7349,7 +7476,7 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "array-bytes", "chrono", @@ -7389,7 +7516,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "fnv", "futures", @@ -7415,7 +7542,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "hash-db", "kvdb", @@ -7441,7 +7568,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "async-trait", "futures", @@ -7463,10 +7590,167 @@ dependencies = [ "thiserror", ] +[[package]] +name = "sc-consensus-babe" +version = "0.10.0-dev" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" +dependencies = [ + "async-trait", + "fork-tree", + "futures", + "log", + "merlin 2.0.1", + "num-bigint", + "num-rational", + "num-traits", + "parity-scale-codec", + "parking_lot 0.12.1", + "sc-client-api", + "sc-consensus", + "sc-consensus-epochs", + "sc-consensus-slots", + "sc-keystore", + "sc-telemetry", + "scale-info", + "schnorrkel", + "sp-api", + "sp-application-crypto", + "sp-block-builder", + "sp-blockchain", + "sp-consensus", + "sp-consensus-babe", + "sp-consensus-slots", + "sp-consensus-vrf", + "sp-core", + "sp-inherents", + "sp-keystore", + "sp-runtime", + "substrate-prometheus-endpoint", + "thiserror", +] + +[[package]] +name = "sc-consensus-babe-rpc" +version = "0.10.0-dev" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" +dependencies = [ + "futures", + "jsonrpsee", + "sc-consensus-babe", + "sc-consensus-epochs", + "sc-rpc-api", + "serde", + "sp-api", + "sp-application-crypto", + "sp-blockchain", + "sp-consensus", + "sp-consensus-babe", + "sp-core", + "sp-keystore", + "sp-runtime", + "thiserror", +] + +[[package]] +name = "sc-consensus-epochs" +version = "0.10.0-dev" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" +dependencies = [ + "fork-tree", + "parity-scale-codec", + "sc-client-api", + "sc-consensus", + "sp-blockchain", + "sp-runtime", +] + +[[package]] +name = "sc-consensus-grandpa" +version = "0.10.0-dev" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" +dependencies = [ + "ahash 0.8.3", + "array-bytes", + "async-trait", + "dyn-clone", + "finality-grandpa", + "fork-tree", + "futures", + "futures-timer", + "log", + "parity-scale-codec", + "parking_lot 0.12.1", + "rand 0.8.5", + "sc-block-builder", + "sc-chain-spec", + "sc-client-api", + "sc-consensus", + "sc-network", + "sc-network-common", + "sc-network-gossip", + "sc-telemetry", + "sc-utils", + "serde_json", + "sp-api", + "sp-application-crypto", + "sp-arithmetic", + "sp-blockchain", + "sp-consensus", + "sp-consensus-grandpa", + "sp-core", + "sp-keystore", + "sp-runtime", + "substrate-prometheus-endpoint", + "thiserror", +] + +[[package]] +name = "sc-consensus-grandpa-rpc" +version = "0.10.0-dev" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" +dependencies = [ + "finality-grandpa", + "futures", + "jsonrpsee", + "log", + "parity-scale-codec", + "sc-client-api", + "sc-consensus-grandpa", + "sc-rpc", + "serde", + "sp-blockchain", + "sp-core", + "sp-runtime", + "thiserror", +] + +[[package]] +name = "sc-consensus-slots" +version = "0.10.0-dev" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" +dependencies = [ + "async-trait", + "futures", + "futures-timer", + "log", + "parity-scale-codec", + "sc-client-api", + "sc-consensus", + "sc-telemetry", + "sp-arithmetic", + "sp-blockchain", + "sp-consensus", + "sp-consensus-slots", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-state-machine", +] + [[package]] name = "sc-executor" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "lru", "parity-scale-codec", @@ -7490,7 +7774,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "sc-allocator", "sp-maybe-compressed-blob", @@ -7503,7 +7787,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "log", "sc-allocator", @@ -7516,7 +7800,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "anyhow", "cfg-if", @@ -7534,13 +7818,14 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "ansi_term", "futures", "futures-timer", "log", "sc-client-api", + "sc-network", "sc-network-common", "sp-blockchain", "sp-runtime", @@ -7549,7 +7834,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "array-bytes", "async-trait", @@ -7564,12 +7849,12 @@ dependencies = [ [[package]] name = "sc-network" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "array-bytes", + "async-channel", "async-trait", "asynchronous-codec", - "backtrace", "bytes", "either", "fnv", @@ -7577,6 +7862,7 @@ dependencies = [ "futures-timer", "ip_network", "libp2p", + "linked_hash_set", "log", "lru", "mockall", @@ -7607,7 +7893,7 @@ dependencies = [ [[package]] name = "sc-network-bitswap" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "cid", "futures", @@ -7616,6 +7902,7 @@ dependencies = [ "prost", "prost-build", "sc-client-api", + "sc-network", "sc-network-common", "sp-blockchain", "sp-runtime", @@ -7626,33 +7913,35 @@ dependencies = [ [[package]] name = "sc-network-common" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ + "array-bytes", "async-trait", "bitflags", "bytes", "futures", "futures-timer", "libp2p", - "linked_hash_set", "parity-scale-codec", "prost-build", "sc-consensus", "sc-peerset", + "sc-utils", "serde", "smallvec", "sp-blockchain", "sp-consensus", - "sp-finality-grandpa", + "sp-consensus-grandpa", "sp-runtime", "substrate-prometheus-endpoint", "thiserror", + "zeroize", ] [[package]] name = "sc-network-gossip" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "ahash 0.8.3", "futures", @@ -7660,6 +7949,7 @@ dependencies = [ "libp2p", "log", "lru", + "sc-network", "sc-network-common", "sc-peerset", "sp-runtime", @@ -7670,7 +7960,7 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "array-bytes", "futures", @@ -7680,6 +7970,7 @@ dependencies = [ "prost", "prost-build", "sc-client-api", + "sc-network", "sc-network-common", "sc-peerset", "sp-blockchain", @@ -7691,12 +7982,13 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "array-bytes", "async-trait", "fork-tree", "futures", + "futures-timer", "libp2p", "log", "lru", @@ -7706,6 +7998,7 @@ dependencies = [ "prost-build", "sc-client-api", "sc-consensus", + "sc-network", "sc-network-common", "sc-peerset", "sc-utils", @@ -7713,8 +8006,8 @@ dependencies = [ "sp-arithmetic", "sp-blockchain", "sp-consensus", + "sp-consensus-grandpa", "sp-core", - "sp-finality-grandpa", "sp-runtime", "substrate-prometheus-endpoint", "thiserror", @@ -7723,7 +8016,7 @@ dependencies = [ [[package]] name = "sc-network-transactions" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "array-bytes", "futures", @@ -7731,6 +8024,7 @@ dependencies = [ "log", "parity-scale-codec", "pin-project", + "sc-network", "sc-network-common", "sc-peerset", "sc-utils", @@ -7742,7 +8036,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "array-bytes", "bytes", @@ -7758,6 +8052,7 @@ dependencies = [ "parking_lot 0.12.1", "rand 0.8.5", "sc-client-api", + "sc-network", "sc-network-common", "sc-peerset", "sc-utils", @@ -7772,7 +8067,7 @@ dependencies = [ [[package]] name = "sc-peerset" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "futures", "libp2p", @@ -7785,7 +8080,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -7794,7 +8089,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "futures", "jsonrpsee", @@ -7824,7 +8119,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -7843,7 +8138,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "http", "jsonrpsee", @@ -7858,7 +8153,7 @@ dependencies = [ [[package]] name = "sc-rpc-spec-v2" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "array-bytes", "futures", @@ -7884,7 +8179,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "async-trait", "directories", @@ -7950,7 +8245,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "log", "parity-scale-codec", @@ -7961,12 +8256,12 @@ dependencies = [ [[package]] name = "sc-storage-monitor" version = "0.1.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "clap 4.1.13", + "fs4", "futures", "log", - "nix 0.26.2", "sc-client-db", "sc-utils", "sp-core", @@ -7977,7 +8272,7 @@ dependencies = [ [[package]] name = "sc-sysinfo" version = "6.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "futures", "libc", @@ -7996,7 +8291,7 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "chrono", "futures", @@ -8012,40 +8307,10 @@ dependencies = [ "wasm-timer", ] -[[package]] -name = "sc-tendermint" -version = "0.1.0" -dependencies = [ - "async-trait", - "futures", - "hex", - "log", - "sc-block-builder", - "sc-client-api", - "sc-consensus", - "sc-network", - "sc-network-common", - "sc-network-gossip", - "sc-service", - "sp-api", - "sp-application-crypto", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-inherents", - "sp-keystore", - "sp-runtime", - "sp-staking", - "sp-tendermint", - "substrate-prometheus-endpoint", - "tendermint-machine", - "tokio", -] - [[package]] name = "sc-tracing" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "ansi_term", "atty", @@ -8076,7 +8341,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -8087,7 +8352,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "async-trait", "futures", @@ -8114,7 +8379,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "async-trait", "futures", @@ -8128,15 +8393,16 @@ dependencies = [ [[package]] name = "sc-utils" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ - "backtrace", + "async-channel", "futures", "futures-timer", "lazy_static", "log", "parking_lot 0.12.1", "prometheus", + "sp-arithmetic", ] [[package]] @@ -8468,19 +8734,25 @@ dependencies = [ "clap 4.1.13", "frame-benchmarking", "frame-benchmarking-cli", + "futures", "jsonrpsee", "pallet-transaction-payment-rpc", + "sc-authority-discovery", "sc-basic-authorship", "sc-cli", "sc-client-api", "sc-client-db", "sc-consensus", + "sc-consensus-babe", + "sc-consensus-babe-rpc", + "sc-consensus-grandpa", + "sc-consensus-grandpa-rpc", "sc-executor", "sc-network", + "sc-network-common", "sc-rpc-api", "sc-service", "sc-telemetry", - "sc-tendermint", "sc-transaction-pool", "sc-transaction-pool-api", "serai-runtime", @@ -8488,10 +8760,12 @@ dependencies = [ "sp-block-builder", "sp-blockchain", "sp-consensus", + "sp-consensus-babe", "sp-core", "sp-inherents", "sp-keyring", "sp-runtime", + "sp-timestamp", "substrate-build-script-utils", "substrate-frame-rpc-system", ] @@ -8521,23 +8795,28 @@ dependencies = [ "hex-literal", "in-instructions-pallet", "pallet-assets", + "pallet-authority-discovery", + "pallet-babe", "pallet-balances", + "pallet-grandpa", "pallet-session", - "pallet-tendermint", + "pallet-timestamp", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", "scale-info", "serai-primitives", "sp-api", + "sp-authority-discovery", "sp-block-builder", + "sp-consensus-babe", + "sp-consensus-grandpa", "sp-core", "sp-inherents", "sp-offchain", "sp-runtime", "sp-session", "sp-std 5.0.0", - "sp-tendermint", "sp-transaction-pool", "sp-version", "substrate-wasm-builder", @@ -8826,7 +9105,7 @@ dependencies = [ [[package]] name = "sp-api" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "hash-db", "log", @@ -8844,9 +9123,11 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ + "Inflector", "blake2", + "expander", "proc-macro-crate", "proc-macro2", "quote", @@ -8856,7 +9137,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "parity-scale-codec", "scale-info", @@ -8869,7 +9150,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "integer-sqrt", "num-traits", @@ -8880,10 +9161,23 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "sp-authority-discovery" +version = "4.0.0-dev" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" +dependencies = [ + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-application-crypto", + "sp-runtime", + "sp-std 5.0.0", +] + [[package]] name = "sp-block-builder" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "parity-scale-codec", "sp-api", @@ -8895,7 +9189,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "futures", "log", @@ -8913,25 +9207,88 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "async-trait", "futures", "log", - "parity-scale-codec", "sp-core", "sp-inherents", "sp-runtime", "sp-state-machine", - "sp-std 5.0.0", - "sp-version", "thiserror", ] +[[package]] +name = "sp-consensus-babe" +version = "0.10.0-dev" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" +dependencies = [ + "async-trait", + "merlin 2.0.1", + "parity-scale-codec", + "scale-info", + "serde", + "sp-api", + "sp-application-crypto", + "sp-consensus", + "sp-consensus-slots", + "sp-consensus-vrf", + "sp-core", + "sp-inherents", + "sp-keystore", + "sp-runtime", + "sp-std 5.0.0", + "sp-timestamp", +] + +[[package]] +name = "sp-consensus-grandpa" +version = "4.0.0-dev" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" +dependencies = [ + "finality-grandpa", + "log", + "parity-scale-codec", + "scale-info", + "serde", + "sp-api", + "sp-application-crypto", + "sp-core", + "sp-keystore", + "sp-runtime", + "sp-std 5.0.0", +] + +[[package]] +name = "sp-consensus-slots" +version = "0.10.0-dev" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", + "sp-std 5.0.0", + "sp-timestamp", +] + +[[package]] +name = "sp-consensus-vrf" +version = "0.10.0-dev" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" +dependencies = [ + "parity-scale-codec", + "scale-info", + "schnorrkel", + "sp-core", + "sp-runtime", + "sp-std 5.0.0", +] + [[package]] name = "sp-core" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "array-bytes", "base58", @@ -8974,9 +9331,9 @@ dependencies = [ [[package]] name = "sp-core-hashing" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ - "blake2", + "blake2b_simd", "byteorder", "digest 0.10.6", "sha2 0.10.6", @@ -9003,7 +9360,7 @@ dependencies = [ [[package]] name = "sp-core-hashing-proc-macro" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "proc-macro2", "quote", @@ -9014,7 +9371,7 @@ dependencies = [ [[package]] name = "sp-database" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "kvdb", "parking_lot 0.12.1", @@ -9023,7 +9380,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "proc-macro2", "quote", @@ -9033,7 +9390,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.13.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "environmental", "parity-scale-codec", @@ -9041,28 +9398,10 @@ dependencies = [ "sp-storage", ] -[[package]] -name = "sp-finality-grandpa" -version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" -dependencies = [ - "finality-grandpa", - "log", - "parity-scale-codec", - "scale-info", - "serde", - "sp-api", - "sp-application-crypto", - "sp-core", - "sp-keystore", - "sp-runtime", - "sp-std 5.0.0", -] - [[package]] name = "sp-inherents" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -9077,7 +9416,7 @@ dependencies = [ [[package]] name = "sp-io" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "bytes", "ed25519", @@ -9102,7 +9441,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "lazy_static", "sp-core", @@ -9113,9 +9452,8 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.13.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ - "async-trait", "futures", "merlin 2.0.1", "parity-scale-codec", @@ -9130,7 +9468,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "4.1.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "thiserror", "zstd", @@ -9139,7 +9477,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "sp-api", "sp-core", @@ -9149,7 +9487,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "backtrace", "lazy_static", @@ -9159,7 +9497,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "rustc-hash", "serde", @@ -9169,7 +9507,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "either", "hash256-std-hasher", @@ -9191,7 +9529,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -9209,7 +9547,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "Inflector", "proc-macro-crate", @@ -9221,7 +9559,7 @@ dependencies = [ [[package]] name = "sp-session" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "parity-scale-codec", "scale-info", @@ -9235,7 +9573,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "parity-scale-codec", "scale-info", @@ -9247,7 +9585,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.13.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "hash-db", "log", @@ -9267,7 +9605,7 @@ dependencies = [ [[package]] name = "sp-std" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" [[package]] name = "sp-std" @@ -9278,7 +9616,7 @@ checksum = "af0ee286f98455272f64ac5bb1384ff21ac029fbb669afbaf48477faff12760e" [[package]] name = "sp-storage" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "impl-serde", "parity-scale-codec", @@ -9288,19 +9626,10 @@ dependencies = [ "sp-std 5.0.0", ] -[[package]] -name = "sp-tendermint" -version = "0.1.0" -dependencies = [ - "sp-api", - "sp-core", - "sp-std 5.0.0", -] - [[package]] name = "sp-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "async-trait", "futures-timer", @@ -9315,7 +9644,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "6.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "parity-scale-codec", "sp-std 5.0.0", @@ -9327,7 +9656,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "sp-api", "sp-runtime", @@ -9336,7 +9665,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "async-trait", "log", @@ -9352,11 +9681,11 @@ dependencies = [ [[package]] name = "sp-trie" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "ahash 0.8.3", "hash-db", - "hashbrown 0.12.3", + "hashbrown 0.13.2", "lazy_static", "memory-db", "nohash-hasher", @@ -9375,7 +9704,7 @@ dependencies = [ [[package]] name = "sp-version" version = "5.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "impl-serde", "parity-scale-codec", @@ -9392,7 +9721,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "parity-scale-codec", "proc-macro2", @@ -9403,7 +9732,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "7.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "anyhow", "impl-trait-for-tuples", @@ -9417,7 +9746,7 @@ dependencies = [ [[package]] name = "sp-weights" version = "4.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "parity-scale-codec", "scale-info", @@ -9586,7 +9915,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "3.0.0" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "platforms 2.0.0", ] @@ -9594,7 +9923,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "4.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "frame-system-rpc-runtime-api", "futures", @@ -9613,7 +9942,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.10.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "hyper", "log", @@ -9625,7 +9954,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "5.0.0-dev" -source = "git+https://github.com/serai-dex/substrate#b1c7248b1fc93e3a453ffa1a14c7bf61dd19f767" +source = "git+https://github.com/serai-dex/substrate#a4cb49764a438bc9066451ac5956ecf3e12de6de" dependencies = [ "ansi_term", "build-helper", @@ -10332,9 +10661,9 @@ dependencies = [ [[package]] name = "trie-db" -version = "0.25.1" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3390c0409daaa6027d6681393316f4ccd3ff82e1590a1e4725014e3ae2bf1920" +checksum = "767abe6ffed88a1889671a102c2861ae742726f52e0a5a425b92c9fbfa7e9c85" dependencies = [ "hash-db", "hashbrown 0.13.2", @@ -10345,9 +10674,9 @@ dependencies = [ [[package]] name = "trie-root" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a36c5ca3911ed3c9a5416ee6c679042064b93fc637ded67e25f92e68d783891" +checksum = "d4ed310ef5ab98f5fa467900ed906cb9232dd5376597e00fd4cba2a449d06c0b" dependencies = [ "hash-db", ] @@ -11270,7 +11599,7 @@ dependencies = [ "lazy_static", "libc", "log", - "nix 0.24.3", + "nix", "rand 0.8.5", "thiserror", "tokio", diff --git a/Cargo.toml b/Cargo.toml index 1faaad53..03d87df9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,8 @@ members = [ "processor/messages", "processor", + "tendermint", + "substrate/serai/primitives", "substrate/serai/client", @@ -35,11 +37,6 @@ members = [ "substrate/validator-sets/primitives", "substrate/validator-sets/pallet", - "substrate/tendermint/machine", - "substrate/tendermint/primitives", - "substrate/tendermint/client", - "substrate/tendermint/pallet", - "substrate/runtime", "substrate/node", ] diff --git a/README.md b/README.md index 7d555174..a2143734 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,11 @@ wallet. - `processor`: A generic chain processor to process data for Serai and process events from Serai, executing transactions as expected and needed. +- `tendermint`: An abstracted implementation of the Tendermint BFT algorithm, + planned to be used in our own micro-blockchain for temporal data needed to + coordinate the Serai validators, yet irrelevant to the Serai network as a + whole. + - `substrate`: Substrate crates used to instantiate the Serai network. - `deploy`: Scripts to deploy a Serai node/test environment. diff --git a/deny.toml b/deny.toml index dbf8555a..a7b43dff 100644 --- a/deny.toml +++ b/deny.toml @@ -56,10 +56,6 @@ exceptions = [ { allow = ["AGPL-3.0"], name = "validator-sets-pallet" }, - { allow = ["AGPL-3.0"], name = "sp-tendermint" }, - { allow = ["AGPL-3.0"], name = "pallet-tendermint" }, - { allow = ["AGPL-3.0"], name = "sc-tendermint" }, - { allow = ["AGPL-3.0"], name = "serai-runtime" }, { allow = ["AGPL-3.0"], name = "serai-node" }, diff --git a/deploy/serai/Dockerfile b/deploy/serai/Dockerfile index 2a8ac31c..b80d5d25 100644 --- a/deploy/serai/Dockerfile +++ b/deploy/serai/Dockerfile @@ -6,7 +6,7 @@ ADD common /serai/common ADD crypto /serai/crypto ADD coins /serai/coins ADD processor /serai/processor -ADD contracts /serai/contracts +ADD tendermint /serai/tendermint ADD substrate /serai/substrate ADD Cargo.toml /serai ADD Cargo.lock /serai diff --git a/substrate/in-instructions/pallet/src/lib.rs b/substrate/in-instructions/pallet/src/lib.rs index 3d5b1074..5be36e30 100644 --- a/substrate/in-instructions/pallet/src/lib.rs +++ b/substrate/in-instructions/pallet/src/lib.rs @@ -2,7 +2,7 @@ #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![cfg_attr(not(feature = "std"), no_std)] -use scale::{Encode, Decode}; +use scale::Encode; use sp_runtime::RuntimeDebug; @@ -12,7 +12,7 @@ pub use in_instructions_primitives as primitives; use primitives::{InInstruction, InInstructionWithBalance, SignedBatch}; #[derive(Clone, Copy, Encode, RuntimeDebug)] -#[cfg_attr(feature = "std", derive(Decode, thiserror::Error))] +#[cfg_attr(feature = "std", derive(scale::Decode, thiserror::Error))] pub enum PalletError { #[cfg_attr(feature = "std", error("batch for unrecognized network"))] UnrecognizedNetwork, @@ -42,7 +42,6 @@ pub mod pallet { } #[pallet::pallet] - #[pallet::generate_store(pub(crate) trait Store)] pub struct Pallet(PhantomData); // Latest block number agreed upon for a coin diff --git a/substrate/node/Cargo.toml b/substrate/node/Cargo.toml index aa78f04a..8e0c072e 100644 --- a/substrate/node/Cargo.toml +++ b/substrate/node/Cargo.toml @@ -16,16 +16,19 @@ async-trait = "0.1" clap = { version = "4", features = ["derive"] } +futures = "0.3" jsonrpsee = { version = "0.16", features = ["server"] } sp-core = { git = "https://github.com/serai-dex/substrate" } sp-keyring = { git = "https://github.com/serai-dex/substrate" } sp-inherents = { git = "https://github.com/serai-dex/substrate" } +sp-timestamp = { git = "https://github.com/serai-dex/substrate" } sp-runtime = { git = "https://github.com/serai-dex/substrate" } sp-blockchain = { git = "https://github.com/serai-dex/substrate" } sp-api = { git = "https://github.com/serai-dex/substrate" } sp-block-builder = { git = "https://github.com/serai-dex/substrate" } sp-consensus = { git = "https://github.com/serai-dex/substrate" } +sp-consensus-babe = { git = "https://github.com/serai-dex/substrate" } frame-benchmarking = { git = "https://github.com/serai-dex/substrate" } frame-benchmarking-cli = { git = "https://github.com/serai-dex/substrate" } @@ -39,9 +42,18 @@ sc-executor = { git = "https://github.com/serai-dex/substrate" } sc-service = { git = "https://github.com/serai-dex/substrate" } sc-client-db = { git = "https://github.com/serai-dex/substrate" } sc-client-api = { git = "https://github.com/serai-dex/substrate" } +sc-network-common = { git = "https://github.com/serai-dex/substrate" } sc-network = { git = "https://github.com/serai-dex/substrate" } sc-consensus = { git = "https://github.com/serai-dex/substrate" } +sc-consensus-babe = { git = "https://github.com/serai-dex/substrate" } +sc-consensus-babe-rpc = { git = "https://github.com/serai-dex/substrate" } + +sc-consensus-grandpa = { git = "https://github.com/serai-dex/substrate" } +sc-consensus-grandpa-rpc = { git = "https://github.com/serai-dex/substrate" } + +sc-authority-discovery = { git = "https://github.com/serai-dex/substrate" } + sc-telemetry = { git = "https://github.com/serai-dex/substrate" } sc-cli = { git = "https://github.com/serai-dex/substrate" } @@ -50,8 +62,6 @@ sc-rpc-api = { git = "https://github.com/serai-dex/substrate" } substrate-frame-rpc-system = { git = "https://github.com/serai-dex/substrate" } pallet-transaction-payment-rpc = { git = "https://github.com/serai-dex/substrate" } -sc-tendermint = { path = "../tendermint/client" } - [build-dependencies] substrate-build-script-utils = { git = "https://github.com/serai-dex/substrate.git" } diff --git a/substrate/node/src/chain_spec.rs b/substrate/node/src/chain_spec.rs index 9f71f721..901eee02 100644 --- a/substrate/node/src/chain_spec.rs +++ b/substrate/node/src/chain_spec.rs @@ -3,9 +3,9 @@ use sp_core::Pair as PairTrait; use sc_service::ChainType; use serai_runtime::{ - primitives::*, tokens::primitives::ADDRESS as TOKENS_ADDRESS, tendermint::crypto::Public, - WASM_BINARY, opaque::SessionKeys, GenesisConfig, SystemConfig, BalancesConfig, AssetsConfig, - ValidatorSetsConfig, SessionConfig, + primitives::*, tokens::primitives::ADDRESS as TOKENS_ADDRESS, WASM_BINARY, opaque::SessionKeys, + BABE_GENESIS_EPOCH_CONFIG, GenesisConfig, SystemConfig, BalancesConfig, AssetsConfig, + ValidatorSetsConfig, SessionConfig, BabeConfig, GrandpaConfig, AuthorityDiscoveryConfig, }; pub type ChainSpec = sc_service::GenericChainSpec; @@ -21,7 +21,11 @@ fn testnet_genesis( ) -> GenesisConfig { let session_key = |name| { let key = account_from_name(name); - (key, key, SessionKeys { tendermint: Public::from(key) }) + ( + key, + key, + SessionKeys { babe: key.into(), grandpa: key.into(), authority_discovery: key.into() }, + ) }; GenesisConfig { @@ -47,7 +51,6 @@ fn testnet_genesis( accounts: vec![], }, - session: SessionConfig { keys: validators.iter().map(|name| session_key(*name)).collect() }, validator_sets: ValidatorSetsConfig { bond: Amount(1_000_000 * 10_u64.pow(8)), networks: vec![ @@ -57,6 +60,11 @@ fn testnet_genesis( ], participants: validators.iter().map(|name| account_from_name(name)).collect(), }, + session: SessionConfig { keys: validators.iter().map(|name| session_key(*name)).collect() }, + babe: BabeConfig { authorities: vec![], epoch_config: Some(BABE_GENESIS_EPOCH_CONFIG) }, + grandpa: GrandpaConfig { authorities: vec![] }, + + authority_discovery: AuthorityDiscoveryConfig { keys: vec![] }, } } diff --git a/substrate/node/src/command.rs b/substrate/node/src/command.rs index 20cd0e29..d2614967 100644 --- a/substrate/node/src/command.rs +++ b/substrate/node/src/command.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use serai_runtime::Block; use sc_service::{PruningMode, PartialComponents}; @@ -9,7 +11,7 @@ use crate::{ chain_spec, cli::{Cli, Subcommand}, command_helper::{RemarkBuilder, inherent_benchmark_data}, - service, + service::{self, FullClient}, }; impl SubstrateCli for Cli { @@ -62,23 +64,23 @@ pub fn run() -> sc_cli::Result<()> { Some(Subcommand::CheckBlock(cmd)) => cli.create_runner(cmd)?.async_run(|config| { let PartialComponents { client, task_manager, import_queue, .. } = - service::new_partial(&config)?.1; + service::new_partial(&config)?; Ok((cmd.run(client, import_queue), task_manager)) }), Some(Subcommand::ExportBlocks(cmd)) => cli.create_runner(cmd)?.async_run(|config| { - let PartialComponents { client, task_manager, .. } = service::new_partial(&config)?.1; + let PartialComponents { client, task_manager, .. } = service::new_partial(&config)?; Ok((cmd.run(client, config.database), task_manager)) }), Some(Subcommand::ExportState(cmd)) => cli.create_runner(cmd)?.async_run(|config| { - let PartialComponents { client, task_manager, .. } = service::new_partial(&config)?.1; + let PartialComponents { client, task_manager, .. } = service::new_partial(&config)?; Ok((cmd.run(client, config.chain_spec), task_manager)) }), Some(Subcommand::ImportBlocks(cmd)) => cli.create_runner(cmd)?.async_run(|config| { let PartialComponents { client, task_manager, import_queue, .. } = - service::new_partial(&config)?.1; + service::new_partial(&config)?; Ok((cmd.run(client, import_queue), task_manager)) }), @@ -87,15 +89,19 @@ pub fn run() -> sc_cli::Result<()> { } Some(Subcommand::Revert(cmd)) => cli.create_runner(cmd)?.async_run(|config| { - let PartialComponents { client, task_manager, backend, .. } = - service::new_partial(&config)?.1; - Ok((cmd.run(client, backend, None), task_manager)) + let PartialComponents { client, task_manager, backend, .. } = service::new_partial(&config)?; + let aux_revert = Box::new(|client: Arc, backend, blocks| { + sc_consensus_babe::revert(client.clone(), backend, blocks)?; + sc_consensus_grandpa::revert(client, blocks)?; + Ok(()) + }); + Ok((cmd.run(client, backend, Some(aux_revert)), task_manager)) }), Some(Subcommand::Benchmark(cmd)) => cli.create_runner(cmd)?.sync_run(|config| match cmd { BenchmarkCmd::Pallet(cmd) => cmd.run::(config), - BenchmarkCmd::Block(cmd) => cmd.run(service::new_partial(&config)?.1.client), + BenchmarkCmd::Block(cmd) => cmd.run(service::new_partial(&config)?.client), #[cfg(not(feature = "runtime-benchmarks"))] BenchmarkCmd::Storage(_) => { @@ -104,12 +110,12 @@ pub fn run() -> sc_cli::Result<()> { #[cfg(feature = "runtime-benchmarks")] BenchmarkCmd::Storage(cmd) => { - let PartialComponents { client, backend, .. } = service::new_partial(&config)?.1; + let PartialComponents { client, backend, .. } = service::new_partial(&config)?; cmd.run(config, client, backend.expose_db(), backend.expose_storage()) } BenchmarkCmd::Overhead(cmd) => { - let client = service::new_partial(&config)?.1.client; + let client = service::new_partial(&config)?.client; cmd.run( config, client.clone(), @@ -120,7 +126,7 @@ pub fn run() -> sc_cli::Result<()> { } BenchmarkCmd::Extrinsic(cmd) => { - let client = service::new_partial(&config)?.1.client; + let client = service::new_partial(&config)?.client; cmd.run( client.clone(), inherent_benchmark_data()?, diff --git a/substrate/node/src/service.rs b/substrate/node/src/service.rs index 03bfde53..b78f8c57 100644 --- a/substrate/node/src/service.rs +++ b/substrate/node/src/service.rs @@ -1,42 +1,24 @@ -use std::{ - error::Error, - boxed::Box, - sync::Arc, - time::{UNIX_EPOCH, SystemTime, Duration}, - str::FromStr, -}; +use std::{boxed::Box, sync::Arc}; -use sp_runtime::traits::{Block as BlockTrait}; -use sp_inherents::CreateInherentDataProviders; -use sp_consensus::DisableProofRecording; -use sp_api::ProvideRuntimeApi; +use futures::stream::StreamExt; + +use sp_timestamp::InherentDataProvider as TimestampInherent; +use sp_consensus_babe::{SlotDuration, inherents::InherentDataProvider as BabeInherent}; use sc_executor::{NativeVersion, NativeExecutionDispatch, NativeElseWasmExecutor}; -use sc_transaction_pool::FullPool; -use sc_network::NetworkService; + +use sc_network_common::sync::warp::WarpSyncParams; +use sc_network::{Event, NetworkEventStream}; use sc_service::{error::Error as ServiceError, Configuration, TaskManager, TFullClient}; use sc_client_api::BlockBackend; use sc_telemetry::{Telemetry, TelemetryWorker}; -pub(crate) use sc_tendermint::{ - TendermintClientMinimal, TendermintValidator, TendermintImport, TendermintAuthority, - TendermintSelectChain, import_queue, -}; -use serai_runtime::{self as runtime, BLOCK_SIZE, TARGET_BLOCK_TIME, opaque::Block, RuntimeApi}; +use serai_runtime::{self as runtime, opaque::Block, RuntimeApi}; -type FullBackend = sc_service::TFullBackend; -pub type FullClient = TFullClient>; - -type PartialComponents = sc_service::PartialComponents< - FullClient, - FullBackend, - TendermintSelectChain, - sc_consensus::DefaultImportQueue, - sc_transaction_pool::FullPool, - Option, ->; +use sc_consensus_babe::{self, SlotProportion}; +use sc_consensus_grandpa as grandpa; pub struct ExecutorDispatch; impl NativeExecutionDispatch for ExecutorDispatch { @@ -54,57 +36,36 @@ impl NativeExecutionDispatch for ExecutorDispatch { } } -pub struct Cidp; -#[async_trait::async_trait] -impl CreateInherentDataProviders for Cidp { - type InherentDataProviders = (); - async fn create_inherent_data_providers( - &self, - _: ::Hash, - _: (), - ) -> Result> { - Ok(()) - } +type FullBackend = sc_service::TFullBackend; +pub type FullClient = TFullClient>; + +type SelectChain = sc_consensus::LongestChain; +type GrandpaBlockImport = grandpa::GrandpaBlockImport; +type BabeBlockImport = sc_consensus_babe::BabeBlockImport; + +type PartialComponents = sc_service::PartialComponents< + FullClient, + FullBackend, + SelectChain, + sc_consensus::DefaultImportQueue, + sc_transaction_pool::FullPool, + ( + BabeBlockImport, + sc_consensus_babe::BabeLink, + grandpa::LinkHalf, + grandpa::SharedVoterState, + Option, + ), +>; + +fn create_inherent_data_providers( + slot_duration: SlotDuration, +) -> (BabeInherent, TimestampInherent) { + let timestamp = TimestampInherent::from_system_time(); + (BabeInherent::from_timestamp_and_slot_duration(*timestamp, slot_duration), timestamp) } -pub struct TendermintValidatorFirm; -impl TendermintClientMinimal for TendermintValidatorFirm { - // TODO: This is passed directly to propose, which warns not to use the hard limit as finalize - // may grow the block. We don't use storage proofs and use the Executive finalize_block. Is that - // guaranteed not to grow the block? - const PROPOSED_BLOCK_SIZE_LIMIT: usize = { BLOCK_SIZE as usize }; - // 3 seconds - const BLOCK_PROCESSING_TIME_IN_SECONDS: u32 = { (TARGET_BLOCK_TIME / 2) as u32 }; - // 1 second - const LATENCY_TIME_IN_SECONDS: u32 = { (TARGET_BLOCK_TIME / 2 / 3) as u32 }; - - type Block = Block; - type Backend = sc_client_db::Backend; - type Api = >::Api; - type Client = FullClient; -} - -impl TendermintValidator for TendermintValidatorFirm { - type CIDP = Cidp; - type Environment = sc_basic_authorship::ProposerFactory< - FullPool, - Self::Backend, - Self::Client, - DisableProofRecording, - >; - - type Network = Arc::Hash>>; -} - -pub fn new_partial( - config: &Configuration, -) -> Result<(TendermintImport, PartialComponents), ServiceError> { - debug_assert_eq!(TARGET_BLOCK_TIME, 6); - - if config.keystore_remote.is_some() { - return Err(ServiceError::Other("Remote Keystores are not supported".to_string())); - } - +pub fn new_partial(config: &Configuration) -> Result { let telemetry = config .telemetry_endpoints .clone() @@ -136,6 +97,8 @@ pub fn new_partial( telemetry }); + let select_chain = sc_consensus::LongestChain::new(backend.clone()); + let transaction_pool = sc_transaction_pool::BasicPool::new_full( config.transaction_pool.clone(), config.role.is_authority().into(), @@ -144,55 +107,69 @@ pub fn new_partial( client.clone(), ); - let (authority, import_queue) = import_queue( - &task_manager.spawn_essential_handle(), + let (grandpa_block_import, grandpa_link) = grandpa::block_import( client.clone(), + &client, + select_chain.clone(), + telemetry.as_ref().map(Telemetry::handle), + )?; + let justification_import = grandpa_block_import.clone(); + + let (block_import, babe_link) = sc_consensus_babe::block_import( + sc_consensus_babe::configuration(&*client)?, + grandpa_block_import, + client.clone(), + )?; + + let slot_duration = babe_link.config().slot_duration(); + let import_queue = sc_consensus_babe::import_queue( + babe_link.clone(), + block_import.clone(), + Some(Box::new(justification_import)), + client.clone(), + select_chain.clone(), + move |_, _| async move { Ok(create_inherent_data_providers(slot_duration)) }, + &task_manager.spawn_essential_handle(), config.prometheus_registry(), - ); + telemetry.as_ref().map(Telemetry::handle), + )?; - let select_chain = TendermintSelectChain::new(backend.clone()); - - Ok(( - authority, - sc_service::PartialComponents { - client, - backend, - task_manager, - import_queue, - keystore_container, - select_chain, - transaction_pool, - other: telemetry, - }, - )) + Ok(sc_service::PartialComponents { + client, + backend, + task_manager, + keystore_container, + select_chain, + import_queue, + transaction_pool, + other: (block_import, babe_link, grandpa_link, grandpa::SharedVoterState::empty(), telemetry), + }) } pub async fn new_full(mut config: Configuration) -> Result { - let ( - authority, - sc_service::PartialComponents { - client, - backend, - mut task_manager, - import_queue, - keystore_container, - select_chain: _, - other: mut telemetry, - transaction_pool, - }, - ) = new_partial(&config)?; + let sc_service::PartialComponents { + client, + backend, + mut task_manager, + import_queue, + keystore_container, + select_chain, + transaction_pool, + other: (block_import, babe_link, grandpa_link, shared_voter_state, mut telemetry), + } = new_partial(&config)?; - let is_authority = config.role.is_authority(); - let genesis = client.block_hash(0).unwrap().unwrap(); - let tendermint_protocol = sc_tendermint::protocol_name(genesis, config.chain_spec.fork_id()); - if is_authority { - config - .network - .extra_sets - .push(sc_tendermint::set_config(tendermint_protocol.clone(), BLOCK_SIZE.into())); - } + let publish_non_global_ips = config.network.allow_non_globals_in_dht; + let grandpa_protocol_name = + grandpa::protocol_standard_name(&client.block_hash(0).unwrap().unwrap(), &config.chain_spec); - let (network, system_rpc_tx, tx_handler_controller, network_starter) = + config.network.extra_sets.push(grandpa::grandpa_peers_set_config(grandpa_protocol_name.clone())); + let warp_sync = Arc::new(grandpa::warp_proof::NetworkProvider::new( + backend.clone(), + grandpa_link.shared_authority_set().clone(), + vec![], + )); + + let (network, system_rpc_tx, tx_handler_controller, network_starter, sync_service) = sc_service::build_network(sc_service::BuildNetworkParams { config: &config, client: client.clone(), @@ -200,7 +177,7 @@ pub async fn new_full(mut config: Configuration) -> Result Result Result, + babe_link, + block_proposal_slot_portion: SlotProportion::new(0.5), + max_block_proposal_slot_portion: None, + telemetry: telemetry.as_ref().map(Telemetry::handle), + }; + + task_manager.spawn_essential_handle().spawn_blocking( + "babe-proposer", + Some("block-authoring"), + sc_consensus_babe::start_babe(babe_config)?, + ); + } + + if role.is_authority() { + task_manager.spawn_handle().spawn( + "authority-discovery-worker", + Some("networking"), + sc_authority_discovery::new_worker_and_service_with_config( + #[allow(clippy::field_reassign_with_default)] + { + let mut worker = sc_authority_discovery::WorkerConfig::default(); + worker.publish_non_global_ips = publish_non_global_ips; + worker + }, + client, + network.clone(), + Box::pin(network.event_stream("authority-discovery").filter_map(|e| async move { + match e { + Event::Dht(e) => Some(e), + _ => None, + } + })), + sc_authority_discovery::Role::PublishAndDiscover(keystore.clone()), + prometheus_registry.clone(), + ) + .0 + .run(), + ); + } + + if enable_grandpa { + task_manager.spawn_essential_handle().spawn_blocking( + "grandpa-voter", + None, + grandpa::run_grandpa_voter(grandpa::GrandpaParams { + config: grandpa::Config { + gossip_duration: std::time::Duration::from_millis(333), + justification_period: 512, + name: Some(name), + observer_enabled: false, + keystore: if role.is_authority() { Some(keystore) } else { None }, + local_role: role, + telemetry: telemetry.as_ref().map(Telemetry::handle), + protocol_name: grandpa_protocol_name, + }, + link: grandpa_link, + network, + sync: Arc::new(sync_service), + telemetry: telemetry.as_ref().map(Telemetry::handle), + voting_rule: grandpa::VotingRulesBuilder::default().build(), + prometheus_registry, + shared_voter_state, + })?, ); } diff --git a/substrate/runtime/Cargo.toml b/substrate/runtime/Cargo.toml index 74c305e7..015c2676 100644 --- a/substrate/runtime/Cargo.toml +++ b/substrate/runtime/Cargo.toml @@ -19,17 +19,23 @@ scale-info = { version = "2", default-features = false, features = ["derive"] } sp-core = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-std = { git = "https://github.com/serai-dex/substrate", default-features = false } + +sp-offchain = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-version = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-inherents = { git = "https://github.com/serai-dex/substrate", default-features = false } -sp-offchain = { git = "https://github.com/serai-dex/substrate", default-features = false } + sp-session = { git = "https://github.com/serai-dex/substrate", default-features = false } +sp-consensus-babe = { git = "https://github.com/serai-dex/substrate", default-features = false } +sp-consensus-grandpa = { git = "https://github.com/serai-dex/substrate", default-features = false } + +sp-authority-discovery = { git = "https://github.com/serai-dex/substrate", default-features = false } + sp-transaction-pool = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-block-builder = { git = "https://github.com/serai-dex/substrate", default-features = false } + sp-runtime = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-api = { git = "https://github.com/serai-dex/substrate", default-features = false } -sp-tendermint = { path = "../tendermint/primitives", default-features = false } - frame-system = { git = "https://github.com/serai-dex/substrate", default-features = false } frame-support = { git = "https://github.com/serai-dex/substrate", default-features = false } frame-executive = { git = "https://github.com/serai-dex/substrate", default-features = false } @@ -37,6 +43,8 @@ frame-benchmarking = { git = "https://github.com/serai-dex/substrate", default-f serai-primitives = { path = "../serai/primitives", default-features = false } +pallet-timestamp = { git = "https://github.com/serai-dex/substrate", default-features = false } + pallet-balances = { git = "https://github.com/serai-dex/substrate", default-features = false } pallet-assets = { git = "https://github.com/serai-dex/substrate", default-features = false } pallet-transaction-payment = { git = "https://github.com/serai-dex/substrate", default-features = false } @@ -46,7 +54,10 @@ in-instructions-pallet = { path = "../in-instructions/pallet", default-features validator-sets-pallet = { path = "../validator-sets/pallet", default-features = false } pallet-session = { git = "https://github.com/serai-dex/substrate", default-features = false } -pallet-tendermint = { path = "../tendermint/pallet", default-features = false } +pallet-babe = { git = "https://github.com/serai-dex/substrate", default-features = false } +pallet-grandpa = { git = "https://github.com/serai-dex/substrate", default-features = false } + +pallet-authority-discovery = { git = "https://github.com/serai-dex/substrate", default-features = false } frame-system-rpc-runtime-api = { git = "https://github.com/serai-dex/substrate", default-features = false } pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/serai-dex/substrate", default-features = false } @@ -61,23 +72,31 @@ std = [ "sp-core/std", "sp-std/std", + + "sp-offchain/std", "sp-version/std", "sp-inherents/std", - "sp-offchain/std", + "sp-session/std", + "sp-consensus-babe/std", + "sp-consensus-grandpa/std", + + "sp-authority-discovery/std", + "sp-transaction-pool/std", "sp-block-builder/std", + "sp-runtime/std", "sp-api/std", - "sp-tendermint/std", - "frame-system/std", "frame-support/std", "frame-executive/std", "serai-primitives/std", + "pallet-timestamp/std", + "pallet-balances/std", "pallet-transaction-payment/std", @@ -87,7 +106,10 @@ std = [ "validator-sets-pallet/std", "pallet-session/std", - "pallet-tendermint/std", + "pallet-babe/std", + "pallet-grandpa/std", + + "pallet-authority-discovery/std", "frame-system-rpc-runtime-api/std", "pallet-transaction-payment-rpc-runtime-api/std", @@ -102,10 +124,13 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-benchmarking/runtime-benchmarks", + "pallet-timestamp/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", "pallet-assets/runtime-benchmarks", - "pallet-tendermint/runtime-benchmarks", + "pallet-babe/runtime-benchmarks", + "pallet-grandpa/runtime-benchmarks", ] default = ["std"] diff --git a/substrate/runtime/src/lib.rs b/substrate/runtime/src/lib.rs index b1bc656d..f24aa291 100644 --- a/substrate/runtime/src/lib.rs +++ b/substrate/runtime/src/lib.rs @@ -12,6 +12,8 @@ pub use serai_primitives as primitives; pub use frame_system as system; pub use frame_support as support; +pub use pallet_timestamp as timestamp; + pub use pallet_balances as balances; pub use pallet_transaction_payment as transaction_payment; @@ -22,7 +24,10 @@ pub use in_instructions_pallet as in_instructions; pub use validator_sets_pallet as validator_sets; pub use pallet_session as session; -pub use pallet_tendermint as tendermint; +pub use pallet_babe as babe; +pub use pallet_grandpa as grandpa; + +pub use pallet_authority_discovery as authority_discovery; // Actually used by the runtime use sp_core::OpaqueMetadata; @@ -52,7 +57,9 @@ use support::{ use transaction_payment::CurrencyAdapter; -use session::PeriodicSessions; +use babe::AuthorityId as BabeId; +use grandpa::AuthorityId as GrandpaId; +use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; /// An index to a block. pub type BlockNumber = u64; @@ -74,7 +81,9 @@ pub mod opaque { impl_opaque_keys! { pub struct SessionKeys { - pub tendermint: Tendermint, + pub babe: Babe, + pub grandpa: Grandpa, + pub authority_discovery: AuthorityDiscovery, } } } @@ -94,6 +103,11 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { state_version: 1, }; +#[cfg(feature = "std")] +pub fn native_version() -> NativeVersion { + NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } +} + // 1 MB pub const BLOCK_SIZE: u32 = 1024 * 1024; // 6 seconds @@ -104,10 +118,13 @@ pub const MINUTES: BlockNumber = 60 / TARGET_BLOCK_TIME; pub const HOURS: BlockNumber = MINUTES * 60; pub const DAYS: BlockNumber = HOURS * 24; -#[cfg(feature = "std")] -pub fn native_version() -> NativeVersion { - NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } -} +pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); + +pub const BABE_GENESIS_EPOCH_CONFIG: sp_consensus_babe::BabeEpochConfiguration = + sp_consensus_babe::BabeEpochConfiguration { + c: PRIMARY_PROBABILITY, + allowed_slots: sp_consensus_babe::AllowedSlots::PrimaryAndSecondaryPlainSlots, + }; const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); @@ -122,14 +139,20 @@ parameter_types! { system::limits::BlockLength::max_with_normal_ratio(BLOCK_SIZE, NORMAL_DISPATCH_RATIO); pub BlockWeights: system::limits::BlockWeights = system::limits::BlockWeights::with_sensible_defaults( - Weight::from_ref_time(2u64 * WEIGHT_REF_TIME_PER_SECOND).set_proof_size(u64::MAX), + Weight::from_parts(2u64 * WEIGHT_REF_TIME_PER_SECOND, u64::MAX), NORMAL_DISPATCH_RATIO, ); + + pub const MaxAuthorities: u32 = 100; } pub struct CallFilter; impl Contains for CallFilter { fn contains(call: &RuntimeCall) -> bool { + if let RuntimeCall::Timestamp(call) = call { + return matches!(call, timestamp::Call::set { .. }); + } + if let RuntimeCall::Balances(call) = call { return matches!(call, balances::Call::transfer { .. } | balances::Call::transfer_all { .. }); } @@ -188,14 +211,29 @@ impl system::Config for Runtime { type MaxConsumers = support::traits::ConstU32<16>; } +impl timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = Babe; + type MinimumPeriod = ConstU64<{ (TARGET_BLOCK_TIME * 1000) / 2 }>; + type WeightInfo = (); +} + impl balances::Config for Runtime { - type MaxLocks = ConstU32<50>; - type MaxReserves = (); - type ReserveIdentifier = [u8; 8]; - type Balance = SubstrateAmount; type RuntimeEvent = RuntimeEvent; + + type Balance = SubstrateAmount; + + type ReserveIdentifier = (); + type HoldIdentifier = (); + type FreezeIdentifier = (); + + type MaxLocks = (); + type MaxReserves = (); + type MaxHolds = (); + type MaxFreezes = (); + type DustRemoval = (); - type ExistentialDeposit = ConstU64<500>; + type ExistentialDeposit = ConstU64<1>; type AccountStore = System; type WeightInfo = balances::weights::SubstrateWeight; } @@ -248,8 +286,9 @@ impl in_instructions::Config for Runtime { type RuntimeEvent = RuntimeEvent; } -const SESSION_LENGTH: BlockNumber = 5 * DAYS; -type Sessions = PeriodicSessions, ConstU64<{ SESSION_LENGTH }>>; +impl validator_sets::Config for Runtime { + type RuntimeEvent = RuntimeEvent; +} pub struct IdentityValidatorIdOf; impl Convert> for IdentityValidatorIdOf { @@ -258,23 +297,49 @@ impl Convert> for IdentityValidatorIdOf { } } -impl validator_sets::Config for Runtime { - type RuntimeEvent = RuntimeEvent; -} - impl session::Config for Runtime { type RuntimeEvent = RuntimeEvent; type ValidatorId = PublicKey; type ValidatorIdOf = IdentityValidatorIdOf; - type ShouldEndSession = Sessions; - type NextSessionRotation = Sessions; - type SessionManager = (); + type ShouldEndSession = Babe; + type NextSessionRotation = Babe; + type SessionManager = (); // TODO? type SessionHandler = ::KeyTypeIdProviders; type Keys = SessionKeys; type WeightInfo = session::weights::SubstrateWeight; } -impl tendermint::Config for Runtime {} +impl babe::Config for Runtime { + #[allow(clippy::identity_op)] + type EpochDuration = ConstU64<{ 1 * DAYS }>; + type ExpectedBlockTime = ConstU64<{ TARGET_BLOCK_TIME * 1000 }>; + type EpochChangeTrigger = pallet_babe::ExternalTrigger; + type DisabledValidators = Session; + + type WeightInfo = (); + + type MaxAuthorities = MaxAuthorities; + + // TODO: Handle equivocation reports + type KeyOwnerProof = sp_core::Void; + type EquivocationReportSystem = (); +} + +impl grandpa::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + + type WeightInfo = (); + type MaxAuthorities = MaxAuthorities; + + // TODO: Handle equivocation reports + type MaxSetIdSessionEntries = ConstU64<0>; + type KeyOwnerProof = sp_core::Void; + type EquivocationReportSystem = (); +} + +impl authority_discovery::Config for Runtime { + type MaxAuthorities = MaxAuthorities; +} pub type Header = generic::Header; pub type Block = generic::Block; @@ -307,6 +372,8 @@ construct_runtime!( { System: system, + Timestamp: timestamp, + Balances: balances, TransactionPayment: transaction_payment, @@ -317,7 +384,10 @@ construct_runtime!( ValidatorSets: validator_sets, Session: session, - Tendermint: tendermint, + Babe: babe, + Grandpa: grandpa, + + AuthorityDiscovery: authority_discovery, } ); @@ -329,8 +399,15 @@ extern crate frame_benchmarking; mod benches { define_benchmarks!( [frame_benchmarking, BaselineBench::] + [system, SystemBench::] + + [pallet_timestamp, Timestamp] + [balances, Balances] + + [babe, Babe] + [grandpa, Grandpa] ); } @@ -353,6 +430,14 @@ sp_api::impl_runtime_apis! { fn metadata() -> OpaqueMetadata { OpaqueMetadata::new(Runtime::metadata().into()) } + + fn metadata_at_version(version: u32) -> Option { + Runtime::metadata_at_version(version) + } + + fn metadata_versions() -> sp_std::vec::Vec { + Runtime::metadata_versions() + } } impl sp_block_builder::BlockBuilder for Runtime { @@ -404,13 +489,69 @@ sp_api::impl_runtime_apis! { } } - impl sp_tendermint::TendermintApi for Runtime { - fn current_session() -> u32 { - Tendermint::session() + impl sp_consensus_babe::BabeApi for Runtime { + fn configuration() -> sp_consensus_babe::BabeConfiguration { + use support::traits::Get; + + let epoch_config = Babe::epoch_config().unwrap_or(BABE_GENESIS_EPOCH_CONFIG); + sp_consensus_babe::BabeConfiguration { + slot_duration: Babe::slot_duration(), + epoch_length: ::EpochDuration::get(), + c: epoch_config.c, + authorities: Babe::authorities().to_vec(), + randomness: Babe::randomness(), + allowed_slots: epoch_config.allowed_slots, + } } - fn validators() -> Vec { - Session::validators().drain(..).map(Into::into).collect() + fn current_epoch_start() -> sp_consensus_babe::Slot { + Babe::current_epoch_start() + } + + fn current_epoch() -> sp_consensus_babe::Epoch { + Babe::current_epoch() + } + + fn next_epoch() -> sp_consensus_babe::Epoch { + Babe::next_epoch() + } + + fn generate_key_ownership_proof( + _: sp_consensus_babe::Slot, + _: BabeId, + ) -> Option { + None + } + + fn submit_report_equivocation_unsigned_extrinsic( + _: sp_consensus_babe::EquivocationProof<::Header>, + _: sp_consensus_babe::OpaqueKeyOwnershipProof, + ) -> Option<()> { + None + } + } + + impl sp_consensus_grandpa::GrandpaApi for Runtime { + fn grandpa_authorities() -> sp_consensus_grandpa::AuthorityList { + Grandpa::grandpa_authorities() + } + + fn current_set_id() -> sp_consensus_grandpa::SetId { + Grandpa::current_set_id() + } + + fn submit_report_equivocation_unsigned_extrinsic( + _: sp_consensus_grandpa::EquivocationProof<::Hash, u64>, + _: sp_consensus_grandpa::OpaqueKeyOwnershipProof, + ) -> Option<()> { + None + } + + fn generate_key_ownership_proof( + _set_id: sp_consensus_grandpa::SetId, + _authority_id: GrandpaId, + ) -> Option { + None } } @@ -446,4 +587,10 @@ sp_api::impl_runtime_apis! { TransactionPayment::length_to_fee(length) } } + + impl sp_authority_discovery::AuthorityDiscoveryApi for Runtime { + fn authorities() -> Vec { + AuthorityDiscovery::authorities() + } + } } diff --git a/substrate/serai/client/src/serai/mod.rs b/substrate/serai/client/src/serai/mod.rs index f4261e32..d8fcf107 100644 --- a/substrate/serai/client/src/serai/mod.rs +++ b/substrate/serai/client/src/serai/mod.rs @@ -12,6 +12,7 @@ use subxt::{ error::Error as SubxtError, utils::Encoded, config::{ + Header as HeaderTrait, substrate::{BlakeTwo256, SubstrateHeader}, extrinsic_params::{BaseExtrinsicParams, BaseExtrinsicParamsBuilder}, }, @@ -66,6 +67,8 @@ pub enum SeraiError { RpcError(SubxtError), #[error("serai-client library was intended for a different runtime version")] InvalidRuntime, + #[error("node is faulty")] + InvalidNode, } #[derive(Clone)] @@ -123,6 +126,44 @@ impl Serai { Ok(self.0.rpc().finalized_head().await.map_err(SeraiError::RpcError)?.into()) } + // There is no provided method for this + // TODO: Add one to Serai + pub async fn is_finalized(&self, header: &Header) -> Result, SeraiError> { + // Get the latest finalized block + let finalized = self.get_latest_block_hash().await?.into(); + // If the latest finalized block is this block, return true + if finalized == header.hash() { + return Ok(Some(true)); + } + + let Some(finalized) = + self.0.rpc().header(Some(finalized)).await.map_err(SeraiError::RpcError)? else { + return Ok(None); + }; + + // If the finalized block has a lower number, this block can't be finalized + if finalized.number() < header.number() { + return Ok(Some(false)); + } + + // This block, if finalized, comes before the finalized block + // If we request the hash of this block's number, Substrate will return the hash on the main + // chain + // If that hash is this hash, this block is finalized + let Some(hash) = + self + .0 + .rpc() + .block_hash(Some(header.number().into())) + .await + .map_err(SeraiError::RpcError)? else { + // This is an error since there is a block at this index + return Err(SeraiError::InvalidNode); + }; + + Ok(Some(header.hash() == hash)) + } + pub async fn get_block(&self, hash: [u8; 32]) -> Result, SeraiError> { let Some(res) = self.0.rpc().block(Some(hash.into())).await.map_err(SeraiError::RpcError)? else { @@ -130,8 +171,7 @@ impl Serai { }; // Only return finalized blocks - let Some(justifications) = res.justifications.as_ref() else { return Ok(None); }; - if justifications.is_empty() { + if self.is_finalized(&res.block.header).await? != Some(true) { return Ok(None); } @@ -140,9 +180,9 @@ impl Serai { // Ideally, this would be get_block_hash, not get_block_by_number // Unfortunately, in order to only operate over only finalized data, we have to check the - // returned hash is for a finalized block. We can only do that by calling subxt's `block`, which - // will return the block and any justifications - // If we're already putting in all the work to get the block, we may as well just return it here + // returned hash is for a finalized block. We can only do that by calling the extensive + // is_finalized method, which at least requires the header + // In practice, the block is likely more useful than the header pub async fn get_block_by_number(&self, number: u64) -> Result, SeraiError> { let Some(hash) = self.0.rpc().block_hash(Some(number.into())).await.map_err(SeraiError::RpcError)? else { diff --git a/substrate/serai/client/tests/runner.rs b/substrate/serai/client/tests/runner.rs index f3013f5c..17e3470c 100644 --- a/substrate/serai/client/tests/runner.rs +++ b/substrate/serai/client/tests/runner.rs @@ -25,7 +25,7 @@ pub async fn provide_batch(batch: SignedBatch) -> [u8; 32] { .await .unwrap() .unwrap() - .header() + .header .number(); let execution = serai.execute_batch(batch.clone()).unwrap(); diff --git a/substrate/serai/primitives/src/block.rs b/substrate/serai/primitives/src/block.rs index deba665e..c8657a68 100644 --- a/substrate/serai/primitives/src/block.rs +++ b/substrate/serai/primitives/src/block.rs @@ -10,7 +10,6 @@ use serde::{Serialize, Deserialize}; use sp_core::H256; /// The type used to identify block numbers. -// Doesn't re-export tendermint-machine's due to traits. #[derive( Clone, Copy, Default, PartialEq, Eq, Hash, Debug, Encode, Decode, MaxEncodedLen, TypeInfo, )] diff --git a/substrate/tendermint/client/Cargo.toml b/substrate/tendermint/client/Cargo.toml deleted file mode 100644 index e78f99bb..00000000 --- a/substrate/tendermint/client/Cargo.toml +++ /dev/null @@ -1,46 +0,0 @@ -[package] -name = "sc-tendermint" -version = "0.1.0" -description = "Tendermint client for Substrate" -license = "AGPL-3.0-only" -repository = "https://github.com/serai-dex/serai/tree/develop/substrate/tendermint/client" -authors = ["Luke Parker "] -edition = "2021" -publish = false - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--cfg", "docsrs"] - -[dependencies] -async-trait = "0.1" - -hex = "0.4" -log = "0.4" - -futures = "0.3" -tokio = { version = "1", features = ["sync", "rt"] } - -sp-core = { git = "https://github.com/serai-dex/substrate" } -sp-application-crypto = { git = "https://github.com/serai-dex/substrate" } -sp-keystore = { git = "https://github.com/serai-dex/substrate" } -sp-inherents = { git = "https://github.com/serai-dex/substrate" } -sp-staking = { git = "https://github.com/serai-dex/substrate" } -sp-blockchain = { git = "https://github.com/serai-dex/substrate" } -sp-runtime = { git = "https://github.com/serai-dex/substrate" } -sp-api = { git = "https://github.com/serai-dex/substrate" } -sp-consensus = { git = "https://github.com/serai-dex/substrate" } - -sp-tendermint = { path = "../primitives" } - -sc-network-common = { git = "https://github.com/serai-dex/substrate" } -sc-network = { git = "https://github.com/serai-dex/substrate" } -sc-network-gossip = { git = "https://github.com/serai-dex/substrate" } -sc-service = { git = "https://github.com/serai-dex/substrate" } -sc-client-api = { git = "https://github.com/serai-dex/substrate" } -sc-block-builder = { git = "https://github.com/serai-dex/substrate" } -sc-consensus = { git = "https://github.com/serai-dex/substrate" } - -substrate-prometheus-endpoint = { git = "https://github.com/serai-dex/substrate" } - -tendermint-machine = { path = "../machine", features = ["substrate"] } diff --git a/substrate/tendermint/client/LICENSE b/substrate/tendermint/client/LICENSE deleted file mode 100644 index c425427c..00000000 --- a/substrate/tendermint/client/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -AGPL-3.0-only license - -Copyright (c) 2022-2023 Luke Parker - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License Version 3 as -published by the Free Software Foundation. - -This program 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 Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . diff --git a/substrate/tendermint/client/src/authority/gossip.rs b/substrate/tendermint/client/src/authority/gossip.rs deleted file mode 100644 index 42e46566..00000000 --- a/substrate/tendermint/client/src/authority/gossip.rs +++ /dev/null @@ -1,67 +0,0 @@ -use std::sync::{Arc, RwLock}; - -use sp_core::Decode; -use sp_runtime::traits::{Hash, Header, Block}; - -use sc_network::PeerId; -use sc_network_gossip::{Validator, ValidatorContext, ValidationResult}; - -use tendermint_machine::{ext::SignatureScheme, SignedMessage}; - -use crate::{TendermintValidator, validators::TendermintValidators}; - -#[derive(Clone)] -pub(crate) struct TendermintGossip { - number: Arc>, - signature_scheme: TendermintValidators, -} - -impl TendermintGossip { - pub(crate) fn new(number: Arc>, signature_scheme: TendermintValidators) -> Self { - TendermintGossip { number, signature_scheme } - } - - pub(crate) fn topic(number: u64) -> ::Hash { - <<::Header as Header>::Hashing as Hash>::hash( - &[b"Tendermint Block Topic".as_ref(), &number.to_le_bytes()].concat(), - ) - } -} - -impl Validator for TendermintGossip { - fn validate( - &self, - _: &mut dyn ValidatorContext, - _: &PeerId, - data: &[u8], - ) -> ValidationResult<::Hash> { - let msg = match SignedMessage::< - u16, - T::Block, - as SignatureScheme>::Signature, - >::decode(&mut &*data) - { - Ok(msg) => msg, - Err(_) => return ValidationResult::Discard, - }; - - if msg.block().0 < *self.number.read().unwrap() { - return ValidationResult::Discard; - } - - // Verify the signature here so we don't carry invalid messages in our gossip layer - // This will cause double verification of the signature, yet that's a minimal cost - if !msg.verify_signature(&self.signature_scheme) { - return ValidationResult::Discard; - } - - ValidationResult::ProcessAndKeep(Self::topic(msg.block().0)) - } - - fn message_expired<'a>( - &'a self, - ) -> Box::Hash, &[u8]) -> bool + 'a> { - let number = self.number.clone(); - Box::new(move |topic, _| topic != Self::topic(*number.read().unwrap())) - } -} diff --git a/substrate/tendermint/client/src/authority/import_future.rs b/substrate/tendermint/client/src/authority/import_future.rs deleted file mode 100644 index c8eda9ee..00000000 --- a/substrate/tendermint/client/src/authority/import_future.rs +++ /dev/null @@ -1,72 +0,0 @@ -use std::{ - pin::Pin, - sync::RwLock, - task::{Poll, Context}, - future::Future, -}; - -use sp_runtime::traits::{Header, Block}; - -use sp_consensus::Error; -use sc_consensus::{BlockImportStatus, BlockImportError, Link}; - -use sc_service::ImportQueue; - -use tendermint_machine::ext::BlockError; - -use crate::TendermintImportQueue; - -// Custom helpers for ImportQueue in order to obtain the result of a block's importing -struct ValidateLink(Option<(B::Hash, Result<(), BlockError>)>); -impl Link for ValidateLink { - fn blocks_processed( - &mut self, - imported: usize, - count: usize, - mut results: Vec<( - Result::Number>, BlockImportError>, - B::Hash, - )>, - ) { - assert!(imported <= 1); - assert_eq!(count, 1); - self.0 = Some(( - results[0].1, - match results.swap_remove(0).0 { - Ok(_) => Ok(()), - Err(BlockImportError::Other(Error::Other(err))) => Err( - err.downcast::().map(|boxed| *boxed.as_ref()).unwrap_or(BlockError::Fatal), - ), - _ => Err(BlockError::Fatal), - }, - )); - } -} - -pub(crate) struct ImportFuture<'a, B: Block, T: Send>( - B::Hash, - RwLock<&'a mut TendermintImportQueue>, -); -impl<'a, B: Block, T: Send> ImportFuture<'a, B, T> { - pub(crate) fn new( - hash: B::Hash, - queue: &'a mut TendermintImportQueue, - ) -> ImportFuture { - ImportFuture(hash, RwLock::new(queue)) - } -} - -impl<'a, B: Block, T: Send> Future for ImportFuture<'a, B, T> { - type Output = Result<(), BlockError>; - - fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll { - let mut link = ValidateLink(None); - self.1.write().unwrap().poll_actions(ctx, &mut link); - if let Some(res) = link.0 { - assert_eq!(res.0, self.0); - Poll::Ready(res.1) - } else { - Poll::Pending - } - } -} diff --git a/substrate/tendermint/client/src/authority/mod.rs b/substrate/tendermint/client/src/authority/mod.rs deleted file mode 100644 index 4181b5ee..00000000 --- a/substrate/tendermint/client/src/authority/mod.rs +++ /dev/null @@ -1,494 +0,0 @@ -use std::{ - sync::{Arc, RwLock}, - time::{UNIX_EPOCH, SystemTime, Duration}, - collections::HashSet, -}; - -use async_trait::async_trait; - -use log::{debug, warn, error}; - -use futures::{ - SinkExt, StreamExt, - lock::Mutex, - channel::mpsc::{self, UnboundedSender}, -}; - -use sp_core::{Encode, Decode, traits::SpawnEssentialNamed}; -use sp_keystore::CryptoStore; -use sp_runtime::{ - traits::{Header, Block}, - Digest, -}; -use sp_blockchain::HeaderBackend; - -use sp_consensus::{Error, BlockOrigin, BlockStatus, Proposer, Environment}; -use sc_consensus::import_queue::IncomingBlock; - -use sc_service::ImportQueue; -use sc_client_api::{BlockBackend, Finalizer, BlockchainEvents}; -use sc_network::{ProtocolName, NetworkBlock}; -use sc_network_gossip::GossipEngine; - -use substrate_prometheus_endpoint::Registry; - -use tendermint_machine::{ - ext::{BlockError, BlockNumber, Commit, SignatureScheme, Network}, - SignedMessage, TendermintMachine, TendermintHandle, -}; - -use crate::{ - CONSENSUS_ID, TendermintValidator, - validators::{TendermintSigner, TendermintValidators}, - tendermint::TendermintImport, -}; - -mod gossip; -use gossip::TendermintGossip; - -mod import_future; -use import_future::ImportFuture; - -// Data for an active validator -// This is distinct as even when we aren't an authority, we still create stubbed Authority objects -// as it's only Authority which implements tendermint_machine::ext::Network. Network has -// verify_commit provided, and even non-authorities have to verify commits -struct ActiveAuthority { - signer: TendermintSigner, - - // The number of the Block we're working on producing - block_in_progress: Arc>, - // Notification channel for when we start on a new block - new_block_event: UnboundedSender<()>, - // Outgoing message queue, placed here as the GossipEngine itself can't be - gossip: UnboundedSender< - SignedMessage as SignatureScheme>::Signature>, - >, - - // Block producer - env: Arc>, - announce: T::Network, -} - -/// Tendermint Authority. Participates in the block proposal and voting process. -pub struct TendermintAuthority { - import: TendermintImport, - active: Option>, -} - -// Get a block to propose after the specified header -// If stub is true, no time will be spent adding transactions to it (beyond what's required), -// making it as minimal as possible (a stub) -// This is so we can create proposals when syncing, respecting tendermint-machine's API boundaries, -// without spending the entire block processing time trying to include transactions (since we know -// our proposal is meaningless and we'll just be syncing a new block anyways) -async fn get_proposal( - env: &Arc>, - import: &TendermintImport, - header: &::Header, -) -> T::Block { - let proposer = - env.lock().await.init(header).await.expect("Failed to create a proposer for the new block"); - - proposer - .propose( - import.inherent_data(*header.parent_hash()).await, - Digest::default(), - // The first processing time is to build the block - // The second is for it to be downloaded (assumes a block won't take longer to download - // than it'll take to process) - // The third is for it to actually be processed - Duration::from_secs((T::BLOCK_PROCESSING_TIME_IN_SECONDS / 3).into()), - Some(T::PROPOSED_BLOCK_SIZE_LIMIT), - ) - .await - .expect("Failed to crate a new block proposal") - .block -} - -impl TendermintAuthority { - // Authority which is capable of verifying commits - pub(crate) fn stub(import: TendermintImport) -> Self { - Self { import, active: None } - } - - async fn get_proposal(&self, header: &::Header) -> T::Block { - get_proposal(&self.active.as_ref().unwrap().env, &self.import, header).await - } - - /// Create and run a new Tendermint Authority, proposing and voting on blocks. - /// This should be spawned on a task as it will not return until the P2P stack shuts down. - #[allow(clippy::too_many_arguments, clippy::new_ret_no_self)] - pub async fn new( - genesis: SystemTime, - protocol: ProtocolName, - import: TendermintImport, - keys: Arc, - providers: T::CIDP, - spawner: impl SpawnEssentialNamed, - env: T::Environment, - network: T::Network, - registry: Option<&Registry>, - ) { - // This should only have a single value, yet a bounded channel with a capacity of 1 would cause - // a firm bound. It's not worth having a backlog crash the node since we aren't constrained - let (new_block_event_send, mut new_block_event_recv) = mpsc::unbounded(); - let (msg_send, mut msg_recv) = mpsc::unbounded(); - - // Move the env into an Arc - let env = Arc::new(Mutex::new(env)); - - // Scoped so the temporary variables used here don't leak - let (block_in_progress, mut gossip, TendermintHandle { mut step, mut messages, machine }) = { - // Get the info necessary to spawn the machine - let info = import.client.info(); - - // Header::Number: TryInto doesn't implement Debug and can't be unwrapped - let last_block: u64 = match info.finalized_number.try_into() { - Ok(best) => best, - Err(_) => panic!("BlockNumber exceeded u64"), - }; - let last_hash = info.finalized_hash; - - let last_time = { - // Convert into a Unix timestamp - let genesis = genesis.duration_since(UNIX_EPOCH).unwrap().as_secs(); - - // Get the last block's time by grabbing its commit and reading the time from that - Commit::>::decode( - &mut import - .client - .justifications(last_hash) - .unwrap() - .map(|justifications| justifications.get(CONSENSUS_ID).cloned().unwrap()) - .unwrap_or_default() - .as_ref(), - ) - .map(|commit| commit.end_time) - // The commit provides the time its block ended at - // The genesis time is when the network starts - // Accordingly, the end of the genesis block is a block time after the genesis time - .unwrap_or_else(|_| genesis + u64::from(Self::block_time())) - }; - - let next_block = last_block + 1; - // Shared references between us and the Tendermint machine (and its actions via its Network - // trait) - let block_in_progress = Arc::new(RwLock::new(next_block)); - - // Write the providers into the import so it can verify inherents - *import.providers.write().await = Some(providers); - - let authority = Self { - import: import.clone(), - active: Some(ActiveAuthority { - signer: TendermintSigner(keys, import.validators.clone()), - - block_in_progress: block_in_progress.clone(), - new_block_event: new_block_event_send, - gossip: msg_send, - - env: env.clone(), - announce: network.clone(), - }), - }; - - // Get our first proposal - let proposal = - authority.get_proposal(&import.client.header(last_hash).unwrap().unwrap()).await; - - // Create the gossip network - // This has to be spawning the machine, else gossip fails for some reason - let gossip = GossipEngine::new( - network, - protocol, - Arc::new(TendermintGossip::new(block_in_progress.clone(), import.validators.clone())), - registry, - ); - - ( - block_in_progress, - gossip, - TendermintMachine::new(authority, BlockNumber(last_block), last_time, proposal).await, - ) - }; - spawner.spawn_essential("machine", Some("tendermint"), Box::pin(machine.run())); - - // Start receiving messages about the Tendermint process for this block - let mut gossip_recv = - gossip.messages_for(TendermintGossip::::topic(*block_in_progress.read().unwrap())); - - // Get finality events from Substrate - let mut finality = import.client.finality_notification_stream(); - - loop { - futures::select_biased! { - // GossipEngine closed down - _ = gossip => { - debug!( - target: "tendermint", - "GossipEngine shut down. {}", - "Is the node shutting down?" - ); - break; - }, - - // Synced a block from the network - notif = finality.next() => { - if let Some(notif) = notif { - let number = match (*notif.header.number()).try_into() { - Ok(number) => number, - Err(_) => panic!("BlockNumber exceeded u64"), - }; - - // There's a race condition between the machine add_block and this - // Both wait for a write lock on this ref and don't release it until after updating it - // accordingly - { - let mut block_in_progress = block_in_progress.write().unwrap(); - if number < *block_in_progress { - continue; - } - let next_block = number + 1; - *block_in_progress = next_block; - gossip_recv = gossip.messages_for(TendermintGossip::::topic(next_block)); - } - - let justifications = import.client.justifications(notif.hash).unwrap().unwrap(); - step.send(( - BlockNumber(number), - Commit::decode(&mut justifications.get(CONSENSUS_ID).unwrap().as_ref()).unwrap(), - // Creating a proposal will fail if syncing occurs radically faster than machine - // stepping takes - // Don't create proposals when stepping accordingly - None - )).await.unwrap(); - } else { - debug!( - target: "tendermint", - "Finality notification stream closed down. {}", - "Is the node shutting down?" - ); - break; - } - }, - - // Machine accomplished a new block - new_block = new_block_event_recv.next() => { - if new_block.is_some() { - gossip_recv = gossip.messages_for( - TendermintGossip::::topic(*block_in_progress.read().unwrap()) - ); - } else { - debug!( - target: "tendermint", - "Block notification stream shut down. {}", - "Is the node shutting down?" - ); - break; - } - }, - - // Message to broadcast - msg = msg_recv.next() => { - if let Some(msg) = msg { - let topic = TendermintGossip::::topic(msg.block().0); - gossip.gossip_message(topic, msg.encode(), false); - } else { - debug!( - target: "tendermint", - "Machine's message channel shut down. {}", - "Is the node shutting down?" - ); - break; - } - }, - - // Received a message - msg = gossip_recv.next() => { - if let Some(msg) = msg { - messages.send( - match SignedMessage::decode(&mut msg.message.as_ref()) { - Ok(msg) => msg, - Err(e) => { - // This is guaranteed to be valid thanks to to the gossip validator, assuming - // that pipeline is correct. This doesn't panic as a hedge - error!(target: "tendermint", "Couldn't decode valid message: {}", e); - continue; - } - } - ).await.unwrap(); - } else { - debug!( - target: "tendermint", - "Gossip channel shut down. {}", - "Is the node shutting down?" - ); - break; - } - } - } - } - } -} - -#[async_trait] -impl Network for TendermintAuthority { - type ValidatorId = u16; - type SignatureScheme = TendermintValidators; - type Weights = TendermintValidators; - type Block = T::Block; - - const BLOCK_PROCESSING_TIME: u32 = T::BLOCK_PROCESSING_TIME_IN_SECONDS; - const LATENCY_TIME: u32 = T::LATENCY_TIME_IN_SECONDS; - - fn signer(&self) -> TendermintSigner { - self.active.as_ref().unwrap().signer.clone() - } - - fn signature_scheme(&self) -> TendermintValidators { - self.import.validators.clone() - } - - fn weights(&self) -> TendermintValidators { - self.import.validators.clone() - } - - async fn broadcast( - &mut self, - msg: SignedMessage as SignatureScheme>::Signature>, - ) { - if self.active.as_mut().unwrap().gossip.unbounded_send(msg).is_err() { - warn!( - target: "tendermint", - "Attempted to broadcast a message except the gossip channel is closed. {}", - "Is the node shutting down?" - ); - } - } - - async fn slash(&mut self, validator: u16) { - // TODO - error!("slashing {}, if this is a local network, this shouldn't happen", validator); - } - - // The Tendermint machine will call add_block for any block which is committed to, regardless of - // validity. To determine validity, it expects a validate function, which Substrate doesn't - // directly offer, and an add function. In order to comply with Serai's modified view of inherent - // transactions, validate MUST check inherents, yet add_block must not. - // - // In order to acquire a validate function, any block proposed by a legitimate proposer is - // imported. This performs full validation and makes the block available as a tip. While this - // would be incredibly unsafe thanks to the unchecked inherents, it's defined as a tip with less - // work, despite being a child of some parent. This means it won't be moved to nor operated on by - // the node. - // - // When Tendermint completes, the block is finalized, setting it as the tip regardless of work. - async fn validate(&mut self, block: &T::Block) -> Result<(), BlockError> { - let hash = block.hash(); - let (header, body) = block.clone().deconstruct(); - let parent = *header.parent_hash(); - let number = *header.number(); - - // Can happen when we sync a block while also acting as a validator - if number <= self.import.client.info().best_number { - debug!(target: "tendermint", "Machine proposed a block for a slot we've already synced"); - Err(BlockError::Temporal)?; - } - - let mut queue_write = self.import.queue.write().await; - *self.import.importing_block.write().unwrap() = Some(hash); - - queue_write.as_mut().unwrap().service_ref().import_blocks( - BlockOrigin::ConsensusBroadcast, // TODO: Use BlockOrigin::Own when it's our block - vec![IncomingBlock { - hash, - header: Some(header), - body: Some(body), - indexed_body: None, - justifications: None, - origin: None, // TODO - allow_missing_state: false, - skip_execution: false, - import_existing: self.import.recheck.read().unwrap().contains(&hash), - state: None, - }], - ); - - ImportFuture::new(hash, queue_write.as_mut().unwrap()).await?; - - // Sanity checks that a child block can have less work than its parent - { - let info = self.import.client.info(); - assert_eq!(info.best_hash, parent); - assert_eq!(info.finalized_hash, parent); - assert_eq!(info.best_number, number - 1u8.into()); - assert_eq!(info.finalized_number, number - 1u8.into()); - } - - Ok(()) - } - - async fn add_block( - &mut self, - block: T::Block, - commit: Commit>, - ) -> Option { - // Prevent import_block from being called while we run - let _lock = self.import.sync_lock.lock().await; - - // If we didn't import this block already, return - // If it's a legitimate block, we'll pick it up in the standard sync loop - if self.import.client.block_status(block.hash()).unwrap() != BlockStatus::InChainWithState { - return None; - } - - // Check if we already imported this externally - if self.import.client.justifications(block.hash()).unwrap().is_some() { - debug!(target: "tendermint", "Machine produced a commit after we already synced it"); - } else { - let hash = block.hash(); - let justification = (CONSENSUS_ID, commit.encode()); - debug_assert!(self.import.verify_justification(hash, &justification).is_ok()); - - let raw_number = *block.header().number(); - let number: u64 = match raw_number.try_into() { - Ok(number) => number, - Err(_) => panic!("BlockNumber exceeded u64"), - }; - - let active = self.active.as_mut().unwrap(); - let mut block_in_progress = active.block_in_progress.write().unwrap(); - // This will hold true unless we received, and handled, a notification for the block before - // its justification was made available - debug_assert_eq!(number, *block_in_progress); - - // Finalize the block - self - .import - .client - .finalize_block(hash, Some(justification), true) - .map_err(|_| Error::InvalidJustification) - .unwrap(); - - // Tell the loop we received a block and to move to the next - *block_in_progress = number + 1; - if active.new_block_event.unbounded_send(()).is_err() { - warn!( - target: "tendermint", - "Attempted to send a new number to the gossip handler except it's closed. {}", - "Is the node shutting down?" - ); - } - - // Announce the block to the network so new clients can sync properly - active.announce.announce_block(hash, None); - active.announce.new_best_block_imported(hash, raw_number); - } - - // Clear any blocks for the previous slot which we were willing to recheck - *self.import.recheck.write().unwrap() = HashSet::new(); - - Some(self.get_proposal(block.header()).await) - } -} diff --git a/substrate/tendermint/client/src/block_import.rs b/substrate/tendermint/client/src/block_import.rs deleted file mode 100644 index 84fc8dab..00000000 --- a/substrate/tendermint/client/src/block_import.rs +++ /dev/null @@ -1,180 +0,0 @@ -use std::{marker::PhantomData, sync::Arc, collections::HashMap}; - -use async_trait::async_trait; - -use sp_runtime::traits::{Header, Block}; -use sp_blockchain::{BlockStatus, HeaderBackend, Backend as BlockchainBackend}; -use sp_consensus::{Error, CacheKeyId, BlockOrigin, SelectChain}; - -use sc_consensus::{BlockCheckParams, BlockImportParams, ImportResult, BlockImport, Verifier}; - -use sc_client_api::{Backend, BlockBackend}; - -use crate::{TendermintValidator, tendermint::TendermintImport}; - -impl TendermintImport { - fn check_already_in_chain(&self, hash: ::Hash) -> bool { - // If it's in chain, with justifications, return it's already on chain - // If it's in chain, without justifications, continue the block import process to import its - // justifications - // This can be triggered if the validators add a block, without justifications, yet the p2p - // process then broadcasts it with its justifications - (self.client.status(hash).unwrap() == BlockStatus::InChain) && - self.client.justifications(hash).unwrap().is_some() - } -} - -#[async_trait] -impl BlockImport for TendermintImport -where - Arc: BlockImport, - as BlockImport>::Error: Into, -{ - type Error = Error; - type Transaction = T::BackendTransaction; - - // TODO: Is there a DoS where you send a block without justifications, causing it to error, - // yet adding it to the blacklist in the process preventing further syncing? - async fn check_block( - &mut self, - mut block: BlockCheckParams, - ) -> Result { - if self.check_already_in_chain(block.hash) { - return Ok(ImportResult::AlreadyInChain); - } - self.verify_order(block.parent_hash, block.number)?; - - // Does not verify origin here as origin only applies to unfinalized blocks - // We don't have context on if this block has justifications or not - - block.allow_missing_state = false; - block.allow_missing_parent = false; - - self.client.check_block(block).await.map_err(Into::into) - } - - async fn import_block( - &mut self, - mut block: BlockImportParams, - new_cache: HashMap>, - ) -> Result { - // Don't allow multiple blocks to be imported at once - let _lock = self.sync_lock.lock().await; - - if self.check_already_in_chain(block.header.hash()) { - return Ok(ImportResult::AlreadyInChain); - } - - self.check(&mut block).await?; - self.client.import_block(block, new_cache).await.map_err(Into::into) - } -} - -#[async_trait] -impl Verifier for TendermintImport -where - Arc: BlockImport, - as BlockImport>::Error: Into, -{ - async fn verify( - &mut self, - mut block: BlockImportParams, - ) -> Result<(BlockImportParams, Option)>>), String> { - block.origin = match block.origin { - BlockOrigin::Genesis => BlockOrigin::Genesis, - BlockOrigin::NetworkBroadcast => BlockOrigin::NetworkBroadcast, - - // Re-map NetworkInitialSync to NetworkBroadcast so it still triggers notifications - // Tendermint will listen to the finality stream. If we sync a block we're running a machine - // for, it'll force the machine to move ahead. We can only do that if there actually are - // notifications - // - // Then Serai also runs data indexing code based on block addition, so ensuring it always - // emits events ensures we always perform our necessary indexing (albeit with a race - // condition since Substrate will eventually prune the block's state, potentially before - // indexing finishes when syncing) - // - // The alternative to this would be editing Substrate directly, which would be a lot less - // fragile, manually triggering the notifications (which may be possible with code intended - // for testing), writing our own notification system, or implementing lock_import_and_run - // on our end, letting us directly set the notifications, so we're not beholden to when - // Substrate decides to call notify_finalized - // - // lock_import_and_run unfortunately doesn't allow async code and generally isn't feasible to - // work with though. We also couldn't use it to prevent Substrate from creating - // notifications, so it only solves half the problem. We'd *still* have to keep this patch, - // with all its fragility, unless we edit Substrate or move the entire block import flow here - BlockOrigin::NetworkInitialSync => BlockOrigin::NetworkBroadcast, - // Also re-map File so bootstraps also trigger notifications, enabling using bootstraps - BlockOrigin::File => BlockOrigin::NetworkBroadcast, - - // We do not want this block, which hasn't been confirmed, to be broadcast over the net - // Substrate will generate notifications unless it's Genesis, which this isn't, InitialSync, - // which changes telemetry behavior, or File, which is... close enough - BlockOrigin::ConsensusBroadcast => BlockOrigin::File, - BlockOrigin::Own => BlockOrigin::File, - }; - - if self.check_already_in_chain(block.header.hash()) { - return Ok((block, None)); - } - - self.check(&mut block).await.map_err(|e| format!("{e}"))?; - Ok((block, None)) - } -} - -/// Tendermint's Select Chain, where the best chain is defined as the most recently finalized -/// block. -/// -/// leaves panics on call due to not being applicable under Tendermint. Any provided answer would -/// have conflicts best left unraised. -// -// SelectChain, while provided by Substrate and part of PartialComponents, isn't used by Substrate -// It's common between various block-production/finality crates, yet Substrate as a system doesn't -// rely on it, which is good, because its definition is explicitly incompatible with Tendermint -// -// leaves is supposed to return all leaves of the blockchain. While Tendermint maintains that view, -// an honest node will only build on the most recently finalized block, so it is a 'leaf' despite -// having descendants -// -// best_chain will always be this finalized block, yet Substrate explicitly defines it as one of -// the above leaves, which this finalized block is explicitly not included in. Accordingly, we -// can never provide a compatible decision -// -// Since PartialComponents expects it, an implementation which does its best is provided. It panics -// if leaves is called, yet returns the finalized chain tip for best_chain, as that's intended to -// be the header to build upon -pub struct TendermintSelectChain>(Arc, PhantomData); - -impl> Clone for TendermintSelectChain { - fn clone(&self) -> Self { - TendermintSelectChain(self.0.clone(), PhantomData) - } -} - -impl> TendermintSelectChain { - pub fn new(backend: Arc) -> TendermintSelectChain { - TendermintSelectChain(backend, PhantomData) - } -} - -#[async_trait] -impl> SelectChain for TendermintSelectChain { - async fn leaves(&self) -> Result, Error> { - panic!("Substrate definition of leaves is incompatible with Tendermint") - } - - async fn best_chain(&self) -> Result { - Ok( - self - .0 - .blockchain() - // There should always be a finalized block - .header(self.0.blockchain().last_finalized().unwrap()) - // There should not be an error in retrieving it and since it's finalized, it should exist - .unwrap() - .unwrap(), - ) - } -} diff --git a/substrate/tendermint/client/src/lib.rs b/substrate/tendermint/client/src/lib.rs deleted file mode 100644 index acc2536c..00000000 --- a/substrate/tendermint/client/src/lib.rs +++ /dev/null @@ -1,163 +0,0 @@ -use std::sync::Arc; - -use sp_core::crypto::KeyTypeId; -use sp_inherents::CreateInherentDataProviders; -use sp_runtime::traits::{Header, Block}; -use sp_blockchain::HeaderBackend; -use sp_api::{StateBackend, StateBackendFor, TransactionFor, ApiExt, ProvideRuntimeApi}; -use sp_consensus::{Error, Environment}; - -use sc_client_api::{BlockBackend, Backend, Finalizer, BlockchainEvents}; -use sc_block_builder::BlockBuilderApi; -use sc_consensus::{BlockImport, BasicQueue}; - -use sc_network_common::config::NonDefaultSetConfig; -use sc_network::{ProtocolName, NetworkBlock}; -use sc_network_gossip::Network; - -use sp_tendermint::TendermintApi; - -use substrate_prometheus_endpoint::Registry; - -mod validators; - -pub(crate) mod tendermint; -pub use tendermint::TendermintImport; - -mod block_import; -pub use block_import::TendermintSelectChain; - -pub(crate) mod authority; -pub use authority::TendermintAuthority; - -pub const CONSENSUS_ID: [u8; 4] = *b"tend"; -pub(crate) const KEY_TYPE_ID: KeyTypeId = KeyTypeId(CONSENSUS_ID); - -const PROTOCOL_NAME: &str = "/tendermint/1"; - -pub fn protocol_name>(genesis: Hash, fork: Option<&str>) -> ProtocolName { - let mut name = format!("/{}", hex::encode(genesis.as_ref())); - if let Some(fork) = fork { - name += &format!("/{fork}"); - } - name += PROTOCOL_NAME; - name.into() -} - -pub fn set_config(protocol: ProtocolName, block_size: u64) -> NonDefaultSetConfig { - // The extra 512 bytes is for the additional data part of Tendermint - // Even with BLS, that should just be 161 bytes in the worst case, for a perfect messaging scheme - // While 256 bytes would suffice there, it's unknown if any LibP2P overhead exists nor if - // anything here will be perfect. Considering this is miniscule compared to the block size, it's - // better safe than sorry. - let mut cfg = NonDefaultSetConfig::new(protocol, block_size + 512); - cfg.allow_non_reserved(25, 25); - cfg -} - -/// Trait consolidating all generics required by sc_tendermint for processing. -pub trait TendermintClient: Send + Sync + 'static { - const PROPOSED_BLOCK_SIZE_LIMIT: usize; - const BLOCK_PROCESSING_TIME_IN_SECONDS: u32; - const LATENCY_TIME_IN_SECONDS: u32; - - type Block: Block; - type Backend: Backend + 'static; - - /// TransactionFor - type BackendTransaction: Send + Sync + 'static; - /// StateBackendFor - type StateBackend: StateBackend< - <::Header as Header>::Hashing, - Transaction = Self::BackendTransaction, - >; - // Client::Api - type Api: ApiExt - + BlockBuilderApi - + TendermintApi; - type Client: Send - + Sync - + HeaderBackend - + BlockBackend - + BlockImport - + Finalizer - + BlockchainEvents - + ProvideRuntimeApi - + 'static; -} - -/// Trait implementable on firm types to automatically provide a full TendermintClient impl. -pub trait TendermintClientMinimal: Send + Sync + 'static { - const PROPOSED_BLOCK_SIZE_LIMIT: usize; - const BLOCK_PROCESSING_TIME_IN_SECONDS: u32; - const LATENCY_TIME_IN_SECONDS: u32; - - type Block: Block; - type Backend: Backend + 'static; - type Api: ApiExt + BlockBuilderApi + TendermintApi; - type Client: Send - + Sync - + HeaderBackend - + BlockBackend - + BlockImport> - + Finalizer - + BlockchainEvents - + ProvideRuntimeApi - + 'static; -} - -impl TendermintClient for T -where - >::Api: - BlockBuilderApi + TendermintApi, - TransactionFor: Send + Sync + 'static, -{ - const PROPOSED_BLOCK_SIZE_LIMIT: usize = T::PROPOSED_BLOCK_SIZE_LIMIT; - const BLOCK_PROCESSING_TIME_IN_SECONDS: u32 = T::BLOCK_PROCESSING_TIME_IN_SECONDS; - const LATENCY_TIME_IN_SECONDS: u32 = T::LATENCY_TIME_IN_SECONDS; - - type Block = T::Block; - type Backend = T::Backend; - - type BackendTransaction = TransactionFor; - type StateBackend = StateBackendFor; - type Api = >::Api; - type Client = T::Client; -} - -/// Trait consolidating additional generics required by sc_tendermint for authoring. -pub trait TendermintValidator: TendermintClient { - type CIDP: CreateInherentDataProviders + 'static; - type Environment: Send + Sync + Environment + 'static; - - type Network: Clone - + Send - + Sync - + Network - + NetworkBlock<::Hash, <::Header as Header>::Number> - + 'static; -} - -pub type TendermintImportQueue = BasicQueue; - -/// Create an import queue, additionally returning the Tendermint Import object iself, enabling -/// creating an author later as well. -pub fn import_queue( - spawner: &impl sp_core::traits::SpawnEssentialNamed, - client: Arc, - registry: Option<&Registry>, -) -> (TendermintImport, TendermintImportQueue) -where - Arc: BlockImport, - as BlockImport>::Error: Into, -{ - let import = TendermintImport::::new(client); - - let boxed = Box::new(import.clone()); - // Use None for the justification importer since justifications always come with blocks - // Therefore, they're never imported after the fact, which is what mandates an importer - let queue = || BasicQueue::new(import.clone(), boxed.clone(), None, spawner, registry); - - *futures::executor::block_on(import.queue.write()) = Some(queue()); - (import.clone(), queue()) -} diff --git a/substrate/tendermint/client/src/tendermint.rs b/substrate/tendermint/client/src/tendermint.rs deleted file mode 100644 index 49f21506..00000000 --- a/substrate/tendermint/client/src/tendermint.rs +++ /dev/null @@ -1,247 +0,0 @@ -use std::{ - sync::{Arc, RwLock}, - collections::HashSet, -}; - -use log::{debug, warn}; - -use tokio::sync::{Mutex, RwLock as AsyncRwLock}; - -use sp_core::Decode; -use sp_runtime::{ - traits::{Header, Block}, - Justification, -}; -use sp_inherents::{InherentData, InherentDataProvider, CreateInherentDataProviders}; -use sp_blockchain::HeaderBackend; -use sp_api::ProvideRuntimeApi; - -use sp_consensus::Error; -use sc_consensus::{ForkChoiceStrategy, BlockImportParams}; - -use sc_block_builder::BlockBuilderApi; - -use tendermint_machine::ext::{BlockError, Commit, Network}; - -use crate::{ - CONSENSUS_ID, TendermintClient, TendermintValidator, validators::TendermintValidators, - TendermintImportQueue, authority::TendermintAuthority, -}; - -type InstantiatedTendermintImportQueue = TendermintImportQueue< - ::Block, - ::BackendTransaction, ->; - -/// Tendermint import handler. -pub struct TendermintImport { - // Lock ensuring only one block is imported at a time - pub(crate) sync_lock: Arc>, - - pub(crate) validators: TendermintValidators, - - pub(crate) providers: Arc>>, - pub(crate) importing_block: Arc::Hash>>>, - - // A set of blocks which we're willing to recheck - // We reject blocks with invalid inherents, yet inherents can be fatally flawed or solely - // perceived as flawed - // If we solely perceive them as flawed, we mark them as eligible for being checked again. Then, - // if they're proposed again, we see if our perception has changed - pub(crate) recheck: Arc::Hash>>>, - - pub(crate) client: Arc, - pub(crate) queue: Arc>>>, -} - -impl Clone for TendermintImport { - fn clone(&self) -> Self { - TendermintImport { - sync_lock: self.sync_lock.clone(), - - validators: self.validators.clone(), - - providers: self.providers.clone(), - importing_block: self.importing_block.clone(), - recheck: self.recheck.clone(), - - client: self.client.clone(), - queue: self.queue.clone(), - } - } -} - -impl TendermintImport { - pub(crate) fn new(client: Arc) -> TendermintImport { - TendermintImport { - sync_lock: Arc::new(Mutex::new(())), - - validators: TendermintValidators::new(client.clone()), - - providers: Arc::new(AsyncRwLock::new(None)), - importing_block: Arc::new(RwLock::new(None)), - recheck: Arc::new(RwLock::new(HashSet::new())), - - client, - queue: Arc::new(AsyncRwLock::new(None)), - } - } - - pub(crate) async fn inherent_data(&self, parent: ::Hash) -> InherentData { - match self - .providers - .read() - .await - .as_ref() - .unwrap() - .create_inherent_data_providers(parent, ()) - .await - { - Ok(providers) => match providers.create_inherent_data().await { - Ok(data) => Some(data), - Err(err) => { - warn!(target: "tendermint", "Failed to create inherent data: {}", err); - None - } - }, - Err(err) => { - warn!(target: "tendermint", "Failed to create inherent data providers: {}", err); - None - } - } - .unwrap_or_else(InherentData::new) - } - - async fn check_inherents( - &self, - hash: ::Hash, - block: T::Block, - ) -> Result<(), Error> { - let inherent_data = self.inherent_data(*block.header().parent_hash()).await; - let err = self - .client - .runtime_api() - .check_inherents(self.client.info().finalized_hash, block, inherent_data) - .map_err(|_| Error::Other(BlockError::Fatal.into()))?; - - if err.ok() { - self.recheck.write().unwrap().remove(&hash); - Ok(()) - } else if err.fatal_error() { - Err(Error::Other(BlockError::Fatal.into())) - } else { - debug!(target: "tendermint", "Proposed block has temporally wrong inherents"); - self.recheck.write().unwrap().insert(hash); - Err(Error::Other(BlockError::Temporal.into())) - } - } - - // Ensure this is part of a sequential import - pub(crate) fn verify_order( - &self, - parent: ::Hash, - number: <::Header as Header>::Number, - ) -> Result<(), Error> { - let info = self.client.info(); - if (info.finalized_hash != parent) || ((info.finalized_number + 1u16.into()) != number) { - Err(Error::Other("non-sequential import".into()))?; - } - Ok(()) - } - - // Do not allow blocks from the traditional network to be broadcast - // Only allow blocks from Tendermint - // Tendermint's propose message could be rewritten as a seal OR Tendermint could produce blocks - // which this checks the proposer slot for, and then tells the Tendermint machine - // While those would be more seamless with Substrate, there's no actual benefit to doing so - fn verify_origin(&self, hash: ::Hash) -> Result<(), Error> { - if let Some(tm_hash) = *self.importing_block.read().unwrap() { - if hash == tm_hash { - return Ok(()); - } - } - Err(Error::Other("block created outside of tendermint".into())) - } - - // Errors if the justification isn't valid - pub(crate) fn verify_justification( - &self, - hash: ::Hash, - justification: &Justification, - ) -> Result<(), Error> { - if justification.0 != CONSENSUS_ID { - Err(Error::InvalidJustification)?; - } - - let commit: Commit> = - Commit::decode(&mut justification.1.as_ref()).map_err(|_| Error::InvalidJustification)?; - // Create a stubbed TendermintAuthority so we can verify the commit - if !TendermintAuthority::stub(self.clone()).verify_commit(hash, &commit) { - Err(Error::InvalidJustification)?; - } - Ok(()) - } - - // Verifies the justifications aren't malformed, not that the block is justified - // Errors if justifications is neither empty nor a single Tendermint justification - // If the block does have a justification, finalized will be set to true - fn verify_justifications( - &self, - block: &mut BlockImportParams, - ) -> Result<(), Error> { - if !block.finalized { - if let Some(justifications) = &block.justifications { - let mut iter = justifications.iter(); - let next = iter.next(); - if next.is_none() || iter.next().is_some() { - Err(Error::InvalidJustification)?; - } - self.verify_justification(block.header.hash(), next.unwrap())?; - block.finalized = true; - } - } - Ok(()) - } - - pub(crate) async fn check( - &self, - block: &mut BlockImportParams, - ) -> Result<(), Error> { - if block.finalized { - if block.fork_choice != Some(ForkChoiceStrategy::Custom(false)) { - // Since we alw1ays set the fork choice, this means something else marked the block as - // finalized, which shouldn't be possible. Ensuring nothing else is setting blocks as - // finalized helps ensure our security - panic!("block was finalized despite not setting the fork choice"); - } - return Ok(()); - } - - // Set the block as a worse choice - block.fork_choice = Some(ForkChoiceStrategy::Custom(false)); - - self.verify_order(*block.header.parent_hash(), *block.header.number())?; - self.verify_justifications(block)?; - - // If the block wasn't finalized, verify the origin and validity of its inherents - if !block.finalized { - let hash = block.header.hash(); - self.verify_origin(hash)?; - self - .check_inherents(hash, T::Block::new(block.header.clone(), block.body.clone().unwrap())) - .await?; - } - - // Additionally check these fields are empty - // They *should* be unused, so requiring their emptiness prevents malleability and ensures - // nothing slips through - if !block.post_digests.is_empty() { - Err(Error::Other("post-digests included".into()))?; - } - if !block.auxiliary.is_empty() { - Err(Error::Other("auxiliary included".into()))?; - } - - Ok(()) - } -} diff --git a/substrate/tendermint/client/src/validators.rs b/substrate/tendermint/client/src/validators.rs deleted file mode 100644 index 9bd0b338..00000000 --- a/substrate/tendermint/client/src/validators.rs +++ /dev/null @@ -1,191 +0,0 @@ -use core::ops::Deref; -use std::sync::{Arc, RwLock}; - -use async_trait::async_trait; - -use sp_core::Decode; -use sp_application_crypto::{ - RuntimePublic as PublicTrait, - sr25519::{Public, Signature}, -}; -use sp_keystore::CryptoStore; - -use sp_staking::SessionIndex; -use sp_api::ProvideRuntimeApi; - -use sc_client_api::HeaderBackend; - -use tendermint_machine::ext::{BlockNumber, RoundNumber, Weights, Signer, SignatureScheme}; - -use sp_tendermint::TendermintApi; - -use crate::{KEY_TYPE_ID, TendermintClient}; - -struct TendermintValidatorsStruct { - session: SessionIndex, - - total_weight: u64, - weights: Vec, - - lookup: Vec, -} - -impl TendermintValidatorsStruct { - fn from_module(client: &Arc) -> Self { - let last = client.info().finalized_hash; - let api = client.runtime_api(); - let session = api.current_session(last).unwrap(); - let validators = api.validators(last).unwrap(); - - Self { - session, - - // TODO - total_weight: validators.len().try_into().unwrap(), - weights: vec![1; validators.len()], - - lookup: validators, - } - } -} - -// Wrap every access of the validators struct in something which forces calling refresh -struct Refresh { - client: Arc, - _refresh: Arc>, -} - -impl Refresh { - // If the session has changed, re-create the struct with the data on it - fn refresh(&self) { - let session = self._refresh.read().unwrap().session; - if session != - self.client.runtime_api().current_session(self.client.info().finalized_hash).unwrap() - { - *self._refresh.write().unwrap() = TendermintValidatorsStruct::from_module::(&self.client); - } - } -} - -impl Deref for Refresh { - type Target = RwLock; - fn deref(&self) -> &RwLock { - self.refresh(); - &self._refresh - } -} - -/// Tendermint validators observer, providing data on the active validators. -pub struct TendermintValidators(Refresh); -impl Clone for TendermintValidators { - fn clone(&self) -> Self { - Self(Refresh { _refresh: self.0._refresh.clone(), client: self.0.client.clone() }) - } -} - -impl TendermintValidators { - pub(crate) fn new(client: Arc) -> TendermintValidators { - TendermintValidators(Refresh { - _refresh: Arc::new(RwLock::new(TendermintValidatorsStruct::from_module::(&client))), - client, - }) - } -} - -pub struct TendermintSigner( - pub(crate) Arc, - pub(crate) TendermintValidators, -); - -impl Clone for TendermintSigner { - fn clone(&self) -> Self { - Self(self.0.clone(), self.1.clone()) - } -} - -impl TendermintSigner { - async fn get_public_key(&self) -> Public { - let pubs = self.0.sr25519_public_keys(KEY_TYPE_ID).await; - if pubs.is_empty() { - self.0.sr25519_generate_new(KEY_TYPE_ID, None).await.unwrap() - } else { - pubs[0] - } - } -} - -#[async_trait] -impl Signer for TendermintSigner { - type ValidatorId = u16; - type Signature = Signature; - - async fn validator_id(&self) -> Option { - let key = self.get_public_key().await; - for (i, k) in (*self.1 .0).read().unwrap().lookup.iter().enumerate() { - if k == &key { - return Some(u16::try_from(i).unwrap()); - } - } - None - } - - async fn sign(&self, msg: &[u8]) -> Signature { - Signature::decode( - &mut self - .0 - .sign_with(KEY_TYPE_ID, &self.get_public_key().await.into(), msg) - .await - .unwrap() - .unwrap() - .as_ref(), - ) - .unwrap() - } -} - -impl SignatureScheme for TendermintValidators { - type ValidatorId = u16; - type Signature = Signature; - type AggregateSignature = Vec; - type Signer = TendermintSigner; - - fn verify(&self, validator: u16, msg: &[u8], sig: &Signature) -> bool { - self.0.read().unwrap().lookup[usize::try_from(validator).unwrap()].verify(&msg, sig) - } - - fn aggregate(sigs: &[Signature]) -> Vec { - sigs.to_vec() - } - - fn verify_aggregate(&self, validators: &[u16], msg: &[u8], sigs: &Vec) -> bool { - if validators.len() != sigs.len() { - return false; - } - for (v, sig) in validators.iter().zip(sigs.iter()) { - if !self.verify(*v, msg, sig) { - return false; - } - } - true - } -} - -impl Weights for TendermintValidators { - type ValidatorId = u16; - - fn total_weight(&self) -> u64 { - self.0.read().unwrap().total_weight - } - - fn weight(&self, id: u16) -> u64 { - self.0.read().unwrap().weights[usize::try_from(id).unwrap()] - } - - // TODO: https://github.com/serai-dex/serai/issues/159 - fn proposer(&self, number: BlockNumber, round: RoundNumber) -> u16 { - u16::try_from( - (number.0 + u64::from(round.0)) % u64::try_from(self.0.read().unwrap().lookup.len()).unwrap(), - ) - .unwrap() - } -} diff --git a/substrate/tendermint/pallet/Cargo.toml b/substrate/tendermint/pallet/Cargo.toml deleted file mode 100644 index 4958dbec..00000000 --- a/substrate/tendermint/pallet/Cargo.toml +++ /dev/null @@ -1,38 +0,0 @@ -[package] -name = "pallet-tendermint" -version = "0.1.0" -description = "Tendermint pallet for Substrate" -license = "AGPL-3.0-only" -repository = "https://github.com/serai-dex/serai/tree/develop/substrate/tendermint/pallet" -authors = ["Luke Parker "] -edition = "2021" - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--cfg", "docsrs"] - -[dependencies] -parity-scale-codec = { version = "3", default-features = false, features = ["derive"] } -scale-info = { version = "2", default-features = false, features = ["derive"] } - -sp-core = { git = "https://github.com/serai-dex/substrate", default-features = false } -sp-std = { git = "https://github.com/serai-dex/substrate", default-features = false } -sp-application-crypto = { git = "https://github.com/serai-dex/substrate", default-features = false } - -frame-system = { git = "https://github.com/serai-dex/substrate", default-features = false } -frame-support = { git = "https://github.com/serai-dex/substrate", default-features = false } - -[features] -std = [ - "sp-application-crypto/std", - - "frame-system/std", - "frame-support/std", -] - -runtime-benchmarks = [ - "frame-system/runtime-benchmarks", - "frame-support/runtime-benchmarks", -] - -default = ["std"] diff --git a/substrate/tendermint/pallet/LICENSE b/substrate/tendermint/pallet/LICENSE deleted file mode 100644 index c425427c..00000000 --- a/substrate/tendermint/pallet/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -AGPL-3.0-only license - -Copyright (c) 2022-2023 Luke Parker - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License Version 3 as -published by the Free Software Foundation. - -This program 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 Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . diff --git a/substrate/tendermint/pallet/src/lib.rs b/substrate/tendermint/pallet/src/lib.rs deleted file mode 100644 index 54d86fe1..00000000 --- a/substrate/tendermint/pallet/src/lib.rs +++ /dev/null @@ -1,75 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std)] - -#[frame_support::pallet] -pub mod pallet { - use sp_std::vec::Vec; - use sp_core::sr25519::Public; - - use frame_support::pallet_prelude::*; - use frame_support::traits::{ConstU32, OneSessionHandler}; - - type MaxValidators = ConstU32<{ u16::MAX as u32 }>; - - #[pallet::config] - pub trait Config: frame_system::Config {} - - #[pallet::pallet] - #[pallet::generate_store(pub(super) trait Store)] - pub struct Pallet(PhantomData); - - #[pallet::storage] - #[pallet::getter(fn session)] - pub type Session = StorageValue<_, u32, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn validators)] - pub type Validators = StorageValue<_, BoundedVec, ValueQuery>; - - pub mod crypto { - use sp_application_crypto::{KeyTypeId, app_crypto, sr25519}; - app_crypto!(sr25519, KeyTypeId(*b"tend")); - - impl sp_application_crypto::BoundToRuntimeAppPublic for crate::Pallet { - type Public = Public; - } - - sp_application_crypto::with_pair! { - pub type AuthorityPair = Pair; - } - pub type AuthoritySignature = Signature; - pub type AuthorityId = Public; - } - - impl OneSessionHandler for Pallet { - type Key = crypto::Public; - - // TODO - fn on_genesis_session<'a, I: 'a>(_validators: I) - where - I: Iterator, - V: 'a, - { - } - - fn on_new_session<'a, I: 'a>(changed: bool, validators: I, _queued: I) - where - I: Iterator, - V: 'a, - { - if !changed { - return; - } - - Session::::put(Self::session() + 1); - Validators::::put( - BoundedVec::try_from(validators.map(|(_, key)| key.into()).collect::>()) - .unwrap(), - ); - } - - // TODO - fn on_disabled(_validator_index: u32) {} - } -} - -pub use pallet::*; diff --git a/substrate/tendermint/primitives/Cargo.toml b/substrate/tendermint/primitives/Cargo.toml deleted file mode 100644 index 6200add5..00000000 --- a/substrate/tendermint/primitives/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "sp-tendermint" -version = "0.1.0" -description = "Tendermint primitives for Substrate" -license = "AGPL-3.0-only" -repository = "https://github.com/serai-dex/serai/tree/develop/substrate/tendermint/primitives" -authors = ["Luke Parker "] -edition = "2021" - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--cfg", "docsrs"] - -[dependencies] -sp-core = { git = "https://github.com/serai-dex/substrate", default-features = false } -sp-std = { git = "https://github.com/serai-dex/substrate", default-features = false } -sp-api = { git = "https://github.com/serai-dex/substrate", default-features = false } - -[features] -std = ["sp-core/std", "sp-std/std", "sp-api/std"] -default = ["std"] diff --git a/substrate/tendermint/primitives/LICENSE b/substrate/tendermint/primitives/LICENSE deleted file mode 100644 index c425427c..00000000 --- a/substrate/tendermint/primitives/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -AGPL-3.0-only license - -Copyright (c) 2022-2023 Luke Parker - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License Version 3 as -published by the Free Software Foundation. - -This program 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 Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . diff --git a/substrate/tendermint/primitives/src/lib.rs b/substrate/tendermint/primitives/src/lib.rs deleted file mode 100644 index b5a1d6b2..00000000 --- a/substrate/tendermint/primitives/src/lib.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std)] - -use sp_core::sr25519::Public; -use sp_std::vec::Vec; - -sp_api::decl_runtime_apis! { - /// TendermintApi trait for runtimes to implement. - pub trait TendermintApi { - /// Current session number. A session is NOT a fixed length of blocks, yet rather a continuous - /// set of validators. - fn current_session() -> u32; - - /// Current validators. - fn validators() -> Vec; - } -} diff --git a/substrate/tokens/pallet/src/lib.rs b/substrate/tokens/pallet/src/lib.rs index 5d0a0845..a82ef1de 100644 --- a/substrate/tokens/pallet/src/lib.rs +++ b/substrate/tokens/pallet/src/lib.rs @@ -34,7 +34,6 @@ pub mod pallet { } #[pallet::pallet] - #[pallet::generate_store(pub(crate) trait Store)] pub struct Pallet(PhantomData); impl Pallet { diff --git a/substrate/validator-sets/pallet/src/lib.rs b/substrate/validator-sets/pallet/src/lib.rs index 9c6b0282..52307ccc 100644 --- a/substrate/validator-sets/pallet/src/lib.rs +++ b/substrate/validator-sets/pallet/src/lib.rs @@ -52,7 +52,6 @@ pub mod pallet { } #[pallet::pallet] - #[pallet::generate_store(pub(super) trait Store)] pub struct Pallet(PhantomData); /// The details of a validator set instance. diff --git a/substrate/tendermint/machine/Cargo.toml b/tendermint/Cargo.toml similarity index 86% rename from substrate/tendermint/machine/Cargo.toml rename to tendermint/Cargo.toml index 4ba9337d..95931c42 100644 --- a/substrate/tendermint/machine/Cargo.toml +++ b/tendermint/Cargo.toml @@ -3,7 +3,7 @@ name = "tendermint-machine" version = "0.2.0" description = "An implementation of the Tendermint state machine in Rust" license = "MIT" -repository = "https://github.com/serai-dex/serai/tree/develop/substrate/tendermint/machine" +repository = "https://github.com/serai-dex/serai/tree/develop/tendermint" authors = ["Luke Parker "] edition = "2021" diff --git a/substrate/tendermint/machine/LICENSE b/tendermint/LICENSE similarity index 100% rename from substrate/tendermint/machine/LICENSE rename to tendermint/LICENSE diff --git a/substrate/tendermint/machine/README.md b/tendermint/README.md similarity index 100% rename from substrate/tendermint/machine/README.md rename to tendermint/README.md diff --git a/substrate/tendermint/machine/src/block.rs b/tendermint/src/block.rs similarity index 100% rename from substrate/tendermint/machine/src/block.rs rename to tendermint/src/block.rs diff --git a/substrate/tendermint/machine/src/ext.rs b/tendermint/src/ext.rs similarity index 100% rename from substrate/tendermint/machine/src/ext.rs rename to tendermint/src/ext.rs diff --git a/substrate/tendermint/machine/src/lib.rs b/tendermint/src/lib.rs similarity index 100% rename from substrate/tendermint/machine/src/lib.rs rename to tendermint/src/lib.rs diff --git a/substrate/tendermint/machine/src/message_log.rs b/tendermint/src/message_log.rs similarity index 100% rename from substrate/tendermint/machine/src/message_log.rs rename to tendermint/src/message_log.rs diff --git a/substrate/tendermint/machine/src/round.rs b/tendermint/src/round.rs similarity index 100% rename from substrate/tendermint/machine/src/round.rs rename to tendermint/src/round.rs diff --git a/substrate/tendermint/machine/src/time.rs b/tendermint/src/time.rs similarity index 100% rename from substrate/tendermint/machine/src/time.rs rename to tendermint/src/time.rs diff --git a/substrate/tendermint/machine/tests/ext.rs b/tendermint/tests/ext.rs similarity index 100% rename from substrate/tendermint/machine/tests/ext.rs rename to tendermint/tests/ext.rs