diff --git a/.gitignore b/.gitignore index a96f7e8e44..b35886097b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,5 @@ expand.rs # Rust Things **/*.rs.bk **/target/ +.cargo-ok Cargo.toml.bak diff --git a/.travis.yml b/.travis.yml index d4ecba1a25..b5f5c86bea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,6 +31,10 @@ jobs: env: STAKING RUST_TOOLCHAIN=nightly script: .maintain/ci/tests.sh staking + - stage: Darwinia Test + env: ELECTIONSPHRAGMEN RUST_TOOLCHAIN=nightly + script: .maintain/ci/tests.sh elections-phragmen + - stage: Darwinia Test env: TREASURY RUST_TOOLCHAIN=nightly script: .maintain/ci/tests.sh treasury diff --git a/Cargo.lock b/Cargo.lock index ae35cd3008..9de5f88de2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,7 +37,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331" dependencies = [ - "generic-array 0.14.3", + "generic-array 0.14.4", ] [[package]] @@ -163,7 +163,7 @@ checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" name = "array-bytes" version = "0.6.4" dependencies = [ - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] @@ -212,47 +212,52 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7deb0a829ca7bcfaf5da70b073a8d128619259a7be8216a355e23f00763059e5" +[[package]] +name = "async-channel" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43de69555a39d52918e2bc33a408d3c0a86c829b212d898f4ca25d21a6387478" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + [[package]] name = "async-std" -version = "1.5.0" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "538ecb01eb64eecd772087e5b6f7540cbc917f047727339a472dafed2185b267" +checksum = "00d68a33ebc8b57800847d00787307f84a562224a14db069b0acefe4c2abbf5d" dependencies = [ "async-task", - "broadcaster", - "crossbeam-channel", - "crossbeam-deque", "crossbeam-utils", + "futures-channel", "futures-core", "futures-io", - "futures-timer 2.0.2", + "futures-timer 3.0.2", "kv-log-macro", "log", "memchr", - "mio", - "mio-uds", "num_cpus", "once_cell", "pin-project-lite", "pin-utils", "slab", + "smol", + "wasm-bindgen-futures", ] [[package]] name = "async-task" -version = "1.3.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ac2c016b079e771204030951c366db398864f5026f84a44dafb0ff20f02085d" -dependencies = [ - "libc", - "winapi 0.3.9", -] +checksum = "c17772156ef2829aadc587461c7753af20b7e8db1529bc66855add962a3b35d3" [[package]] name = "async-tls" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fd83426b89b034bf4e9ceb9c533c2f2386b813fd3dcae0a425ec6f1837d78a" +checksum = "df097e3f506bec0e1a24f06bb3c962c228f36671de841ff579cb99f371772634" dependencies = [ "futures 0.3.5", "rustls", @@ -260,6 +265,12 @@ dependencies = [ "webpki-roots 0.19.0", ] +[[package]] +name = "atomic-waker" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" + [[package]] name = "atty" version = "0.2.14" @@ -371,18 +382,6 @@ dependencies = [ "radium", ] -[[package]] -name = "blake2" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" -dependencies = [ - "byte-tools", - "crypto-mac 0.7.0", - "digest 0.8.1", - "opaque-debug 0.2.3", -] - [[package]] name = "blake2" version = "0.9.0" @@ -446,7 +445,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.3", + "generic-array 0.14.4", ] [[package]] @@ -455,7 +454,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa136449e765dc7faa244561ccae839c394048667929af599b5d931ebe7b7f10" dependencies = [ - "generic-array 0.14.3", + "generic-array 0.14.4", ] [[package]] @@ -468,17 +467,17 @@ dependencies = [ ] [[package]] -name = "broadcaster" -version = "1.0.0" +name = "blocking" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c972e21e0d055a36cf73e4daae870941fe7a8abcd5ac3396aab9e4c126bd87" +checksum = "d2468ff7bf85066b4a3678fede6fe66db31846d753ff0adfbfab2c6a6e81612b" dependencies = [ - "futures-channel", - "futures-core", - "futures-sink", - "futures-util", - "parking_lot 0.10.2", - "slab", + "async-channel", + "atomic-waker", + "futures-lite", + "once_cell", + "parking", + "waker-fn", ] [[package]] @@ -546,6 +545,12 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" +[[package]] +name = "cache-padded" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" + [[package]] name = "cast" version = "0.2.3" @@ -648,21 +653,21 @@ dependencies = [ ] [[package]] -name = "clear_on_drop" -version = "0.2.4" +name = "cloudabi" +version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9cc5db465b294c3fa986d5bbb0f3017cd850bff6dd6c52f9ccff8b4d21b7b08" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" dependencies = [ - "cc", + "bitflags", ] [[package]] -name = "cloudabi" -version = "0.0.3" +name = "concurrent-queue" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" dependencies = [ - "bitflags", + "cache-padded", ] [[package]] @@ -850,16 +855,6 @@ dependencies = [ "itertools 0.9.0", ] -[[package]] -name = "crossbeam-channel" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ee0cc8804d5393478d743b035099520087a5186f3b93fa58cec08fa62407b6" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - [[package]] name = "crossbeam-deque" version = "0.7.3" @@ -930,7 +925,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ - "generic-array 0.14.3", + "generic-array 0.14.4", "subtle 2.2.3", ] @@ -958,9 +953,9 @@ dependencies = [ [[package]] name = "ct-logs" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d3686f5fa27dbc1d76c751300376e167c5a43387f44bb451fd1c24776e49113" +checksum = "8c8e13110a84b6315df212c045be706af261fd364791cad863285439ebba672e" dependencies = [ "sct", ] @@ -992,7 +987,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] @@ -1036,7 +1031,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "tiny-keccak 1.5.0", ] @@ -1067,7 +1062,7 @@ dependencies = [ "sp-io", "sp-npos-elections", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "substrate-test-utils", ] @@ -1093,7 +1088,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-staking", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] @@ -1114,7 +1109,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] @@ -1134,7 +1129,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] @@ -1158,7 +1153,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] @@ -1177,7 +1172,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] @@ -1203,7 +1198,7 @@ dependencies = [ "serde", "sp-api", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] @@ -1220,7 +1215,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] @@ -1245,7 +1240,7 @@ dependencies = [ "sp-npos-elections", "sp-runtime", "sp-staking", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "sp-storage", "static_assertions 1.1.0", "substrate-test-utils", @@ -1286,7 +1281,7 @@ dependencies = [ "num-traits 0.2.12", "parity-scale-codec", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] @@ -1302,14 +1297,15 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", + "sp-storage", ] [[package]] name = "data-encoding" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72aa14c04dfae8dd7d8a2b1cb7ca2152618cd01336dbfe704b8dcbf8d41dbd69" +checksum = "d4d0e2d24e5ee3b23a01de38eefdcd978907890701f08ffffd4cb457ca4ee8d6" [[package]] name = "derive_more" @@ -1337,7 +1333,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.3", + "generic-array 0.14.4", ] [[package]] @@ -1377,16 +1373,27 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +[[package]] +name = "ed25519" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf038a7b6fd7ef78ad3348b63f3a17550877b0e28f8d68bcc94894d1412158bc" +dependencies = [ + "signature", +] + [[package]] name = "ed25519-dalek" -version = "1.0.0-pre.3" +version = "1.0.0-pre.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978710b352437433c97b2bff193f2fb1dfd58a093f863dd95e225a19baa599a2" +checksum = "21a8a37f4e8b35af971e6db5e3897e7a6344caa3f92f6544f88125a1f5f0035a" dependencies = [ - "clear_on_drop", "curve25519-dalek", + "ed25519", "rand 0.7.3", + "serde", "sha2 0.8.2", + "zeroize", ] [[package]] @@ -1530,7 +1537,7 @@ dependencies = [ "serde_json", "sp-io", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "triehash", ] @@ -1571,6 +1578,12 @@ dependencies = [ "serde", ] +[[package]] +name = "event-listener" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f14646a9e0430150a87951622ba9675472b68e384b7701b8423b30560805c7a" + [[package]] name = "exit-future" version = "0.2.0" @@ -1629,6 +1642,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "fastrand" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bd3bdaaf0a72155260a1c098989b60db1cbb22d6a628e64f16237aa4da93cc7" + [[package]] name = "fdlimit" version = "0.1.4" @@ -1726,16 +1745,16 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fork-tree" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "parity-scale-codec", ] [[package]] name = "frame-benchmarking" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-support", "frame-system", @@ -1746,13 +1765,13 @@ dependencies = [ "sp-io", "sp-runtime", "sp-runtime-interface", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "frame-executive" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-support", "frame-system", @@ -1760,25 +1779,25 @@ dependencies = [ "serde", "sp-io", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "sp-tracing", ] [[package]] name = "frame-metadata" -version = "11.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "11.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "parity-scale-codec", "serde", "sp-core", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "frame-support" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "bitmask", "frame-metadata", @@ -1796,14 +1815,14 @@ dependencies = [ "sp-io", "sp-runtime", "sp-state-machine", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "sp-tracing", ] [[package]] name = "frame-support-procedural" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-support-procedural-tools", "proc-macro2", @@ -1813,8 +1832,8 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", @@ -1825,8 +1844,8 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "proc-macro2", "quote 1.0.7", @@ -1835,8 +1854,8 @@ dependencies = [ [[package]] name = "frame-system" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -1845,14 +1864,14 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "sp-version", ] [[package]] name = "frame-system-rpc-runtime-api" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "parity-scale-codec", "sp-api", @@ -1988,6 +2007,21 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789" +[[package]] +name = "futures-lite" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe71459749b2e8e66fb95df721b22fa08661ad384a0c5b519e11d3893b4692a" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + [[package]] name = "futures-macro" version = "0.3.5" @@ -2026,6 +2060,10 @@ name = "futures-timer" version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +dependencies = [ + "gloo-timers", + "send_wrapper 0.4.0", +] [[package]] name = "futures-util" @@ -2060,18 +2098,6 @@ dependencies = [ "slab", ] -[[package]] -name = "futures_codec" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0a73299e4718f5452e45980fc1d6957a070abe308d3700b63b8673f47e1c2b3" -dependencies = [ - "bytes 0.5.6", - "futures 0.3.5", - "memchr", - "pin-project", -] - [[package]] name = "futures_codec" version = "0.4.1" @@ -2101,9 +2127,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60fb4bb6bba52f78a471264d9a3b7d026cc0af47b22cd2cffbc0b787ca003e63" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" dependencies = [ "typenum", "version_check", @@ -2190,6 +2216,19 @@ dependencies = [ "regex", ] +[[package]] +name = "gloo-timers" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "goblin" version = "0.1.3" @@ -2271,9 +2310,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34f595585f103464d8d2f6e9864682d74c1601fed5e07d62b1c9058dba8246fb" +checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25" dependencies = [ "ahash 0.3.8", "autocfg 1.0.0", @@ -2473,9 +2512,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac965ea399ec3a25ac7d13b8affd4b8f39325cca00858ddf5eb29b79e6b14b08" +checksum = "37743cc83e8ee85eacfce90f2f4102030d9ff0a95244098d781e9bee4a90abb6" dependencies = [ "bytes 0.5.6", "ct-logs", @@ -2584,12 +2623,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b88cd59ee5f71fea89a62248fc8f387d44400cefe05ef548466d61ced9029a7" +checksum = "86b45e59b16c76b11bf9738fd5d38879d3bd28ad292d7b313608becb17ae2df9" dependencies = [ "autocfg 1.0.0", - "hashbrown 0.8.1", + "hashbrown 0.8.2", ] [[package]] @@ -2840,9 +2879,9 @@ dependencies = [ [[package]] name = "kvdb" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e763b2a9b500ba47948061d1e8bc3b5f03a8a1f067dbcf822a4d2c84d2b54a3a" +checksum = "0315ef2f688e33844400b31f11c263f2b3dc21d8b9355c6891c5f185fae43f9a" dependencies = [ "parity-util-mem", "smallvec 1.4.1", @@ -2850,9 +2889,9 @@ dependencies = [ [[package]] name = "kvdb-memorydb" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73027d5e228de6f503b5b7335d530404fc26230a6ae3e09b33ec6e45408509a4" +checksum = "73de822b260a3bdfb889dbbb65bb2d473eee2253973d6fa4a5d149a2a4a7c66e" dependencies = [ "kvdb", "parity-util-mem", @@ -2861,9 +2900,9 @@ dependencies = [ [[package]] name = "kvdb-rocksdb" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84384eca250c7ff67877eda5336f28a86586aaee24acb945643590671f6bfce1" +checksum = "7c341ef15cfb1f923fa3b5138bfbd2d4813a2c1640b473727a53351c7f0b0fa2" dependencies = [ "fs-swap", "kvdb", @@ -2937,9 +2976,9 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libp2p" -version = "0.19.1" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057eba5432d3e740e313c6e13c9153d0cb76b4f71bfc2e5242ae5bdb7d41af67" +checksum = "0306a49ee6a89468f96089906f36b0eef82c988dcfc8acf3e2dcd6ad1c859f85" dependencies = [ "bytes 0.5.6", "futures 0.3.5", @@ -2959,7 +2998,7 @@ dependencies = [ "libp2p-websocket", "libp2p-yamux", "multihash", - "parity-multiaddr 0.9.1", + "parity-multiaddr", "parking_lot 0.10.2", "pin-project", "smallvec 1.4.1", @@ -2968,9 +3007,9 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.19.2" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a0387b930c3d4c2533dc4893c1e0394185ddcc019846121b1b27491e45a2c08" +checksum = "6a694fd76d7c33a45a0e6e1525e9b9b5d11127c9c94e560ac0f8abba54ed80af" dependencies = [ "asn1_der", "bs58", @@ -2984,7 +3023,7 @@ dependencies = [ "log", "multihash", "multistream-select", - "parity-multiaddr 0.9.1", + "parity-multiaddr", "parking_lot 0.10.2", "pin-project", "prost", @@ -3002,9 +3041,9 @@ dependencies = [ [[package]] name = "libp2p-core-derive" -version = "0.19.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09548626b737ed64080fde595e06ce1117795b8b9fc4d2629fa36561c583171" +checksum = "f753d9324cd3ec14bf04b8a8cd0d269c87f294153d6bf2a84497a63a5ad22213" dependencies = [ "quote 1.0.7", "syn 1.0.38", @@ -3012,9 +3051,9 @@ dependencies = [ [[package]] name = "libp2p-dns" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cc186d9a941fd0207cf8f08ef225a735e2d7296258f570155e525f6ee732f87" +checksum = "f751924b6b98e350005e0b87a822beb246792a3fb878c684e088f866158120ac" dependencies = [ "futures 0.3.5", "libp2p-core", @@ -3023,9 +3062,9 @@ dependencies = [ [[package]] name = "libp2p-identify" -version = "0.19.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f76075b170d908bae616f550ade410d9d27c013fa69042551dbfc757c7c094" +checksum = "912c00a7bf67e0e765daf0cc37e08f675ea26aba3d6d1fbfaee81f19a4c23049" dependencies = [ "futures 0.3.5", "libp2p-core", @@ -3039,16 +3078,16 @@ dependencies = [ [[package]] name = "libp2p-kad" -version = "0.19.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d6c1d5100973527ae70d82687465b17049c1b717a7964de38b8e65000878ff" +checksum = "44ed3a4c8111c570ab2bffb30c6353178d7603ce3787e3c5f2493c8d3d16d1f0" dependencies = [ "arrayvec 0.5.1", "bytes 0.5.6", "either", "fnv", "futures 0.3.5", - "futures_codec 0.3.4", + "futures_codec", "libp2p-core", "libp2p-swarm", "log", @@ -3059,16 +3098,16 @@ dependencies = [ "sha2 0.8.2", "smallvec 1.4.1", "uint 0.8.4", - "unsigned-varint 0.3.3", + "unsigned-varint 0.4.0", "void", "wasm-timer", ] [[package]] name = "libp2p-mdns" -version = "0.19.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f55b2d4b80986e5bf158270ab23268ec0e7f644ece5436fbaabc5155472f357" +checksum = "cd004c668160fd922f7268b2cd1e4550ff69165d9c744e9eb5770086eb753d02" dependencies = [ "async-std", "data-encoding", @@ -3088,14 +3127,14 @@ dependencies = [ [[package]] name = "libp2p-mplex" -version = "0.19.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be7d913a4cd57de2013257ec73f07d77bfce390b370023e2d59083e5ca079864" +checksum = "14ae0ffacd30f073f96cd518b2c9cd2cb18ac27c3d136a4b23cf1af99f33e541" dependencies = [ "bytes 0.5.6", "fnv", "futures 0.3.5", - "futures_codec 0.4.1", + "futures_codec", "libp2p-core", "log", "parking_lot 0.10.2", @@ -3104,10 +3143,11 @@ dependencies = [ [[package]] name = "libp2p-noise" -version = "0.19.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a03db664653369f46ee03fcec483a378c20195089bb43a26cb9fb0058009ac88" +checksum = "8f353f8966bbaaf7456535fffd3f366f153148773a0cf04b2ec3860955cb720e" dependencies = [ + "bytes 0.5.6", "curve25519-dalek", "futures 0.3.5", "lazy_static", @@ -3125,9 +3165,9 @@ dependencies = [ [[package]] name = "libp2p-ping" -version = "0.19.3" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8dedd34e35a9728d52d59ef36a218e411359a353f9011b2574b86ee790978f6" +checksum = "70130cf130e4ba6dc177366e72dd9f86f9e3588fa1a0c4145247e676f16affad" dependencies = [ "futures 0.3.5", "libp2p-core", @@ -3140,9 +3180,9 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.19.1" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce53ff4d127cf8b39adf84dbd381ca32d49bd85788cee08e6669da2495993930" +checksum = "f88d5e2a090a2aadf042cd33484e2f015c6dab212567406a59deece5dedbd133" dependencies = [ "futures 0.3.5", "libp2p-core", @@ -3155,9 +3195,9 @@ dependencies = [ [[package]] name = "libp2p-tcp" -version = "0.19.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481500c5774c62e8c413e9535b3f33a0e3dbacf2da63b8d3056c686a9df4146" +checksum = "9b1fa2bbad054020cb875546a577a66a65a5bf42eff55ed5265f92ffee3cc052" dependencies = [ "async-std", "futures 0.3.5", @@ -3171,9 +3211,9 @@ dependencies = [ [[package]] name = "libp2p-wasm-ext" -version = "0.19.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f59fdbb5706f2723ca108c088b1c7a37f735a8c328021f0508007162627e9885" +checksum = "0feb99e32fea20ffb1bbf56a6fb2614bff7325ff44a515728385170b3420d2c3" dependencies = [ "futures 0.3.5", "js-sys", @@ -3185,12 +3225,11 @@ dependencies = [ [[package]] name = "libp2p-websocket" -version = "0.19.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "085fbe4c05c4116c2164ab4d5a521eb6e00516c444f61b3ee9f68c7b1e53580b" +checksum = "046a5201f6e471f22b22b394e4d084269ed1e28cf7300f7b49874385db84c7bd" dependencies = [ "async-tls", - "bytes 0.5.6", "either", "futures 0.3.5", "libp2p-core", @@ -3206,9 +3245,9 @@ dependencies = [ [[package]] name = "libp2p-yamux" -version = "0.19.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da33e7b5f49c75c6a8afb0b8d1e229f5fa48be9f39bd14cdbc21459a02ac6fc" +checksum = "46ae9bf2f7d8a4be9c7e9b61df9de9dc1bd66419d669098f22f81f8d9571029a" dependencies = [ "futures 0.3.5", "libp2p-core", @@ -3367,13 +3406,12 @@ dependencies = [ [[package]] name = "memory-db" -version = "0.21.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb2999ff7a65d5a1d72172f6d51fa2ea03024b51aee709ba5ff81c3c629a2410" +checksum = "36f36ddb0b2cdc25d38babba472108798e3477f02be5165f038c5e393e50c57a" dependencies = [ - "ahash 0.2.18", "hash-db", - "hashbrown 0.6.3", + "hashbrown 0.8.2", "parity-util-mem", ] @@ -3389,12 +3427,12 @@ version = "0.6.4" dependencies = [ "criterion", "ethereum-types 0.5.2", - "hashbrown 0.8.1", + "hashbrown 0.8.2", "hex", "keccak-hash", "rand 0.7.3", "rlp 0.4.4", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "uuid", ] @@ -3605,19 +3643,24 @@ name = "node-template" version = "0.6.4" dependencies = [ "darwinia-balances-rpc", + "darwinia-balances-rpc-runtime-api", "darwinia-claims", "darwinia-cli", "darwinia-ethereum-linear-relay", "darwinia-ethereum-relay", "darwinia-header-mmr-rpc", + "darwinia-header-mmr-rpc-runtime-api", "darwinia-staking", "darwinia-staking-rpc", + "darwinia-staking-rpc-runtime-api", + "frame-system-rpc-runtime-api", "futures 0.3.5", "jsonrpc-core", "log", "node-template-runtime", "pallet-im-online", "pallet-transaction-payment-rpc", + "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", "sc-basic-authorship", "sc-cli", @@ -3644,11 +3687,15 @@ dependencies = [ "sp-core", "sp-finality-grandpa", "sp-inherents", + "sp-offchain", "sp-runtime", + "sp-session", "sp-transaction-pool", + "sp-trie", "structopt", "substrate-build-script-utils", "substrate-frame-rpc-system", + "substrate-prometheus-endpoint", "tokio 0.2.22", ] @@ -3706,7 +3753,7 @@ dependencies = [ "sp-runtime", "sp-session", "sp-staking", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "sp-transaction-pool", "sp-version", "static_assertions 1.1.0", @@ -3875,8 +3922,8 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-support", "frame-system", @@ -3886,13 +3933,13 @@ dependencies = [ "sp-application-crypto", "sp-authority-discovery", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "pallet-authorship" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-support", "frame-system", @@ -3901,16 +3948,18 @@ dependencies = [ "sp-authorship", "sp-inherents", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "pallet-babe" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", + "pallet-authorship", "pallet-session", "pallet-timestamp", "parity-scale-codec", @@ -3921,15 +3970,16 @@ dependencies = [ "sp-inherents", "sp-io", "sp-runtime", + "sp-session", "sp-staking", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "sp-timestamp", ] [[package]] name = "pallet-balances" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-benchmarking", "frame-support", @@ -3937,13 +3987,13 @@ dependencies = [ "parity-scale-codec", "serde", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "pallet-collective" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-support", "frame-system", @@ -3952,13 +4002,13 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "pallet-finality-tracker" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-support", "frame-system", @@ -3968,16 +4018,18 @@ dependencies = [ "sp-finality-tracker", "sp-inherents", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "pallet-grandpa" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", + "pallet-authorship", "pallet-finality-tracker", "pallet-session", "parity-scale-codec", @@ -3988,13 +4040,13 @@ dependencies = [ "sp-runtime", "sp-session", "sp-staking", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "pallet-im-online" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-support", "frame-system", @@ -4007,13 +4059,13 @@ dependencies = [ "sp-io", "sp-runtime", "sp-staking", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "pallet-membership" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-support", "frame-system", @@ -4021,13 +4073,13 @@ dependencies = [ "serde", "sp-io", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "pallet-offences" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-support", "frame-system", @@ -4036,26 +4088,26 @@ dependencies = [ "serde", "sp-runtime", "sp-staking", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "pallet-randomness-collective-flip" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-support", "frame-system", "parity-scale-codec", "safe-mix", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "pallet-session" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-support", "frame-system", @@ -4068,14 +4120,14 @@ dependencies = [ "sp-runtime", "sp-session", "sp-staking", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "sp-trie", ] [[package]] name = "pallet-sudo" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-support", "frame-system", @@ -4083,13 +4135,13 @@ dependencies = [ "serde", "sp-io", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "pallet-timestamp" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-benchmarking", "frame-support", @@ -4099,14 +4151,14 @@ dependencies = [ "serde", "sp-inherents", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "sp-timestamp", ] [[package]] name = "pallet-transaction-payment" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-support", "frame-system", @@ -4114,14 +4166,16 @@ dependencies = [ "parity-scale-codec", "serde", "smallvec 1.4.1", + "sp-core", + "sp-io", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "pallet-transaction-payment-rpc" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -4138,15 +4192,15 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-support", "parity-scale-codec", "serde", "sp-api", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] @@ -4163,24 +4217,6 @@ dependencies = [ "parking_lot 0.10.2", ] -[[package]] -name = "parity-multiaddr" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f77055f9e81921a8cc7bebeb6cded3d128931d51f1e3dd6251f0770a6d431477" -dependencies = [ - "arrayref", - "bs58", - "byteorder", - "data-encoding", - "parity-multihash", - "percent-encoding 2.1.0", - "serde", - "static_assertions 1.1.0", - "unsigned-varint 0.3.3", - "url 2.1.1", -] - [[package]] name = "parity-multiaddr" version = "0.9.1" @@ -4199,21 +4235,6 @@ dependencies = [ "url 2.1.1", ] -[[package]] -name = "parity-multihash" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a1cd2ba02391b81367bec529fb209019d718684fdc8ad6a712c2b536e46f775" -dependencies = [ - "blake2 0.8.1", - "bytes 0.5.6", - "rand 0.7.3", - "sha-1", - "sha2 0.8.2", - "sha3", - "unsigned-varint 0.3.3", -] - [[package]] name = "parity-scale-codec" version = "1.3.4" @@ -4266,11 +4287,12 @@ dependencies = [ [[package]] name = "parity-util-mem" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6e2583649a3ca84894d1d71da249abcfda54d5aca24733d72ca10d0f02361c" +checksum = "297ff91fa36aec49ce183484b102f6b75b46776822bd81525bfc4cc9b0dd0f5c" dependencies = [ "cfg-if", + "hashbrown 0.8.2", "impl-trait-for-tuples", "parity-util-mem-derive", "parking_lot 0.10.2", @@ -4296,6 +4318,12 @@ version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" +[[package]] +name = "parking" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb300f271742d4a2a66c01b6b2fa0c83dfebd2e0bf11addb879a3547b4ed87c" + [[package]] name = "parking_lot" version = "0.9.0" @@ -5059,6 +5087,12 @@ dependencies = [ "syn 1.0.38", ] +[[package]] +name = "retain_mut" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e005d658ad26eacc2b6c506dfde519f4e277e328d0eb3379ca61647d70a8f531" + [[package]] name = "ring" version = "0.16.15" @@ -5168,11 +5202,11 @@ dependencies = [ [[package]] name = "rustls" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1" +checksum = "cac94b333ee2aac3284c5b8a1b7fb4dd11cba88c244e3fe33cdbd047af0eb693" dependencies = [ - "base64 0.11.0", + "base64 0.12.3", "log", "ring", "sct", @@ -5181,9 +5215,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75ffeb84a6bd9d014713119542ce415db3a3e4748f0bfce1e1416cd224a23a5" +checksum = "629d439a7672da82dd955498445e496ee2096fe2117b9f796558a43fdb9e59b8" dependencies = [ "openssl-probe", "rustls", @@ -5228,8 +5262,8 @@ dependencies = [ [[package]] name = "sc-basic-authorship" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "futures 0.3.5", "futures-timer 3.0.2", @@ -5252,8 +5286,8 @@ dependencies = [ [[package]] name = "sc-block-builder" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -5262,14 +5296,15 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-core", + "sp-inherents", "sp-runtime", "sp-state-machine", ] [[package]] name = "sc-chain-spec" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "impl-trait-for-tuples", "sc-chain-spec-derive", @@ -5284,8 +5319,8 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -5295,8 +5330,8 @@ dependencies = [ [[package]] name = "sc-cli" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "ansi_term 0.12.1", "atty", @@ -5318,6 +5353,7 @@ dependencies = [ "sc-service", "sc-telemetry", "sc-tracing", + "serde", "serde_json", "sp-blockchain", "sp-core", @@ -5335,8 +5371,8 @@ dependencies = [ [[package]] name = "sc-client-api" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "derive_more", "fnv", @@ -5360,7 +5396,7 @@ dependencies = [ "sp-keyring", "sp-runtime", "sp-state-machine", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "sp-storage", "sp-transaction-pool", "sp-trie", @@ -5371,8 +5407,8 @@ dependencies = [ [[package]] name = "sc-client-db" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "blake2-rfc", "hash-db", @@ -5400,8 +5436,8 @@ dependencies = [ [[package]] name = "sc-consensus" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "sc-client-api", "sp-blockchain", @@ -5411,8 +5447,8 @@ dependencies = [ [[package]] name = "sc-consensus-babe" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "derive_more", "fork-tree", @@ -5453,8 +5489,8 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "derive_more", "futures 0.3.5", @@ -5477,8 +5513,8 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "fork-tree", "parity-scale-codec", @@ -5490,8 +5526,8 @@ dependencies = [ [[package]] name = "sc-consensus-slots" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "futures 0.3.5", "futures-timer 3.0.2", @@ -5504,6 +5540,7 @@ dependencies = [ "sp-application-crypto", "sp-blockchain", "sp-consensus", + "sp-consensus-slots", "sp-core", "sp-inherents", "sp-runtime", @@ -5512,8 +5549,8 @@ dependencies = [ [[package]] name = "sc-consensus-uncles" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "log", "sc-client-api", @@ -5526,8 +5563,8 @@ dependencies = [ [[package]] name = "sc-executor" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "derive_more", "lazy_static", @@ -5554,8 +5591,8 @@ dependencies = [ [[package]] name = "sc-executor-common" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "derive_more", "log", @@ -5571,8 +5608,8 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "log", "parity-scale-codec", @@ -5586,8 +5623,8 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "cranelift-codegen", "cranelift-wasm", @@ -5607,8 +5644,8 @@ dependencies = [ [[package]] name = "sc-finality-grandpa" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "assert_matches", "derive_more", @@ -5645,8 +5682,8 @@ dependencies = [ [[package]] name = "sc-finality-grandpa-rpc" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "derive_more", "finality-grandpa", @@ -5662,14 +5699,13 @@ dependencies = [ [[package]] name = "sc-informant" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "ansi_term 0.12.1", "futures 0.3.5", "log", "parity-util-mem", - "parking_lot 0.10.2", "sc-client-api", "sc-network", "sp-blockchain", @@ -5681,8 +5717,8 @@ dependencies = [ [[package]] name = "sc-keystore" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "derive_more", "hex", @@ -5697,8 +5733,8 @@ dependencies = [ [[package]] name = "sc-light" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "hash-db", "lazy_static", @@ -5716,8 +5752,8 @@ dependencies = [ [[package]] name = "sc-network" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "bitflags", "bs58", @@ -5729,7 +5765,7 @@ dependencies = [ "fork-tree", "futures 0.3.5", "futures-timer 3.0.2", - "futures_codec 0.3.4", + "futures_codec", "hex", "ip_network", "libp2p", @@ -5760,7 +5796,7 @@ dependencies = [ "sp-utils", "substrate-prometheus-endpoint", "thiserror", - "unsigned-varint 0.3.3", + "unsigned-varint 0.4.0", "void", "wasm-timer", "zeroize", @@ -5768,8 +5804,8 @@ dependencies = [ [[package]] name = "sc-network-gossip" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "futures 0.3.5", "futures-timer 3.0.2", @@ -5783,8 +5819,8 @@ dependencies = [ [[package]] name = "sc-offchain" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "bytes 0.5.6", "fnv", @@ -5810,8 +5846,8 @@ dependencies = [ [[package]] name = "sc-peerset" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "futures 0.3.5", "libp2p", @@ -5823,8 +5859,8 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -5832,8 +5868,8 @@ dependencies = [ [[package]] name = "sc-rpc" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "futures 0.3.5", "hash-db", @@ -5864,8 +5900,8 @@ dependencies = [ [[package]] name = "sc-rpc-api" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "derive_more", "futures 0.3.5", @@ -5888,8 +5924,8 @@ dependencies = [ [[package]] name = "sc-rpc-server" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "jsonrpc-core", "jsonrpc-http-server", @@ -5904,8 +5940,8 @@ dependencies = [ [[package]] name = "sc-service" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "derive_more", "directories", @@ -5918,7 +5954,6 @@ dependencies = [ "lazy_static", "log", "netstat2", - "parity-multiaddr 0.7.3", "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.2", @@ -5967,8 +6002,8 @@ dependencies = [ [[package]] name = "sc-state-db" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "log", "parity-scale-codec", @@ -5981,10 +6016,9 @@ dependencies = [ [[package]] name = "sc-telemetry" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ - "bytes 0.5.6", "futures 0.3.5", "futures-timer 3.0.2", "libp2p", @@ -6003,8 +6037,8 @@ dependencies = [ [[package]] name = "sc-tracing" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "erased-serde", "log", @@ -6020,8 +6054,8 @@ dependencies = [ [[package]] name = "sc-transaction-graph" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "derive_more", "futures 0.3.5", @@ -6029,6 +6063,7 @@ dependencies = [ "log", "parity-util-mem", "parking_lot 0.10.2", + "retain_mut", "serde", "sp-blockchain", "sp-core", @@ -6040,8 +6075,8 @@ dependencies = [ [[package]] name = "sc-transaction-pool" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "derive_more", "futures 0.3.5", @@ -6134,11 +6169,20 @@ dependencies = [ "untrusted", ] +[[package]] +name = "secrecy" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9182278ed645df3477a9c27bfee0621c621aa16f6972635f7f795dae3d81070f" +dependencies = [ + "zeroize", +] + [[package]] name = "security-framework" -version = "0.4.4" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535" +checksum = "ad502866817f0575705bd7be36e2b2535cc33262d493aa733a2ec862baa2bc2b" dependencies = [ "bitflags", "core-foundation", @@ -6149,9 +6193,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "0.4.3" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405" +checksum = "51ceb04988b17b6d1dcd555390fa822ca5637b4a14e1f5099f13d351bed4d6c7" dependencies = [ "core-foundation-sys", "libc", @@ -6178,6 +6222,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0eddf2e8f50ced781f288c19f18621fa72a3779e3cb58dbf23b07469b0abeb4" +[[package]] +name = "send_wrapper" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" + [[package]] name = "serde" version = "1.0.114" @@ -6231,12 +6281,6 @@ dependencies = [ "opaque-debug 0.2.3", ] -[[package]] -name = "sha1" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" - [[package]] name = "sha2" version = "0.8.2" @@ -6291,6 +6335,12 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29f060a7d147e33490ec10da418795238fd7545bba241504d6b31a409f2e6210" + [[package]] name = "slab" version = "0.4.2" @@ -6356,6 +6406,27 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3757cb9d89161a2f24e1cf78efa0c1fcff485d18e3f55e0aa3480824ddaa0f3f" +[[package]] +name = "smol" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "620cbb3c6e34da57d3a248cda0cd01cd5848164dc062e764e65d06fe3ea7aed5" +dependencies = [ + "async-task", + "blocking", + "concurrent-queue", + "fastrand", + "futures-io", + "futures-util", + "libc", + "once_cell", + "scoped-tls", + "slab", + "socket2", + "wepoll-sys-stjepang", + "winapi 0.3.9", +] + [[package]] name = "snow" version = "0.7.1" @@ -6363,7 +6434,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32bf8474159a95551661246cda4976e89356999e3cbfef36f493dacc3fae1e8e" dependencies = [ "aes-gcm", - "blake2 0.9.0", + "blake2", "chacha20poly1305", "rand 0.7.3", "rand_core 0.5.1", @@ -6388,40 +6459,36 @@ dependencies = [ [[package]] name = "soketto" -version = "0.3.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c9dab3f95c9ebdf3a88268c19af668f637a3c5039c2c56ff2d40b1b2d64a25b" +checksum = "85457366ae0c6ce56bf05a958aef14cd38513c236568618edbcd9a8c52cb80b0" dependencies = [ - "base64 0.11.0", + "base64 0.12.3", "bytes 0.5.6", "flate2", "futures 0.3.5", - "http 0.2.1", "httparse", "log", "rand 0.7.3", - "sha1", - "smallvec 1.4.1", - "static_assertions 1.1.0", - "thiserror", + "sha-1", ] [[package]] name = "sp-allocator" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "derive_more", "log", "sp-core", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "sp-wasm-interface", ] [[package]] name = "sp-api" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "hash-db", "parity-scale-codec", @@ -6429,14 +6496,14 @@ dependencies = [ "sp-core", "sp-runtime", "sp-state-machine", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "sp-version", ] [[package]] name = "sp-api-proc-macro" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "blake2-rfc", "proc-macro-crate", @@ -6447,68 +6514,68 @@ dependencies = [ [[package]] name = "sp-application-crypto" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "parity-scale-codec", "serde", "sp-core", "sp-io", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "sp-arithmetic" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "integer-sqrt", "num-traits 0.2.12", "parity-scale-codec", "serde", "sp-debug-derive", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "sp-authority-discovery" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "parity-scale-codec", "sp-api", "sp-application-crypto", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "sp-authorship" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "parity-scale-codec", "sp-inherents", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "sp-block-builder" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "parity-scale-codec", "sp-api", "sp-inherents", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "sp-blockchain" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "derive_more", "log", @@ -6517,14 +6584,15 @@ dependencies = [ "parking_lot 0.10.2", "sp-block-builder", "sp-consensus", + "sp-database", "sp-runtime", "sp-state-machine", ] [[package]] name = "sp-chain-spec" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "serde", "serde_json", @@ -6532,8 +6600,8 @@ dependencies = [ [[package]] name = "sp-consensus" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "derive_more", "futures 0.3.5", @@ -6547,7 +6615,8 @@ dependencies = [ "sp-inherents", "sp-runtime", "sp-state-machine", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", + "sp-trie", "sp-utils", "sp-version", "substrate-prometheus-endpoint", @@ -6556,38 +6625,48 @@ dependencies = [ [[package]] name = "sp-consensus-babe" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "merlin", "parity-scale-codec", "sp-api", "sp-application-crypto", "sp-consensus", + "sp-consensus-slots", "sp-consensus-vrf", "sp-core", "sp-inherents", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "sp-timestamp", ] +[[package]] +name = "sp-consensus-slots" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" +dependencies = [ + "parity-scale-codec", + "sp-runtime", +] + [[package]] name = "sp-consensus-vrf" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "parity-scale-codec", "schnorrkel", "sp-core", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "sp-core" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "base58", "blake2-rfc", @@ -6611,12 +6690,13 @@ dependencies = [ "rand 0.7.3", "regex", "schnorrkel", + "secrecy", "serde", "sha2 0.8.2", "sp-debug-derive", "sp-externalities", "sp-runtime-interface", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "sp-storage", "substrate-bip39", "tiny-bip39", @@ -6628,8 +6708,8 @@ dependencies = [ [[package]] name = "sp-database" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "kvdb", "parking_lot 0.10.2", @@ -6637,8 +6717,8 @@ dependencies = [ [[package]] name = "sp-debug-derive" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "proc-macro2", "quote 1.0.7", @@ -6647,19 +6727,19 @@ dependencies = [ [[package]] name = "sp-externalities" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "environmental", "parity-scale-codec", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "sp-storage", ] [[package]] name = "sp-finality-grandpa" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "finality-grandpa", "log", @@ -6669,35 +6749,35 @@ dependencies = [ "sp-application-crypto", "sp-core", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "sp-finality-tracker" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "parity-scale-codec", "sp-inherents", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "sp-inherents" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "derive_more", "parity-scale-codec", "parking_lot 0.10.2", "sp-core", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "sp-io" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "futures 0.3.5", "hash-db", @@ -6709,7 +6789,7 @@ dependencies = [ "sp-externalities", "sp-runtime-interface", "sp-state-machine", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "sp-tracing", "sp-trie", "sp-wasm-interface", @@ -6717,8 +6797,8 @@ dependencies = [ [[package]] name = "sp-keyring" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "lazy_static", "sp-core", @@ -6728,20 +6808,20 @@ dependencies = [ [[package]] name = "sp-npos-elections" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "parity-scale-codec", "serde", "sp-arithmetic", "sp-npos-elections-compact", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "sp-npos-elections-compact" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -6751,8 +6831,8 @@ dependencies = [ [[package]] name = "sp-offchain" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "sp-api", "sp-core", @@ -6761,8 +6841,8 @@ dependencies = [ [[package]] name = "sp-panic-handler" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "backtrace", "log", @@ -6770,8 +6850,8 @@ dependencies = [ [[package]] name = "sp-rpc" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "serde", "sp-core", @@ -6779,8 +6859,8 @@ dependencies = [ [[package]] name = "sp-runtime" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "either", "hash256-std-hasher", @@ -6796,19 +6876,19 @@ dependencies = [ "sp-core", "sp-inherents", "sp-io", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "sp-runtime-interface" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "parity-scale-codec", "primitive-types 0.7.2", "sp-externalities", "sp-runtime-interface-proc-macro", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "sp-tracing", "sp-wasm-interface", "static_assertions 1.1.0", @@ -6816,8 +6896,8 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "Inflector", "proc-macro-crate", @@ -6828,8 +6908,8 @@ dependencies = [ [[package]] name = "sp-serializer" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "serde", "serde_json", @@ -6837,31 +6917,31 @@ dependencies = [ [[package]] name = "sp-session" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "parity-scale-codec", "sp-api", "sp-core", "sp-runtime", "sp-staking", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "sp-staking" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "parity-scale-codec", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "sp-state-machine" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "hash-db", "itertools 0.9.0", @@ -6886,39 +6966,39 @@ source = "git+https://github.com/darwinia-network/substrate.git?branch=darwinia- [[package]] name = "sp-std" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" [[package]] name = "sp-storage" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "impl-serde 0.2.3", "ref-cast", "serde", "sp-debug-derive", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "sp-timestamp" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "sp-api", "sp-inherents", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "wasm-timer", ] [[package]] name = "sp-tracing" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "log", "rental", @@ -6927,8 +7007,8 @@ dependencies = [ [[package]] name = "sp-transaction-pool" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "derive_more", "futures 0.3.5", @@ -6938,27 +7018,26 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-runtime", - "sp-utils", ] [[package]] name = "sp-trie" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "hash-db", "memory-db", "parity-scale-codec", "sp-core", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "trie-db", "trie-root", ] [[package]] name = "sp-utils" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "futures 0.3.5", "futures-core", @@ -6969,24 +7048,24 @@ dependencies = [ [[package]] name = "sp-version" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "impl-serde 0.2.3", "parity-scale-codec", "serde", "sp-runtime", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", ] [[package]] name = "sp-wasm-interface" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", - "sp-std 2.0.0-rc4", + "sp-std 2.0.0-rc5", "wasmi", ] @@ -7029,7 +7108,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09f8ed9974042b8c3672ff3030a69fcc03b74c47c3d1ecb7755e8a3626011e88" dependencies = [ - "generic-array 0.14.3", + "generic-array 0.14.4", ] [[package]] @@ -7115,16 +7194,16 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "platforms", ] [[package]] name = "substrate-frame-rpc-system" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "frame-system-rpc-runtime-api", "futures 0.3.5", @@ -7146,8 +7225,8 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" -version = "0.8.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "0.8.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" dependencies = [ "async-std", "derive_more", @@ -7160,13 +7239,13 @@ dependencies = [ [[package]] name = "substrate-test-utils" -version = "2.0.0-rc4" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +version = "2.0.0-rc5" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" [[package]] name = "substrate-wasm-builder-runner" version = "1.0.6" -source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.3#93a6a53061b9ecb8660c291ab43d083cf51c1f89" +source = "git+https://github.com/darwinia-network/substrate.git?tag=v2.0.0-rc.darwinia.4#065b0f321f223b4cb3b22cee0e71fa6930034e2a" [[package]] name = "substrate-wasmtime" @@ -7314,9 +7393,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.13.4" +version = "0.14.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac193374347e7c263c5f547524f36ff8ec6702d56c8799c8331d26dffe8c1e" +checksum = "2983daff11a197c7c406b130579bc362177aa54cf2cc1f34d6ac88fccaa6a5e1" dependencies = [ "cfg-if", "doc-comment", @@ -7624,9 +7703,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15cb62a0d2770787abc96e99c1cd98fcf17f94959f3af63ca85bdfb203f051b4" +checksum = "228139ddd4fea3fa345a29233009635235833e52807af7ea6448ead03890d6a9" dependencies = [ "futures-core", "rustls", @@ -7803,12 +7882,12 @@ dependencies = [ [[package]] name = "trie-db" -version = "0.21.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb230c24c741993b04cfccbabb45acff6f6480c5f00d3ed8794ea43db3a9d727" +checksum = "9e55f7ace33d6237e14137e386f4e1672e2a5c6bbc97fef9f438581a143971f0" dependencies = [ "hash-db", - "hashbrown 0.6.3", + "hashbrown 0.8.2", "log", "rustc-hex", "smallvec 1.4.1", @@ -7945,7 +8024,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402" dependencies = [ - "generic-array 0.14.3", + "generic-array 0.14.4", "subtle 2.2.3", ] @@ -7954,12 +8033,6 @@ name = "unsigned-varint" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f67332660eb59a6f1eb24ff1220c9e8d01738a8503c6002e30bcfe4bd9f2b4a9" -dependencies = [ - "bytes 0.5.6", - "futures-io", - "futures-util", - "futures_codec 0.3.4", -] [[package]] name = "unsigned-varint" @@ -7968,7 +8041,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "669d776983b692a906c881fcd0cfb34271a48e197e4d6cb8df32b05bfc3d3fa5" dependencies = [ "bytes 0.5.6", - "futures_codec 0.4.1", + "futures-io", + "futures-util", + "futures_codec", ] [[package]] @@ -8033,6 +8108,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +[[package]] +name = "waker-fn" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9571542c2ce85ce642e6b58b3364da2fb53526360dfb7c211add4f5c23105ff7" + [[package]] name = "walkdir" version = "2.3.1" @@ -8147,7 +8228,7 @@ dependencies = [ "js-sys", "parking_lot 0.9.0", "pin-utils", - "send_wrapper", + "send_wrapper 0.2.0", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -8235,18 +8316,18 @@ dependencies = [ [[package]] name = "wast" -version = "21.0.0" +version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b1844f66a2bc8526d71690104c0e78a8e59ffa1597b7245769d174ebb91deb5" +checksum = "fe1220ed7f824992b426a76125a3403d048eaf0f627918e97ade0d9b9d510d20" dependencies = [ "leb128", ] [[package]] name = "wat" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce85d72b74242c340e9e3492cfb602652d7bb324c3172dd441b5577e39a2e18c" +checksum = "f888158d9a4b7c39b859f72a435019835b64097c749f4f28d319004ca5a520b8" dependencies = [ "wast", ] @@ -8289,6 +8370,15 @@ dependencies = [ "webpki", ] +[[package]] +name = "wepoll-sys-stjepang" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fd319e971980166b53e17b1026812ad66c6b54063be879eb182342b55284694" +dependencies = [ + "cc", +] + [[package]] name = "which" version = "3.1.1" diff --git a/bin/node-template/node/Cargo.toml b/bin/node-template/node/Cargo.toml index 4967137d22..6b8085be01 100644 --- a/bin/node-template/node/Cargo.toml +++ b/bin/node-template/node/Cargo.toml @@ -24,51 +24,60 @@ structopt = { version = "0.3.15" } tokio = { version = "0.2.22", optional = true, features = ["rt-threaded"] } # darwinia darwinia-balances-rpc = { path = "../../../frame/balances/rpc" } +darwinia-balances-rpc-runtime-api = { path = "../../../frame/balances/rpc/runtime-api" } darwinia-claims = { path = "../../../frame/claims" } darwinia-cli = { optional = true, path = "../../../client/cli" } darwinia-ethereum-linear-relay = { path = "../../../frame/bridge/ethereum/linear-relay" } darwinia-ethereum-relay = { path = "../../../frame/bridge/ethereum/relay" } darwinia-header-mmr-rpc = { path = "../../../frame/header-mmr/rpc" } +darwinia-header-mmr-rpc-runtime-api = { path = "../../../frame/header-mmr/rpc/runtime-api" } darwinia-staking = { path = "../../../frame/staking" } darwinia-staking-rpc = { path = "../../../frame/staking/rpc" } +darwinia-staking-rpc-runtime-api = { path = "../../../frame/staking/rpc/runtime-api" } # substrate -pallet-im-online = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-transaction-payment-rpc = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-basic-authorship = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-cli = { optional = true, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-client-api = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-consensus = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-consensus-babe = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-consensus-babe-rpc = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-consensus-epochs = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-executor = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-finality-grandpa = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-finality-grandpa-rpc = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-keystore = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-network = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-rpc = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-rpc-api = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-service = { optional = true, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-transaction-pool = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-api = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-authority-discovery = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-blockchain = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-block-builder = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-consensus = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-consensus-babe = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-inherents = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-finality-grandpa = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-transaction-pool = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -substrate-frame-rpc-system = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +frame-system-rpc-runtime-api = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-im-online = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-transaction-payment-rpc = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-basic-authorship = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-cli = { optional = true, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-client-api = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-consensus = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-consensus-babe = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-consensus-babe-rpc = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-consensus-epochs = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-executor = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-finality-grandpa = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-finality-grandpa-rpc = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-keystore = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-network = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-rpc = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-rpc-api = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-service = { optional = true, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-transaction-pool = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-api = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-authority-discovery = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-blockchain = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-block-builder = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-consensus = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-consensus-babe = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-inherents = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-finality-grandpa = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-offchain = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-session = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-transaction-pool = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-trie = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +substrate-frame-rpc-system = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +substrate-prometheus-endpoint = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [build-dependencies] # substrate -substrate-build-script-utils = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +substrate-build-script-utils = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [features] -default = [ "cli", "db", "wasmtime" ] +default = [ "cli", "db", "wasmtime", "full-node" ] cli = [ "tokio", "darwinia-cli", @@ -77,3 +86,4 @@ cli = [ ] db = [ "sc-service/db" ] wasmtime = [ "sc-cli/wasmtime" ] +full-node = [] diff --git a/bin/node-template/node/src/chain_spec.rs b/bin/node-template/node/src/chain_spec.rs index 0f30659bee..577363214b 100644 --- a/bin/node-template/node/src/chain_spec.rs +++ b/bin/node-template/node/src/chain_spec.rs @@ -18,8 +18,8 @@ use node_template_runtime::{BalancesConfig as RingConfig, *}; // Note this is the URL for the telemetry server //const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; -/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type. -pub type ChainSpec = sc_service::GenericChainSpec; +/// Specialized `NodeTemplateChainSpec`. This is a specialization of the general Substrate ChainSpec type. +pub type NodeTemplateChainSpec = sc_service::GenericChainSpec; fn session_keys( babe: BabeId, @@ -86,8 +86,8 @@ pub fn get_authority_keys_from_seed( ) } -pub fn development_config() -> ChainSpec { - ChainSpec::from_genesis( +pub fn node_template_development_config() -> NodeTemplateChainSpec { + NodeTemplateChainSpec::from_genesis( "Development", "dev", ChainType::Development, @@ -101,7 +101,6 @@ pub fn development_config() -> ChainSpec { get_account_id_from_seed::("Alice//stash"), get_account_id_from_seed::("Bob//stash"), ], - true, ) }, vec![], @@ -112,8 +111,8 @@ pub fn development_config() -> ChainSpec { ) } -pub fn local_testnet_config() -> ChainSpec { - ChainSpec::from_genesis( +pub fn node_template_local_testnet_config() -> NodeTemplateChainSpec { + NodeTemplateChainSpec::from_genesis( "Local Testnet", "local_testnet", ChainType::Local, @@ -138,7 +137,6 @@ pub fn local_testnet_config() -> ChainSpec { get_account_id_from_seed::("Eve//stash"), get_account_id_from_seed::("Ferdie//stash"), ], - true, ) }, vec![], @@ -160,10 +158,8 @@ fn testnet_genesis( )>, root_key: AccountId, endowed_accounts: Vec, - _enable_println: bool, ) -> GenesisConfig { GenesisConfig { - // --- substrate --- frame_system: Some(SystemConfig { code: WASM_BINARY.to_vec(), changes_trie_config: Default::default(), @@ -192,7 +188,7 @@ fn testnet_genesis( .map(|x| (x.0, x.1, 1 << 60, StakerStatus::Validator)) .collect(), invulnerables: initial_authorities.iter().cloned().map(|x| x.0).collect(), - force_era: darwinia_staking::Forcing::NotForcing, + force_era: darwinia_staking::Forcing::ForceAlways, slash_reward_fraction: Perbill::from_percent(10), payout_fraction: Perbill::from_percent(50), ..Default::default() @@ -209,14 +205,7 @@ fn testnet_genesis( pallet_authority_discovery: Some(Default::default()), pallet_collective_Instance0: Some(Default::default()), pallet_collective_Instance1: Some(Default::default()), - darwinia_elections_phragmen: Some(ElectionsPhragmenConfig { - members: endowed_accounts - .iter() - .take((endowed_accounts.len() + 1) / 2) - .cloned() - .map(|member| (member, 1 << 60)) - .collect(), - }), + darwinia_elections_phragmen: Some(Default::default()), pallet_membership_Instance0: Some(Default::default()), darwinia_claims: Some(ClaimsConfig { claims_list: ClaimsList::from_file( diff --git a/bin/node-template/node/src/command.rs b/bin/node-template/node/src/command.rs index 4d06fb3cd2..6bca90dd40 100644 --- a/bin/node-template/node/src/command.rs +++ b/bin/node-template/node/src/command.rs @@ -1,7 +1,8 @@ // --- std --- use std::path::PathBuf; // --- substrate --- -use sc_cli::{RunCmd, SubstrateCli}; +use sc_cli::{Role, RunCmd, RuntimeVersion, SubstrateCli}; +use sp_core::crypto::Ss58AddressFormat; // --- darwinia --- use crate::{ chain_spec, @@ -11,45 +12,59 @@ use crate::{ use darwinia_cli::{Configuration, DarwiniaCli}; impl SubstrateCli for Cli { - fn impl_name() -> &'static str { - "Darwinia Node" + fn impl_name() -> String { + "Node Template".into() } - fn impl_version() -> &'static str { - env!("SUBSTRATE_CLI_IMPL_VERSION") + fn impl_version() -> String { + env!("SUBSTRATE_CLI_IMPL_VERSION").into() } - fn executable_name() -> &'static str { - env!("CARGO_PKG_NAME") + fn description() -> String { + env!("CARGO_PKG_DESCRIPTION").into() } - fn description() -> &'static str { - env!("CARGO_PKG_DESCRIPTION") + fn author() -> String { + env!("CARGO_PKG_AUTHORS").into() } - fn author() -> &'static str { - env!("CARGO_PKG_AUTHORS") - } - - fn support_url() -> &'static str { - "support.anonymous.an" + fn support_url() -> String { + "support.anonymous.an".into() } fn copyright_start_year() -> i32 { 2018 } + fn executable_name() -> String { + "node-template".into() + } + fn load_spec(&self, id: &str) -> Result, String> { + let id = if id == "" { + let n = get_exec_name().unwrap_or_default(); + ["node-template"] + .iter() + .cloned() + .find(|&chain| n.starts_with(chain)) + .unwrap_or("node-template") + } else { + id + }; + Ok(match id { - "dev" => Box::new(chain_spec::development_config()), - "" | "local" => Box::new(chain_spec::local_testnet_config()), - path => Box::new(chain_spec::ChainSpec::from_json_file( - std::path::PathBuf::from(path), + "node-template-dev" | "dev" => Box::new(chain_spec::node_template_development_config()), + "node-template-local" => Box::new(chain_spec::node_template_local_testnet_config()), + path => Box::new(chain_spec::NodeTemplateChainSpec::from_json_file( + PathBuf::from(path), )?), }) } -} + fn native_runtime_version(_spec: &Box) -> &'static RuntimeVersion { + &service::node_template_runtime::VERSION + } +} impl DarwiniaCli for Cli { fn conf(&self) -> &Option { &self.conf @@ -64,23 +79,48 @@ impl DarwiniaCli for Cli { } } +fn get_exec_name() -> Option { + std::env::current_exe() + .ok() + .and_then(|pb| pb.file_name().map(|s| s.to_os_string())) + .and_then(|s| s.into_string().ok()) +} + /// Parse command line arguments into service configuration. pub fn run() -> sc_cli::Result<()> { let cli = Cli::from_args(); + fn set_default_ss58_version(_spec: &Box) { + let ss58_version = Ss58AddressFormat::PolkadotAccount; + + sp_core::crypto::set_default_ss58_version(ss58_version); + }; + match &cli.subcommand { None => { - let runtime = Configuration::create_runner_from_cli(cli)?; - runtime.run_node( - service::new_light, - service::new_full, - node_template_runtime::VERSION, - ) + let runtime = Configuration::create_runner(cli)?; + let chain_spec = &runtime.config().chain_spec; + + set_default_ss58_version(chain_spec); + + runtime.run_node_until_exit(|config| match config.role { + Role::Light => service::node_template_new_light(config), + _ => service::node_template_new_full(config).map(|(components, _)| components), + }) } Some(Subcommand::Base(subcommand)) => { - let runner = cli.create_runner(subcommand)?; + let runtime = cli.create_runner(subcommand)?; + let chain_spec = &runtime.config().chain_spec; + + set_default_ss58_version(chain_spec); - runner.run_subcommand(subcommand, |config| Ok(new_full_start!(config).0)) + runtime.run_subcommand(subcommand, |config| { + service::new_chain_ops::< + service::node_template_runtime::RuntimeApi, + service::NodeTemplateExecutor, + service::node_template_runtime::UncheckedExtrinsic, + >(config) + }) } } } diff --git a/bin/node-template/node/src/rpc.rs b/bin/node-template/node/src/rpc.rs index b2d5becb80..bc5b4e4abd 100644 --- a/bin/node-template/node/src/rpc.rs +++ b/bin/node-template/node/src/rpc.rs @@ -61,12 +61,25 @@ pub struct FullDeps { pub grandpa: GrandpaDeps, } -pub fn create(deps: FullDeps) -> RpcExtension +/// Light client extra dependencies. +pub struct LightDeps { + /// The client instance to use. + pub client: Arc, + /// Transaction pool instance. + pub pool: Arc

, + /// Remote access to the blockchain (async). + pub remote_blockchain: Arc>, + /// Fetcher instance. + pub fetcher: Arc, +} + +/// Instantiate all RPC extensions. +pub fn create_full(deps: FullDeps) -> RpcExtension where + C: 'static + Send + Sync, C: ProvideRuntimeApi, C: sp_blockchain::HeaderBackend + sp_blockchain::HeaderMetadata, - C: 'static + Send + Sync, C::Api: substrate_frame_rpc_system::AccountNonceApi, C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, C::Api: sc_consensus_babe::BabeApi, @@ -96,8 +109,8 @@ where babe, grandpa, } = deps; - let mut io = jsonrpc_core::IoHandler::default(); + io.extend_with(SystemApi::to_delegate(FullSystem::new( client.clone(), pool, @@ -136,3 +149,33 @@ where io } + +/// Instantiate all RPC extensions for light node. +pub fn create_light(deps: LightDeps) -> RpcExtension +where + C: 'static + Send + Sync, + C: ProvideRuntimeApi, + C: sp_blockchain::HeaderBackend, + C::Api: substrate_frame_rpc_system::AccountNonceApi, + C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, + P: 'static + sp_transaction_pool::TransactionPool, + F: 'static + sc_client_api::Fetcher, + UE: 'static + Send + Sync + codec::Codec, +{ + // --- substrate --- + use substrate_frame_rpc_system::{LightSystem, SystemApi}; + + let LightDeps { + client, + pool, + remote_blockchain, + fetcher, + } = deps; + let mut io = jsonrpc_core::IoHandler::default(); + + io.extend_with(SystemApi::::to_delegate( + LightSystem::new(client, remote_blockchain, fetcher, pool), + )); + + io +} diff --git a/bin/node-template/node/src/service.rs b/bin/node-template/node/src/service.rs index 9bbc72e222..eba7f12d0a 100644 --- a/bin/node-template/node/src/service.rs +++ b/bin/node-template/node/src/service.rs @@ -2,24 +2,45 @@ // --- substrate --- pub use sc_executor::NativeExecutor; +// --- darwinia --- +pub use node_template_runtime; // --- std --- use std::{sync::Arc, time::Duration}; // --- substrate --- -use sc_client_api::ExecutorProvider; +use sc_basic_authorship::ProposerFactory; +use sc_client_api::{ExecutorProvider, StateBackendFor}; use sc_consensus::LongestChain; -use sc_executor::native_executor_instance; +use sc_executor::{native_executor_instance, NativeExecutionDispatch}; +use sc_consensus_babe::{Config as BabeConfig, BabeParams}; use sc_finality_grandpa::{ - self, FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider, + Config as GrandpaConfig,GrandpaParams,SharedVoterState as GrandpaSharedVoterState, VotingRulesBuilder as GrandpaVotingRulesBuilder, + FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider as GrandpaStorageAndProofProvider, +}; +use sc_service::{ + config::{KeystoreConfig, PrometheusConfig}, + Configuration, Error as ServiceError, ServiceBuilder, ServiceComponents, TFullBackend, + TFullClient, TaskManager, }; -use sc_service::{error::Error as ServiceError, AbstractService, Configuration, ServiceBuilder}; +use sc_transaction_pool::{BasicPool, FullChainApi, LightChainApi}; +use sp_api::ConstructRuntimeApi; +use sp_consensus::import_queue::BasicQueue; +use sp_core::traits::BareCryptoStorePtr; use sp_inherents::InherentDataProviders; +use sp_runtime::traits::BlakeTwo256; +use sp_trie::PrefixedMemoryDB; +use substrate_prometheus_endpoint::Registry; // --- darwinia --- -use node_template_runtime::{self, opaque::Block, RuntimeApi}; +use crate::rpc; +use node_template_runtime::{ + opaque::Block, + primitives::{AccountId, Balance, Hash, Nonce, Power}, + RuntimeApi, +}; // Our native executor instance. native_executor_instance!( - pub Executor, + pub NodeTemplateExecutor, node_template_runtime::api::dispatch, node_template_runtime::native_version, ); @@ -29,307 +50,438 @@ native_executor_instance!( /// Use this macro if you don't actually need the full service, but just the builder in order to /// be able to perform chain operations. macro_rules! new_full_start { - ($config:expr) => {{ - // --- std --- - use std::sync::Arc; + ($config:expr, $runtime:ty, $executor:ty) => {{ + set_prometheus_registry(&mut $config)?; let mut import_setup = None; let mut rpc_setup = None; - let inherent_data_providers = sp_inherents::InherentDataProviders::new(); - - let builder = sc_service::ServiceBuilder::new_full::< - node_template_runtime::opaque::Block, - node_template_runtime::RuntimeApi, - crate::service::Executor, - >($config)? - .with_select_chain(|_config, backend| Ok(sc_consensus::LongestChain::new(backend.clone())))? - .with_transaction_pool(|builder| { - let pool_api = sc_transaction_pool::FullChainApi::new(builder.client().clone()); - let config = builder.config(); - - Ok(sc_transaction_pool::BasicPool::new( - config.transaction_pool.clone(), - std::sync::Arc::new(pool_api), - builder.prometheus_registry(), - )) - })? - .with_import_queue( - |_config, - client, - mut select_chain, - _transaction_pool, - spawn_task_handle, - prometheus_registry| { - let select_chain = select_chain - .take() - .ok_or_else(|| sc_service::Error::SelectChainRequired)?; - - let (grandpa_block_import, grandpa_link) = sc_finality_grandpa::block_import( - client.clone(), - &(client.clone() as Arc<_>), - select_chain, - )?; - - let justification_import = grandpa_block_import.clone(); - - let (block_import, babe_link) = sc_consensus_babe::block_import( - sc_consensus_babe::Config::get_or_compute(&*client)?, - grandpa_block_import, - client.clone(), - )?; - - let import_queue = sc_consensus_babe::import_queue( - babe_link.clone(), - block_import.clone(), - Some(Box::new(justification_import)), - None, - client, - inherent_data_providers.clone(), - spawn_task_handle, - prometheus_registry, - )?; - - import_setup = Some((block_import, grandpa_link, babe_link)); - - Ok(import_queue) - }, + let inherent_data_providers = InherentDataProviders::new(); + let builder = ServiceBuilder::new_full::($config)? + .with_select_chain(|_, backend| Ok(LongestChain::new(backend.clone())))? + .with_transaction_pool(|builder| { + let pool_api = + FullChainApi::new(builder.client().clone(), builder.prometheus_registry()); + let pool = BasicPool::new_full( + builder.config().transaction_pool.clone(), + Arc::new(pool_api), + builder.prometheus_registry(), + builder.spawn_handle(), + builder.client().clone(), + ); + + Ok(pool) + })? + .with_import_queue( + |_, client, mut select_chain, _, spawn_task_handle, registry| { + let select_chain = select_chain + .take() + .ok_or_else(|| ServiceError::SelectChainRequired)?; + let (grandpa_block_import, grandpa_link) = sc_finality_grandpa::block_import( + client.clone(), + &(client.clone() as Arc<_>), + select_chain.clone(), + )?; + let justification_import = grandpa_block_import.clone(); + let (block_import, babe_link) = sc_consensus_babe::block_import( + BabeConfig::get_or_compute(&*client)?, + grandpa_block_import, + client.clone(), + )?; + + let import_queue = sc_consensus_babe::import_queue( + babe_link.clone(), + block_import.clone(), + Some(Box::new(justification_import)), + None, + client, + select_chain, + inherent_data_providers.clone(), + spawn_task_handle, + registry, + )?; + + import_setup = Some((block_import, grandpa_link, babe_link)); + + Ok(import_queue) + }, )? - .with_rpc_extensions_builder(|builder| { - let grandpa_link = import_setup - .as_ref() - .map(|s| &s.1) - .expect("GRANDPA LinkHalf is present for full services or set up failed; qed."); - - let shared_authority_set = grandpa_link.shared_authority_set().clone(); - let shared_voter_state = sc_finality_grandpa::SharedVoterState::empty(); - - rpc_setup = Some((shared_voter_state.clone())); - - let babe_link = import_setup - .as_ref() - .map(|s| &s.2) - .expect("BabeLink is present for full services or set up failed; qed."); - - let babe_config = babe_link.config().clone(); - let shared_epoch_changes = babe_link.epoch_changes().clone(); - - let client = builder.client().clone(); - let pool = builder.pool().clone(); - let select_chain = builder - .select_chain() - .cloned() - .expect("SelectChain is present for full services or set up failed; qed."); - let keystore = builder.keystore().clone(); - - Ok(move |deny_unsafe| -> crate::rpc::RpcExtension { - let deps = crate::rpc::FullDeps { - client: client.clone(), - pool: pool.clone(), - select_chain: select_chain.clone(), - deny_unsafe, - babe: crate::rpc::BabeDeps { - babe_config: babe_config.clone(), - shared_epoch_changes: shared_epoch_changes.clone(), - keystore: keystore.clone(), - }, - grandpa: crate::rpc::GrandpaDeps { - shared_voter_state: shared_voter_state.clone(), - shared_authority_set: shared_authority_set.clone(), - }, - }; - - crate::rpc::create(deps) - }) - })?; + .with_rpc_extensions_builder(|builder| { + let grandpa_link = import_setup + .as_ref() + .map(|s| &s.1) + .expect("GRANDPA LinkHalf is present for full services or set up failed; qed."); + let shared_authority_set = grandpa_link.shared_authority_set().clone(); + let shared_voter_state = GrandpaSharedVoterState::empty(); + + rpc_setup = Some((shared_voter_state.clone())); + + let babe_link = import_setup + .as_ref() + .map(|s| &s.2) + .expect("BabeLink is present for full services or set up failed; qed."); + let babe_config = babe_link.config().clone(); + let shared_epoch_changes = babe_link.epoch_changes().clone(); + let client = builder.client().clone(); + let pool = builder.pool().clone(); + let select_chain = builder + .select_chain() + .cloned() + .expect("SelectChain is present for full services or set up failed; qed."); + let keystore = builder.keystore().clone(); + + Ok(move |deny_unsafe| -> rpc::RpcExtension { + let deps = rpc::FullDeps { + client: client.clone(), + pool: pool.clone(), + select_chain: select_chain.clone(), + deny_unsafe, + babe: rpc::BabeDeps { + babe_config: babe_config.clone(), + shared_epoch_changes: shared_epoch_changes.clone(), + keystore: keystore.clone(), + }, + grandpa: rpc::GrandpaDeps { + shared_voter_state: shared_voter_state.clone(), + shared_authority_set: shared_authority_set.clone(), + }, + }; + + rpc::create_full(deps) + }) + })?; (builder, import_setup, inherent_data_providers, rpc_setup) }}; } /// Builds a new service for a full client. -pub fn new_full(config: Configuration) -> Result { - let (role, force_authoring, name, disable_grandpa) = ( - config.role.clone(), - config.force_authoring, - config.network.node_name.clone(), - config.disable_grandpa, - ); - - let (builder, mut import_setup, inherent_data_providers, mut rpc_setup) = - new_full_start!(config); - - let (block_import, grandpa_link, babe_link) = import_setup.take().expect( - "Link Half and Block Import are present for Full Services or setup failed before. qed", - ); - - let shared_voter_state = rpc_setup - .take() - .expect("The SharedVoterState is present for Full Services or setup failed before. qed"); - - let service = builder - .with_finality_proof_provider(|client, backend| { - // GenesisAuthoritySetProvider is implemented for StorageAndProofProvider - let provider = client as Arc>; - Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _) - })? - .build_full()?; - - if let sc_service::config::Role::Authority { .. } = &role { - let proposer = sc_basic_authorship::ProposerFactory::new( - service.client(), - service.transaction_pool(), - service.prometheus_registry().as_ref(), - ); - - let client = service.client(); - let select_chain = service - .select_chain() - .ok_or(ServiceError::SelectChainRequired)?; - - let can_author_with = - sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()); - - let babe_config = sc_consensus_babe::BabeParams { - keystore: service.keystore(), +macro_rules! new_full { + ($config:expr, $runtime:ty, $dispatch:ty) => {{ + let (role, force_authoring, name, disable_grandpa) = ( + $config.role.clone(), + $config.force_authoring, + $config.network.node_name.clone(), + $config.disable_grandpa, + ); + let (builder, mut import_setup, inherent_data_providers, mut rpc_setup) = + new_full_start!($config, $runtime, $dispatch); + let ServiceComponents { client, + network, select_chain, - env: proposer, - block_import, - sync_oracle: service.network(), - inherent_data_providers: inherent_data_providers.clone(), - force_authoring, - babe_link, - can_author_with, - }; - - let babe = sc_consensus_babe::start_babe(babe_config)?; - service - .spawn_essential_task_handle() - .spawn_blocking("babe-proposer", babe); - } + keystore, + transaction_pool, + prometheus_registry, + task_manager, + telemetry_on_connect_sinks, + .. + } = builder + .with_finality_proof_provider(|client, backend| { + let provider = client as Arc>; + Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _) + })? + .build_full()?; + let (block_import, link_half, babe_link) = import_setup.take().expect( + "Link Half and Block Import are present for Full Services or setup failed before. qed", + ); + let shared_voter_state = rpc_setup.take().expect( + "The SharedVoterState is present for Full Services or setup failed before. qed", + ); - // if the node isn't actively participating in consensus then it doesn't - // need a keystore, regardless of which protocol we use below. - let keystore = if role.is_authority() { - Some(service.keystore() as sp_core::traits::BareCryptoStorePtr) - } else { - None - }; - - let grandpa_config = sc_finality_grandpa::Config { - // FIXME #1578 make this available through chainspec - gossip_duration: Duration::from_millis(333), - justification_period: 512, - name: Some(name), - observer_enabled: false, - keystore, - is_authority: role.is_network_authority(), - }; - - let enable_grandpa = !disable_grandpa; - if enable_grandpa { - // start the full GRANDPA voter - // NOTE: non-authorities could run the GRANDPA observer protocol, but at - // this point the full voter should provide better guarantees of block - // and vote data availability than the observer. The observer has not - // been tested extensively yet and having most nodes in a network run it - // could lead to finality stalls. - let grandpa_config = sc_finality_grandpa::GrandpaParams { - config: grandpa_config, - link: grandpa_link, - network: service.network(), - inherent_data_providers: inherent_data_providers.clone(), - telemetry_on_connect: Some(service.telemetry_on_connect_stream()), - voting_rule: sc_finality_grandpa::VotingRulesBuilder::default().build(), - prometheus_registry: service.prometheus_registry(), - shared_voter_state, - }; - - // the GRANDPA voter task is considered infallible, i.e. - // if it fails we take down the service with it. - service.spawn_essential_task_handle().spawn_blocking( - "sc_finality_grandpa-voter", - sc_finality_grandpa::run_grandpa_voter(grandpa_config)?, - ); - } else { - sc_finality_grandpa::setup_disabled_grandpa( - service.client(), - &inherent_data_providers, - service.network(), - )?; + if role.is_authority() { + let select_chain = select_chain.ok_or(ServiceError::SelectChainRequired)?; + let can_author_with = + sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()); + let proposer = ProposerFactory::new( + client.clone(), + transaction_pool, + prometheus_registry.as_ref(), + ); + let babe_config = BabeParams { + keystore: keystore.clone(), + client: client.clone(), + select_chain, + block_import, + env: proposer, + sync_oracle: network.clone(), + inherent_data_providers: inherent_data_providers.clone(), + force_authoring, + babe_link, + can_author_with, + }; + let babe = sc_consensus_babe::start_babe(babe_config)?; + + task_manager + .spawn_essential_handle() + .spawn_blocking("babe", babe); + } + + // if the node isn't actively participating in consensus then it doesn't + // need a keystore, regardless of which protocol we use below. + let keystore = if role.is_authority() { + Some(keystore.clone() as BareCryptoStorePtr) + } else { + None + }; + let grandpa_config = GrandpaConfig { + // FIXME substrate#1578 make this available through chainspec + gossip_duration: Duration::from_millis(1000), + justification_period: 512, + name: Some(name), + observer_enabled: false, + keystore, + is_authority: role.is_network_authority(), + }; + let enable_grandpa = !disable_grandpa; + + if enable_grandpa { + // start the full GRANDPA voter + // NOTE: non-authorities could run the GRANDPA observer protocol, but at + // this point the full voter should provide better guarantees of block + // and vote data availability than the observer. The observer has not + // been tested extensively yet and having most nodes in a network run it + // could lead to finality stalls. + let grandpa_config = GrandpaParams { + config: grandpa_config, + link: link_half, + network: network.clone(), + inherent_data_providers: inherent_data_providers.clone(), + telemetry_on_connect: Some(telemetry_on_connect_sinks.on_connect_stream()), + voting_rule: GrandpaVotingRulesBuilder::default().build(), + prometheus_registry, + shared_voter_state, + }; + + task_manager.spawn_essential_handle().spawn_blocking( + "grandpa-voter", + sc_finality_grandpa::run_grandpa_voter(grandpa_config)?, + ); + } else { + sc_finality_grandpa::setup_disabled_grandpa( + client.clone(), + &inherent_data_providers, + network.clone(), + )?; + } + + (task_manager, client) + }}; +} + +/// Builds a new service for a light client. +macro_rules! new_light { + ($config:expr, $runtime:ty, $dispatch:ty) => {{ + set_prometheus_registry(&mut $config)?; + + let inherent_data_providers = InherentDataProviders::new(); + + ServiceBuilder::new_light::($config)? + .with_select_chain(|_, backend| Ok(LongestChain::new(backend.clone())))? + .with_transaction_pool(|builder| { + let fetcher = builder.fetcher().ok_or_else(|| { + "Trying to start light transaction pool without active fetcher" + })?; + let pool_api = LightChainApi::new(builder.client().clone(), fetcher); + let pool = Arc::new(BasicPool::new_light( + builder.config().transaction_pool.clone(), + Arc::new(pool_api), + builder.prometheus_registry(), + builder.spawn_handle(), + )); + + Ok(pool) + })? + .with_import_queue_and_fprb( + |_, client, backend, fetcher, mut select_chain, _, spawn_task_handle, registry| { + let select_chain = select_chain + .take() + .ok_or_else(|| ServiceError::SelectChainRequired)?; + let fetch_checker = fetcher + .map(|fetcher| fetcher.checker().clone()) + .ok_or_else(|| { + "Trying to start light import queue without active fetch checker" + })?; + let grandpa_block_import = sc_finality_grandpa::light_block_import( + client.clone(), + backend, + &(client.clone() as Arc<_>), + Arc::new(fetch_checker), + )?; + let finality_proof_import = grandpa_block_import.clone(); + let finality_proof_request_builder = + finality_proof_import.create_finality_proof_request_builder(); + let (babe_block_import, babe_link) = sc_consensus_babe::block_import( + BabeConfig::get_or_compute(&*client)?, + grandpa_block_import, + client.clone(), + )?; + // FIXME: pruning task isn't started since light client doesn't do `AuthoritySetup`. + let import_queue = sc_consensus_babe::import_queue( + babe_link, + babe_block_import, + None, + Some(Box::new(finality_proof_import)), + client, + select_chain, + inherent_data_providers.clone(), + spawn_task_handle, + registry, + )?; + + Ok((import_queue, finality_proof_request_builder)) + }, + )? + .with_finality_proof_provider(|client, backend| { + let provider = client as Arc>; + Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _) + })? + .with_rpc_extensions(|builder| { + let fetcher = builder + .fetcher() + .ok_or_else(|| "Trying to start node RPC without active fetcher")?; + let remote_blockchain = builder + .remote_backend() + .ok_or_else(|| "Trying to start node RPC without active remote blockchain")?; + let light_deps = rpc::LightDeps { + remote_blockchain, + fetcher, + client: builder.client().clone(), + pool: builder.pool(), + }; + + Ok(rpc::create_light(light_deps)) + })? + .build_light() + .map(|ServiceComponents { task_manager, .. }| task_manager) + }}; +} + +/// A set of APIs that polkadot-like runtimes must implement. +pub trait RuntimeApiCollection: + sp_api::ApiExt + + sp_api::Metadata + + sp_authority_discovery::AuthorityDiscoveryApi + + sp_block_builder::BlockBuilder + + sp_consensus_babe::BabeApi + + sp_offchain::OffchainWorkerApi + + sp_session::SessionKeys + + sp_transaction_pool::runtime_api::TaggedTransactionQueue + + frame_system_rpc_runtime_api::AccountNonceApi + + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi + + darwinia_balances_rpc_runtime_api::BalancesApi + + darwinia_header_mmr_rpc_runtime_api::HeaderMMRApi + + darwinia_staking_rpc_runtime_api::StakingApi +where + Extrinsic: RuntimeExtrinsic, + >::StateBackend: sp_api::StateBackend, +{ +} +impl RuntimeApiCollection for Api +where + Api: sp_transaction_pool::runtime_api::TaggedTransactionQueue + + sp_api::ApiExt + + sp_api::Metadata + + sp_authority_discovery::AuthorityDiscoveryApi + + sp_block_builder::BlockBuilder + + sp_consensus_babe::BabeApi + + sp_offchain::OffchainWorkerApi + + sp_session::SessionKeys + + frame_system_rpc_runtime_api::AccountNonceApi + + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi + + darwinia_balances_rpc_runtime_api::BalancesApi + + darwinia_header_mmr_rpc_runtime_api::HeaderMMRApi + + darwinia_staking_rpc_runtime_api::StakingApi, + Extrinsic: RuntimeExtrinsic, + >::StateBackend: sp_api::StateBackend, +{ +} + +pub trait RuntimeExtrinsic: codec::Codec + Send + Sync + 'static {} +impl RuntimeExtrinsic for E where E: codec::Codec + Send + Sync + 'static {} + +/// node-template client abstraction, this super trait only pulls in functionality required for +/// node-template internal crates like node-template-collator. +pub trait NodeTemplateClient: + Sized + + Send + + Sync + + sc_client_api::BlockchainEvents + + sp_api::CallApiAt + + sp_api::ProvideRuntimeApi + + sp_blockchain::HeaderBackend +where + Backend: sc_client_api::Backend, + Block: sp_runtime::traits::Block, + Runtime: sp_api::ConstructRuntimeApi, +{ +} +impl NodeTemplateClient for Client +where + Backend: sc_client_api::Backend, + Block: sp_runtime::traits::Block, + Client: Sized + + Send + + Sync + + sp_api::CallApiAt + + sp_api::ProvideRuntimeApi + + sp_blockchain::HeaderBackend + + sc_client_api::BlockchainEvents, + Runtime: sp_api::ConstructRuntimeApi, +{ +} + +fn set_prometheus_registry(config: &mut Configuration) -> Result<(), ServiceError> { + if let Some(PrometheusConfig { registry, .. }) = config.prometheus_config.as_mut() { + *registry = Registry::new_custom(Some("node-template".into()), None)?; } - Ok(service) + Ok(()) } -/// Builds a new service for a light client. -pub fn new_light(config: Configuration) -> Result { - let inherent_data_providers = InherentDataProviders::new(); - - ServiceBuilder::new_light::(config)? - .with_select_chain(|_config, backend| Ok(LongestChain::new(backend.clone())))? - .with_transaction_pool(|builder| { - let fetcher = builder - .fetcher() - .ok_or_else(|| "Trying to start light transaction pool without active fetcher")?; - let pool_api = - sc_transaction_pool::LightChainApi::new(builder.client().clone(), fetcher); - let pool = sc_transaction_pool::BasicPool::with_revalidation_type( - builder.config().transaction_pool.clone(), - Arc::new(pool_api), - builder.prometheus_registry(), - sc_transaction_pool::RevalidationType::Light, - ); - Ok(pool) - })? - .with_import_queue_and_fprb( - |_config, - client, - backend, - fetcher, - _select_chain, - _tx_pool, - spawn_task_handle, - registry| { - let fetch_checker = fetcher - .map(|fetcher| fetcher.checker().clone()) - .ok_or_else(|| { - "Trying to start light import queue without active fetch checker" - })?; - let grandpa_block_import = sc_finality_grandpa::light_block_import( - client.clone(), - backend, - &(client.clone() as Arc<_>), - Arc::new(fetch_checker), - )?; - let finality_proof_import = grandpa_block_import.clone(); - let finality_proof_request_builder = - finality_proof_import.create_finality_proof_request_builder(); - - let (babe_block_import, babe_link) = sc_consensus_babe::block_import( - sc_consensus_babe::Config::get_or_compute(&*client)?, - grandpa_block_import, - client.clone(), - )?; - - let import_queue = sc_consensus_babe::import_queue( - babe_link, - babe_block_import, - None, - Some(Box::new(finality_proof_import)), - client, - inherent_data_providers.clone(), - spawn_task_handle, - registry, - )?; - - Ok((import_queue, finality_proof_request_builder)) - }, - )? - .with_finality_proof_provider(|client, backend| { - // GenesisAuthoritySetProvider is implemented for StorageAndProofProvider - let provider = client as Arc>; - Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _) - })? - .build_light() +/// Builds a new object suitable for chain operations. +pub fn new_chain_ops( + mut config: Configuration, +) -> Result< + ( + Arc>, + Arc>, + BasicQueue>, + TaskManager, + ), + ServiceError, +> +where + Runtime: + 'static + Send + Sync + ConstructRuntimeApi>, + Runtime::RuntimeApi: + RuntimeApiCollection, Block>>, + Dispatch: 'static + NativeExecutionDispatch, + Extrinsic: RuntimeExtrinsic, +{ + config.keystore = KeystoreConfig::InMemory; + + let (builder, _, _, _) = new_full_start!(config, Runtime, Dispatch); + + Ok(builder.to_chain_ops_parts()) +} + +/// Create a new node-template service for a full node. +#[cfg(feature = "full-node")] +pub fn node_template_new_full( + mut config: Configuration, +) -> Result< + ( + TaskManager, + Arc, RuntimeApi>>, + ), + ServiceError, +> { + let (components, client) = new_full!(config, RuntimeApi, NodeTemplateExecutor); + + Ok((components, client)) +} + +/// Create a new node-template service for a light client. +pub fn node_template_new_light(mut config: Configuration) -> Result { + new_light!(config, RuntimeApi, NodeTemplateExecutor) } diff --git a/bin/node-template/runtime/Cargo.toml b/bin/node-template/runtime/Cargo.toml index f422b856c8..52a1af1495 100644 --- a/bin/node-template/runtime/Cargo.toml +++ b/bin/node-template/runtime/Cargo.toml @@ -31,44 +31,44 @@ darwinia-support = { default-features = false, path = "../../../frame/support" } darwinia-treasury = { default-features = false, path = "../../../frame/treasury" } ethereum-primitives = { default-features = false, path = "../../../primitives/ethereum-primitives" } # substrate -frame-executive = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -frame-system-rpc-runtime-api = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-authority-discovery = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-authorship = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-babe = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-collective = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-finality-tracker = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-grandpa = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-im-online = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-membership = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-offences = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-randomness-collective-flip = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-session = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-sudo = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-timestamp = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-transaction-payment = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-transaction-payment-rpc-runtime-api = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-api = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-application-crypto = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-authority-discovery = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-block-builder = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-consensus-babe = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-core = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-inherents = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-io = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-offchain = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-session = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-staking = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-transaction-pool = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-version = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +frame-executive = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +frame-system-rpc-runtime-api = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-authority-discovery = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-authorship = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-babe = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-collective = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-finality-tracker = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-grandpa = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-im-online = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-membership = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-offences = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-randomness-collective-flip = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-session = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-sudo = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-timestamp = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-transaction-payment = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-transaction-payment-rpc-runtime-api = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-api = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-application-crypto = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-authority-discovery = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-block-builder = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-consensus-babe = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-core = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-inherents = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-io = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-offchain = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-session = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-staking = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-transaction-pool = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-version = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [build-dependencies] # substrate -wasm-builder-runner = { package = "substrate-wasm-builder-runner", git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +wasm-builder-runner = { package = "substrate-wasm-builder-runner", git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [features] default = ["std"] diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 16e10994e9..89fe4185e7 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -4,6 +4,32 @@ // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. #![recursion_limit = "256"] +pub mod constants { + // --- darwinia --- + use super::{primitives::*, *}; + + pub const NANO: Balance = 1; + pub const MICRO: Balance = 1_000 * NANO; + pub const MILLI: Balance = 1_000 * MICRO; + pub const COIN: Balance = 1_000 * MILLI; + + pub const CAP: Balance = 10_000_000_000 * COIN; + pub const TOTAL_POWER: Power = 1_000_000_000; + + pub const MILLISECS_PER_BLOCK: Moment = 3000; + pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; + pub const BLOCKS_PER_SESSION: BlockNumber = MINUTES / 2; + pub const SESSIONS_PER_ERA: SessionIndex = 3; + + // These time units are defined in number of blocks. + pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); + pub const HOURS: BlockNumber = 60 * MINUTES; + pub const DAYS: BlockNumber = 24 * HOURS; + + // 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks. + pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); +} + pub mod impls { //! Some configurable implementations as associated type for the substrate runtime. @@ -121,7 +147,7 @@ pub mod impls { /// node's balance type. /// /// This should typically create a mapping between the following ranges: - /// - [0, system::MaximumBlockWeight] + /// - [0, frame_system::MaximumBlockWeight] /// - [Balance::min, Balance::max] /// /// Yet, it can be used for any other sort of change to weight-fee. Some examples being: @@ -268,7 +294,6 @@ pub mod primitives { frame_system::CheckNonce, frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, - pallet_grandpa::ValidateEquivocationReport, darwinia_ethereum_linear_relay::CheckEthereumRelayHeaderHash, ); @@ -354,10 +379,12 @@ use sp_std::prelude::*; use sp_version::NativeVersion; use sp_version::RuntimeVersion; // --- darwinia --- +use constants::*; use darwinia_balances_rpc_runtime_api::RuntimeDispatchInfo as BalancesRuntimeDispatchInfo; use darwinia_ethereum_linear_relay::EthereumNetworkType; use darwinia_ethereum_offchain::crypto::AuthorityId as EthOffchainId; use darwinia_header_mmr_rpc_runtime_api::RuntimeDispatchInfo as HeaderMMRRuntimeDispatchInfo; +use darwinia_staking::EraIndex; use darwinia_staking_rpc_runtime_api::RuntimeDispatchInfo as StakingRuntimeDispatchInfo; use impls::*; @@ -372,35 +399,6 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { transaction_version: 1, }; -pub const NANO: Balance = 1; -pub const MICRO: Balance = 1_000 * NANO; -pub const MILLI: Balance = 1_000 * MICRO; -pub const COIN: Balance = 1_000 * MILLI; - -pub const MILLISECS_PER_BLOCK: u64 = 3000; - -pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; - -// 1 in 4 blocks (on average, not counting collisions) will be primary BABE blocks. -pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); - -// These time units are defined in number of blocks. -pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); -pub const HOURS: BlockNumber = MINUTES * 60; -pub const DAYS: BlockNumber = HOURS * 24; - -pub const BLOCKS_PER_SESSION: BlockNumber = MINUTES / 2; -pub const EPOCH_DURATION_IN_SLOTS: u64 = { - const SLOT_FILL_RATE: f64 = MILLISECS_PER_BLOCK as f64 / SLOT_DURATION as f64; - - (BLOCKS_PER_SESSION as f64 * SLOT_FILL_RATE) as u64 -}; -pub const SESSION_DURATION: BlockNumber = EPOCH_DURATION_IN_SLOTS as _; -pub const SESSIONS_PER_ERA: SessionIndex = 3; - -pub const CAP: Balance = 10_000_000_000 * COIN; -pub const TOTAL_POWER: Power = 1_000_000_000; - /// The version information used to identify this runtime when compiled natively. #[cfg(feature = "std")] pub fn native_version() -> NativeVersion { @@ -451,17 +449,28 @@ impl frame_system::Trait for Runtime { type AccountData = AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { - pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS; + pub const EpochDuration: u64 = BLOCKS_PER_SESSION as _; pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; } impl pallet_babe::Trait for Runtime { type EpochDuration = EpochDuration; type ExpectedBlockTime = ExpectedBlockTime; - // session module is the trigger type EpochChangeTrigger = pallet_babe::ExternalTrigger; + type KeyOwnerProofSystem = Historical; + type KeyOwnerProof = >::Proof; + type KeyOwnerIdentification = >::IdentificationTuple; + type HandleEquivocation = + pallet_babe::EquivocationHandler; } parameter_types! { @@ -471,6 +480,7 @@ impl pallet_timestamp::Trait for Runtime { type Moment = Moment; type OnTimestampSet = Babe; type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); } type RingInstance = darwinia_balances::Instance0; @@ -484,6 +494,7 @@ impl darwinia_balances::Trait for Runtime { type ExistentialDeposit = ExistentialDeposit; type BalanceInfo = AccountData; type AccountStore = System; + type WeightInfo = (); type DustCollector = (Kton,); } type KtonInstance = darwinia_balances::Instance1; @@ -494,6 +505,7 @@ impl darwinia_balances::Trait for Runtime { type ExistentialDeposit = ExistentialDeposit; type BalanceInfo = AccountData; type AccountStore = System; + type WeightInfo = (); type DustCollector = (Ring,); } @@ -534,14 +546,15 @@ impl pallet_authorship::Trait for Runtime { parameter_types! { pub const SessionsPerEra: SessionIndex = SESSIONS_PER_ERA; - pub const BondingDurationInEra: darwinia_staking::EraIndex = 14 * 24 * (HOURS / (SESSIONS_PER_ERA * BLOCKS_PER_SESSION)); + pub const BondingDurationInEra: EraIndex = 14 * DAYS + / (SESSIONS_PER_ERA as BlockNumber * BLOCKS_PER_SESSION); pub const BondingDurationInBlockNumber: BlockNumber = 14 * DAYS; - pub const SlashDeferDuration: darwinia_staking::EraIndex = 0; + pub const SlashDeferDuration: EraIndex = 14 * DAYS + / (SESSIONS_PER_ERA as BlockNumber * BLOCKS_PER_SESSION); + // quarter of the last session will be for election. pub const ElectionLookahead: BlockNumber = BLOCKS_PER_SESSION / 4; - pub const MaxIterations: u32 = 10; - // 0.05%. The higher the value, the more strict solution acceptance becomes. + pub const MaxIterations: u32 = 5; pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000); - /// We prioritize im-online heartbeats over election solution submission. pub const MaxNominatorRewardedPerValidator: u32 = 64; pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2; pub const Cap: Balance = CAP; @@ -575,6 +588,7 @@ impl darwinia_staking::Trait for Runtime { type KtonSlash = Treasury; // rewards are minted from the void type KtonReward = (); + type WeightInfo = (); type Cap = Cap; type TotalPower = TotalPower; } @@ -587,6 +601,7 @@ impl pallet_offences::Trait for Runtime { type IdentificationTuple = pallet_session::historical::IdentificationTuple; type OnOffenceHandler = Staking; type WeightSoftLimit = OffencesWeightSoftLimit; + type WeightInfo = (); } impl pallet_session::historical::Trait for Runtime { @@ -615,6 +630,7 @@ impl pallet_session::Trait for Runtime { type SessionHandler = ::KeyTypeIdProviders; type Keys = SessionKeys; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; + type WeightInfo = (); } parameter_types! { @@ -637,16 +653,12 @@ impl pallet_grandpa::Trait for Runtime { GrandpaId, )>>::IdentificationTuple; type KeyOwnerProofSystem = Historical; - type HandleEquivocation = pallet_grandpa::EquivocationHandler< - Self::KeyOwnerIdentification, - primitives::report::ReporterAppCrypto, - Runtime, - Offences, - >; + type HandleEquivocation = + pallet_grandpa::EquivocationHandler; } parameter_types! { - pub const SessionDuration: BlockNumber = SESSION_DURATION; + pub const SessionDuration: BlockNumber = BLOCKS_PER_SESSION as _; pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); } impl pallet_im_online::Trait for Runtime { @@ -655,6 +667,7 @@ impl pallet_im_online::Trait for Runtime { type SessionDuration = SessionDuration; type ReportUnresponsiveness = Offences; type UnsignedPriority = ImOnlineUnsignedPriority; + type WeightInfo = (); } impl pallet_authority_discovery::Trait for Runtime {} @@ -672,6 +685,7 @@ impl pallet_collective::Trait for Runtime { type Event = Event; type MotionDuration = CouncilMotionDuration; type MaxProposals = CouncilMaxProposals; + type WeightInfo = (); } type TechnicalCollective = pallet_collective::Instance1; impl pallet_collective::Trait for Runtime { @@ -680,6 +694,7 @@ impl pallet_collective::Trait for Runtime { type Event = Event; type MotionDuration = TechnicalMotionDuration; type MaxProposals = TechnicalMaxProposals; + type WeightInfo = (); } parameter_types! { @@ -710,6 +725,7 @@ impl darwinia_elections_phragmen::Trait for Runtime { type DesiredMembers = DesiredMembers; type DesiredRunnersUp = DesiredRunnersUp; type TermDuration = TermDuration; + type WeightInfo = (); } type EnsureRootOrHalfCouncil = EnsureOneOf< @@ -764,6 +780,9 @@ impl darwinia_treasury::Trait for Runtime { type KtonProposalBondMinimum = KtonProposalBondMinimum; type SpendPeriod = SpendPeriod; type Burn = Burn; + type RingBurnDestination = (); + type KtonBurnDestination = (); + type WeightInfo = (); } parameter_types! { @@ -795,6 +814,7 @@ impl darwinia_ethereum_backing::Trait for Runtime { type RingCurrency = Ring; type KtonCurrency = Kton; type SubKeyPrefix = SubKeyPrefix; + type WeightInfo = (); } parameter_types! { @@ -807,6 +827,7 @@ impl darwinia_ethereum_linear_relay::Trait for Runtime { type EthereumNetwork = EthereumNetwork; type Call = Call; type Currency = Ring; + type WeightInfo = (); } parameter_types! { @@ -824,6 +845,7 @@ impl darwinia_ethereum_relay::Trait for Runtime { type ModuleId = EthereumRelayModuleId; type Event = Event; type Currency = Ring; + type WeightInfo = (); } type EthereumRelayerGameInstance = darwinia_relayer_game::Instance0; @@ -839,6 +861,7 @@ impl darwinia_relayer_game::Trait for Runtime { type ConfirmPeriod = ConfirmPeriod; type ApproveOrigin = ApproveOrigin; type RejectOrigin = EnsureRootOrHalfCouncil; + type WeightInfo = (); } impl darwinia_header_mmr::Trait for Runtime {} @@ -855,7 +878,7 @@ construct_runtime!( RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage}, // Must be before session. - Babe: pallet_babe::{Module, Call, Storage, Config, Inherent(Timestamp)}, + Babe: pallet_babe::{Module, Call, Storage, Config, Inherent, ValidateUnsigned}, Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent}, Balances: darwinia_balances::::{Module, Call, Storage, Config, Event}, @@ -869,7 +892,7 @@ construct_runtime!( Historical: pallet_session_historical::{Module}, Session: pallet_session::{Module, Call, Storage, Config, Event}, FinalityTracker: pallet_finality_tracker::{Module, Call, Storage, Inherent}, - Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event}, + Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event, ValidateUnsigned}, ImOnline: pallet_im_online::{Module, Call, Storage, Config, Event, ValidateUnsigned}, AuthorityDiscovery: pallet_authority_discovery::{Module, Call, Config}, @@ -895,19 +918,6 @@ construct_runtime!( } ); -impl frame_system::offchain::SigningTypes for Runtime { - type Public = ::Signer; - type Signature = Signature; -} - -impl frame_system::offchain::SendTransactionTypes for Runtime -where - Call: From, -{ - type Extrinsic = UncheckedExtrinsic; - type OverarchingCall = Call; -} - impl frame_system::offchain::CreateSignedTransaction for Runtime where Call: From, @@ -940,7 +950,6 @@ where frame_system::CheckNonce::::from(nonce), frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(tip), - pallet_grandpa::ValidateEquivocationReport::::new(), Default::default(), ); let raw_payload = SignedPayload::new(call, extra) @@ -953,6 +962,17 @@ where Some((call, (account, signature, extra))) } } +impl frame_system::offchain::SigningTypes for Runtime { + type Public = ::Signer; + type Signature = Signature; +} +impl frame_system::offchain::SendTransactionTypes for Runtime +where + Call: From, +{ + type Extrinsic = UncheckedExtrinsic; + type OverarchingCall = Call; +} impl_runtime_apis! { impl sp_api::Core for Runtime { @@ -1022,7 +1042,7 @@ impl_runtime_apis! { Grandpa::grandpa_authorities() } - fn submit_report_equivocation_extrinsic( + fn submit_report_equivocation_unsigned_extrinsic( equivocation_proof: fg_primitives::EquivocationProof< ::Hash, NumberFor, @@ -1031,7 +1051,7 @@ impl_runtime_apis! { ) -> Option<()> { let key_owner_proof = key_owner_proof.decode()?; - Grandpa::submit_report_equivocation_extrinsic( + Grandpa::submit_unsigned_equivocation_report( equivocation_proof, key_owner_proof, ) @@ -1069,6 +1089,29 @@ impl_runtime_apis! { fn current_epoch_start() -> sp_consensus_babe::SlotNumber { Babe::current_epoch_start() } + + fn generate_key_ownership_proof( + _slot_number: sp_consensus_babe::SlotNumber, + authority_id: sp_consensus_babe::AuthorityId, + ) -> Option { + use codec::Encode; + + Historical::prove((sp_consensus_babe::KEY_TYPE, authority_id)) + .map(|p| p.encode()) + .map(sp_consensus_babe::OpaqueKeyOwnershipProof::new) + } + + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: sp_consensus_babe::EquivocationProof<::Header>, + key_owner_proof: sp_consensus_babe::OpaqueKeyOwnershipProof, + ) -> Option<()> { + let key_owner_proof = key_owner_proof.decode()?; + + Babe::submit_unsigned_equivocation_report( + equivocation_proof, + key_owner_proof, + ) + } } impl sp_authority_discovery::AuthorityDiscoveryApi for Runtime { diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index 948df8bed2..597b00a470 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -13,7 +13,7 @@ repository = "https://github.com/darwinia-network/darwinia-common/" serde = { version = "1.0.114", features = ["derive"] } toml = { version = "0.5.6" } # substrate -sc-cli = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-client-api = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-service = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sc-tracing = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +sc-cli = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-client-api = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-service = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sc-tracing = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index 860c5cf0a3..78d23e8d12 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -204,7 +204,7 @@ pub struct Configuration { sentry_nodes: Option>, } impl Configuration { - pub fn create_runner_from_cli( + pub fn create_runner( cli: C, ) -> sc_cli::Result> { if let Some(path) = cli.conf() { @@ -342,7 +342,9 @@ impl Configuration { self.keystore_config, password_interactive ); - quick_if_let!(cmd.keystore_params, self.keystore_config, Some(password)); + if let Some(ref password) = self.keystore_config.password { + cmd.keystore_params.password = Some(password.parse().unwrap()); + } quick_if_let!( cmd.keystore_params, self.keystore_config, diff --git a/frame/balances/Cargo.toml b/frame/balances/Cargo.toml index 59c4849371..fcb5883079 100644 --- a/frame/balances/Cargo.toml +++ b/frame/balances/Cargo.toml @@ -16,16 +16,16 @@ serde = { version = "1.0.114", optional = true } darwinia-balances-rpc-runtime-api = { default-features = false, path = "./rpc/runtime-api" } darwinia-support = { default-features = false, path = "../support" } # substrate -frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [dev-dependencies] # substrate -pallet-transaction-payment = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-io = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +pallet-transaction-payment = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-io = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [features] default = ["std"] diff --git a/frame/balances/rpc/Cargo.toml b/frame/balances/rpc/Cargo.toml index 445ab4eaea..2e26637070 100644 --- a/frame/balances/rpc/Cargo.toml +++ b/frame/balances/rpc/Cargo.toml @@ -17,6 +17,6 @@ jsonrpc-derive = "14.2.1" # darwinia darwinia-balances-rpc-runtime-api = { path = "./runtime-api" } # substrate -sp-api = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-blockchain = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +sp-api = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-blockchain = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } diff --git a/frame/balances/rpc/runtime-api/Cargo.toml b/frame/balances/rpc/runtime-api/Cargo.toml index 6d330b5ab7..0efd3d415a 100644 --- a/frame/balances/rpc/runtime-api/Cargo.toml +++ b/frame/balances/rpc/runtime-api/Cargo.toml @@ -15,8 +15,8 @@ serde = { version = "1.0.114", optional = true, features = ["derive"] } # darwinia darwinia-support = { default-features = false, path = "../../../support" } # substrate -sp-api = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +sp-api = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [features] default = ["std"] diff --git a/frame/balances/src/benchmarking.rs b/frame/balances/src/benchmarking.rs deleted file mode 100644 index f2b44a14a1..0000000000 --- a/frame/balances/src/benchmarking.rs +++ /dev/null @@ -1,149 +0,0 @@ -//! Balances pallet benchmarking. - -// --- substrate --- -use frame_benchmarking::{account, benchmarks}; -use frame_system::RawOrigin; -use sp_runtime::traits::{Bounded, Dispatchable}; -// --- darwinia --- -use crate::{Module as Balances, *}; - -const SEED: u32 = 0; -const MAX_EXISTENTIAL_DEPOSIT: u32 = 1000; -const MAX_USER_INDEX: u32 = 1000; - -benchmarks! { - _ { - let e in 2 .. MAX_EXISTENTIAL_DEPOSIT => (); - let u in 1 .. MAX_USER_INDEX => (); - } - - // Benchmark `transfer` extrinsic with the worst possible conditions: - // * Transfer will kill the sender account. - // * Transfer will create the recipient account. - transfer { - let u in ...; - let e in ...; - - let existential_deposit = T::ExistentialDeposit::get(); - let caller = account("caller", u, SEED); - - // Give some multiple of the existential deposit + creation fee + transfer fee - let balance = existential_deposit.saturating_mul(e.into()); - let _ = as Currency<_>>::make_free_balance_be(&caller, balance); - - // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, and reap this user. - let recipient: T::AccountId = account("recipient", u, SEED); - let recipient_lookup: ::Source = T::Lookup::unlookup(recipient.clone()); - let transfer_amount = existential_deposit.saturating_mul((e - 1).into()) + 1.into(); - }: _(RawOrigin::Signed(caller), recipient_lookup, transfer_amount) - verify { - assert_eq!(>::free_balance(&recipient), transfer_amount); - } - - // Benchmark `transfer` with the best possible condition: - // * Both accounts exist and will continue to exist. - transfer_best_case { - let u in ...; - let e in ...; - - let caller = account("caller", u, SEED); - let recipient: T::AccountId = account("recipient", u, SEED); - let recipient_lookup: ::Source = T::Lookup::unlookup(recipient.clone()); - - // Give the sender account max funds for transfer (their account will never reasonably be killed). - let _ = as Currency<_>>::make_free_balance_be(&caller, T::Balance::max_value()); - - // Give the recipient account existential deposit (thus their account already exists). - let existential_deposit = T::ExistentialDeposit::get(); - let _ = as Currency<_>>::make_free_balance_be(&recipient, existential_deposit); - let transfer_amount = existential_deposit.saturating_mul(e.into()); - }: transfer(RawOrigin::Signed(caller), recipient_lookup, transfer_amount) - - // Benchmark `transfer_keep_alive` with the worst possible condition: - // * The recipient account is created. - transfer_keep_alive { - let u in ...; - let e in ...; - - let caller = account("caller", u, SEED); - let recipient = account("recipient", u, SEED); - let recipient_lookup: ::Source = T::Lookup::unlookup(recipient); - - // Give the sender account max funds, thus a transfer will not kill account. - let _ = as Currency<_>>::make_free_balance_be(&caller, T::Balance::max_value()); - let existential_deposit = T::ExistentialDeposit::get(); - let transfer_amount = existential_deposit.saturating_mul(e.into()); - }: _(RawOrigin::Signed(caller), recipient_lookup, transfer_amount) - - // Benchmark `set_balance` coming from ROOT account. This always creates an account. - set_balance { - let u in ...; - let e in ...; - - let user: T::AccountId = account("user", u, SEED); - let user_lookup: ::Source = T::Lookup::unlookup(user.clone()); - - // Give the user some initial balance. - let existential_deposit = T::ExistentialDeposit::get(); - let balance_amount = existential_deposit.saturating_mul(e.into()); - let _ = as Currency<_>>::make_free_balance_be(&user, balance_amount); - }: _(RawOrigin::Root, user_lookup, balance_amount, balance_amount) - - // Benchmark `set_balance` coming from ROOT account. This always kills an account. - set_balance_killing { - let u in ...; - let e in ...; - - let user: T::AccountId = account("user", u, SEED); - let user_lookup: ::Source = T::Lookup::unlookup(user.clone()); - - // Give the user some initial balance. - let existential_deposit = T::ExistentialDeposit::get(); - let balance_amount = existential_deposit.saturating_mul(e.into()); - let _ = as Currency<_>>::make_free_balance_be(&user, balance_amount); - }: set_balance(RawOrigin::Root, user_lookup, 0.into(), 0.into()) -} - -#[cfg(test)] -mod tests { - // --- substrate --- - use frame_support::assert_ok; - // --- darwinia --- - use super::*; - use crate::tests_composite::{ExtBuilder, Test}; - - #[test] - fn transfer() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(test_benchmark_transfer::()); - }); - } - - #[test] - fn transfer_best_case() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(test_benchmark_transfer_best_case::()); - }); - } - - #[test] - fn transfer_keep_alive() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(test_benchmark_transfer_keep_alive::()); - }); - } - - #[test] - fn transfer_set_balance() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(test_benchmark_set_balance::()); - }); - } - - #[test] - fn transfer_set_balance_killing() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(test_benchmark_set_balance_killing::()); - }); - } -} diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index 88083a5930..060d236f10 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -132,9 +132,6 @@ #![cfg_attr(not(feature = "std"), no_std)] -#[cfg(feature = "runtime-benchmarks")] -mod benchmarking; - #[cfg(test)] #[macro_use] mod tests; @@ -156,9 +153,10 @@ use frame_support::{ ExistenceRequirement::KeepAlive, Get, Imbalance, IsDeadAccount, OnKilledAccount, OnUnbalanced, ReservableCurrency, SignedImbalance, StoredMap, TryDrop, }, + weights::Weight, Parameter, StorageValue, }; -use frame_system::{self as system, ensure_root, ensure_signed}; +use frame_system::{ensure_root, ensure_signed}; use sp_runtime::{ traits::{ AtLeast32BitUnsigned, Bounded, CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Member, @@ -182,6 +180,31 @@ use darwinia_support::{ traits::BalanceInfo, }; +pub trait WeightInfo { + fn transfer(u: u32, e: u32) -> Weight; + fn transfer_best_case(u: u32, e: u32) -> Weight; + fn transfer_keep_alive(u: u32, e: u32) -> Weight; + fn set_balance(u: u32, e: u32) -> Weight; + fn set_balance_killing(u: u32, e: u32) -> Weight; +} +impl WeightInfo for () { + fn transfer(_u: u32, _e: u32) -> Weight { + 1_000_000_000 + } + fn transfer_best_case(_u: u32, _e: u32) -> Weight { + 1_000_000_000 + } + fn transfer_keep_alive(_u: u32, _e: u32) -> Weight { + 1_000_000_000 + } + fn set_balance(_u: u32, _e: u32) -> Weight { + 1_000_000_000 + } + fn set_balance_killing(_u: u32, _e: u32) -> Weight { + 1_000_000_000 + } +} + pub trait Subtrait: frame_system::Trait { /// The balance of an account. type Balance: Parameter @@ -207,6 +230,9 @@ pub trait Subtrait: frame_system::Trait { + Default + EncodeLike; + /// Weight information for the extrinsics in this pallet. + type WeightInfo: WeightInfo; + // TODO: doc type DustCollector: DustCollector; } @@ -242,6 +268,9 @@ pub trait Trait: frame_system::Trait { /// The means of storing the balances of an account. type AccountStore: StoredMap; + /// Weight information for the extrinsics in this pallet. + type WeightInfo: WeightInfo; + // TODO: doc type DustCollector: DustCollector; } @@ -251,6 +280,7 @@ impl, I: Instance> Subtrait for T { type ExistentialDeposit = T::ExistentialDeposit; type AccountStore = T::AccountStore; type BalanceInfo = T::BalanceInfo; + type WeightInfo = >::WeightInfo; type DustCollector = T::DustCollector; } @@ -260,23 +290,24 @@ decl_event!( ::AccountId, >::Balance, { - /// An account was created with some free balance. + /// An account was created with some free balance. [account, free_balance] Endowed(AccountId, Balance), /// An account was removed whose balance was non-zero but below ExistentialDeposit, - /// resulting in an outright loss. + /// resulting in an outright loss. [account, balance] DustLost(AccountId, Balance), - /// Transfer succeeded (from, to, value). + /// Transfer succeeded. [from, to, value] Transfer(AccountId, AccountId, Balance), - /// A balance was set by root (who, free, reserved). + /// A balance was set by root. [who, free, reserved] BalanceSet(AccountId, Balance, Balance), - /// Some amount was deposited (e.g. for transaction fees). + /// Some amount was deposited (e.g. for transaction fees). [who, deposit] Deposit(AccountId, Balance), - /// Some balance was reserved (moved from free to reserved). + /// Some balance was reserved (moved from free to reserved). [who, value] Reserved(AccountId, Balance), - /// Some balance was unreserved (moved from reserved to free). + /// Some balance was unreserved (moved from reserved to free). [who, value] Unreserved(AccountId, Balance), /// Some balance was moved from the reserve of the first account to the second account. /// Final argument indicates the destination balance type. + /// [from, to, balance, destination_status] ReserveRepatriated(AccountId, AccountId, Balance, Status), } ); @@ -812,6 +843,7 @@ impl, I: Instance> frame_system::Trait for ElevatedTrait { type AccountData = T::AccountData; type OnNewAccount = T::OnNewAccount; type OnKilledAccount = T::OnKilledAccount; + type SystemWeightInfo = T::SystemWeightInfo; } impl, I: Instance> Trait for ElevatedTrait { type Balance = T::Balance; @@ -820,6 +852,7 @@ impl, I: Instance> Trait for ElevatedTrait { type ExistentialDeposit = T::ExistentialDeposit; type BalanceInfo = T::BalanceInfo; type AccountStore = T::AccountStore; + type WeightInfo = >::WeightInfo; type DustCollector = T::DustCollector; } diff --git a/frame/balances/src/tests_local.rs b/frame/balances/src/tests_local.rs index a5cacf314f..c3e79a59dd 100644 --- a/frame/balances/src/tests_local.rs +++ b/frame/balances/src/tests_local.rs @@ -99,6 +99,7 @@ impl frame_system::Trait for Test { type AccountData = AccountData; type OnNewAccount = (); type OnKilledAccount = Ring; + type SystemWeightInfo = (); } parameter_types! { pub const TransactionByteFee: Balance = 1; @@ -118,11 +119,12 @@ impl Trait for Test { type BalanceInfo = AccountData; type AccountStore = StorageMapShim< Account, - system::CallOnCreatedAccount, - system::CallKillAccount, + frame_system::CallOnCreatedAccount, + frame_system::CallKillAccount, Balance, AccountData, >; + type WeightInfo = (); type DustCollector = (Kton,); } impl Trait for Test { @@ -133,11 +135,12 @@ impl Trait for Test { type BalanceInfo = AccountData; type AccountStore = StorageMapShim< Account, - system::CallOnCreatedAccount, - system::CallKillAccount, + frame_system::CallOnCreatedAccount, + frame_system::CallKillAccount, Balance, AccountData, >; + type WeightInfo = (); type DustCollector = (Ring,); } @@ -208,7 +211,7 @@ fn emit_events_with_no_existential_deposit_suicide_with_dust() { assert_eq!( events(), [ - Event::system(system::RawEvent::NewAccount(1)), + Event::system(frame_system::RawEvent::NewAccount(1)), Event::balances_Instance0(RawEvent::Endowed(1, 100)), Event::balances_Instance0(RawEvent::BalanceSet(1, 100, 0)), ] @@ -225,7 +228,7 @@ fn emit_events_with_no_existential_deposit_suicide_with_dust() { events(), [ Event::balances_Instance0(RawEvent::DustLost(1, 1)), - Event::system(system::RawEvent::KilledAccount(1)) + Event::system(frame_system::RawEvent::KilledAccount(1)) ] ); }); diff --git a/frame/bridge/ethereum/backing/Cargo.toml b/frame/bridge/ethereum/backing/Cargo.toml index a7c430219f..55064b699a 100644 --- a/frame/bridge/ethereum/backing/Cargo.toml +++ b/frame/bridge/ethereum/backing/Cargo.toml @@ -19,11 +19,11 @@ ethereum-primitives = { default-features = false, path = "../../../../primitives # github ethabi = { default-features = false, git = "https://github.com/darwinia-network/ethabi.git", branch = "with_no_std" } # substrate -frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-core = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-core = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [dev-dependencies] # darwinia @@ -34,10 +34,10 @@ ethereum-primitives = { features = ["easy-testing"], path = "../../../../primiti # github rlp = { package = "rlp", git = "https://github.com/darwinia-network/parity-common.git" } # substrate -pallet-session = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-timestamp = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-io = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-staking = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +pallet-session = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-timestamp = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-io = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-staking = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [features] default = ["std"] diff --git a/frame/bridge/ethereum/backing/src/lib.rs b/frame/bridge/ethereum/backing/src/lib.rs index 9227720ec6..8f2c28727f 100644 --- a/frame/bridge/ethereum/backing/src/lib.rs +++ b/frame/bridge/ethereum/backing/src/lib.rs @@ -3,53 +3,6 @@ #![cfg_attr(not(feature = "std"), no_std)] #![recursion_limit = "128"] -mod migration { - // --- substrate --- - use frame_support::migration::*; - // --- darwinia --- - use crate::*; - - pub fn migrate() { - sp_runtime::print("Migrating DarwiniaEthereumBacking..."); - - let old_module: &[u8] = b"DarwiniaEthBacking"; - let new_module: &[u8] = b"DarwiniaEthereumBacking"; - let addresses: &[&[u8]] = &[ - // pub RingRedeemAddress get(fn ring_redeem_address) config(): EthAddress; - b"RingRedeemAddress", - // pub KtonRedeemAddress get(fn kton_redeem_address) config(): EthAddress; - b"KtonRedeemAddress", - // pub DepositRedeemAddress get(fn deposit_redeem_address) config(): EthAddress; - b"DepositRedeemAddress", - ]; - let receipt_proofs: &[&[u8]] = &[ - // pub RingProofVerified - // get(fn ring_proof_verfied) - // : map hasher(blake2_128_concat) EthTransactionIndex => Option; - b"RingProofVerified", - // pub KtonProofVerified - // get(fn kton_proof_verfied) - // : map hasher(blake2_128_concat) EthTransactionIndex => Option; - b"KtonProofVerified", - // pub DepositProofVerified - // get(fn deposit_proof_verfied) - // : map hasher(blake2_128_concat) EthTransactionIndex => Option; - b"DepositProofVerified", - ]; - let hash: &[u8] = &[]; - - for address in addresses { - if let Some(value) = take_storage_value::(old_module, address, hash) { - put_storage_value(new_module, address, hash, value); - } - } - - for item in receipt_proofs { - remove_storage_prefix(old_module, item, hash); - } - } -} - #[cfg(test)] mod mock; #[cfg(test)] @@ -62,12 +15,12 @@ mod types { pub type DepositId = U256; pub type RingBalance = - <::RingCurrency as Currency<::AccountId>>::Balance; + <::RingCurrency as Currency<::AccountId>>::Balance; pub type KtonBalance = - <::KtonCurrency as Currency<::AccountId>>::Balance; + <::KtonCurrency as Currency<::AccountId>>::Balance; pub type EthereumReceiptProof = <::EthereumRelay as EthereumReceipt< - ::AccountId, + ::AccountId, RingBalance, >>::EthereumReceiptProof; } @@ -81,7 +34,7 @@ use frame_support::{ debug, decl_error, decl_event, decl_module, decl_storage, ensure, traits::{Currency, ExistenceRequirement::KeepAlive, Get}, }; -use frame_system::{self as system, ensure_root, ensure_signed}; +use frame_system::{ensure_root, ensure_signed}; use sp_runtime::{ traits::{AccountIdConversion, SaturatedConversion, Saturating}, DispatchError, DispatchResult, ModuleId, RuntimeDebug, @@ -98,7 +51,7 @@ pub trait Trait: frame_system::Trait { /// The backing's module id, used for deriving its sovereign account ID. type ModuleId: Get; - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; type DetermineAccountId: AccountIdFor; @@ -111,59 +64,23 @@ pub trait Trait: frame_system::Trait { type KtonCurrency: LockableCurrency; type SubKeyPrefix: Get; -} -#[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug)] -pub enum RedeemFor { - Ring, - Kton, - Deposit, -} - -decl_storage! { - trait Store for Module as DarwiniaEthereumBacking { - pub RingProofVerified - get(fn ring_proof_verfied) - : map hasher(blake2_128_concat) EthTransactionIndex => Option; - pub RingRedeemAddress get(fn ring_redeem_address) config(): EthAddress; - - pub KtonProofVerified - get(fn kton_proof_verfied) - : map hasher(blake2_128_concat) EthTransactionIndex => Option; - pub KtonRedeemAddress get(fn kton_redeem_address) config(): EthAddress; - - pub DepositProofVerified - get(fn deposit_proof_verfied) - : map hasher(blake2_128_concat) EthTransactionIndex => Option; - pub DepositRedeemAddress get(fn deposit_redeem_address) config(): EthAddress; - } - add_extra_genesis { - config(ring_locked): RingBalance; - config(kton_locked): KtonBalance; - build(|config: &GenesisConfig| { - // Create Backing account - let _ = T::RingCurrency::make_free_balance_be( - &>::account_id(), - T::RingCurrency::minimum_balance().max(config.ring_locked), - ); - - let _ = T::KtonCurrency::make_free_balance_be( - &>::account_id(), - T::KtonCurrency::minimum_balance().max(config.kton_locked), - ); - }); - } + /// Weight information for the extrinsics in this pallet. + type WeightInfo: WeightInfo; } decl_event! { pub enum Event where - ::AccountId, + ::AccountId, RingBalance = RingBalance, KtonBalance = KtonBalance, { + /// Some one redeem some *RING*. [account, amount, transaction index] RedeemRing(AccountId, RingBalance, EthTransactionIndex), + /// Some one redeem some *KTON*. [account, amount, transaction index] RedeemKton(AccountId, KtonBalance, EthTransactionIndex), + /// Some one redeem a deposit. [account, deposit id, amount, transaction index] RedeemDeposit(AccountId, DepositId, RingBalance, EthTransactionIndex), } } @@ -206,6 +123,41 @@ decl_error! { } } +decl_storage! { + trait Store for Module as DarwiniaEthereumBacking { + pub RingProofVerified + get(fn ring_proof_verfied) + : map hasher(blake2_128_concat) EthTransactionIndex => Option; + pub RingRedeemAddress get(fn ring_redeem_address) config(): EthAddress; + + pub KtonProofVerified + get(fn kton_proof_verfied) + : map hasher(blake2_128_concat) EthTransactionIndex => Option; + pub KtonRedeemAddress get(fn kton_redeem_address) config(): EthAddress; + + pub DepositProofVerified + get(fn deposit_proof_verfied) + : map hasher(blake2_128_concat) EthTransactionIndex => Option; + pub DepositRedeemAddress get(fn deposit_redeem_address) config(): EthAddress; + } + add_extra_genesis { + config(ring_locked): RingBalance; + config(kton_locked): KtonBalance; + build(|config: &GenesisConfig| { + // Create Backing account + let _ = T::RingCurrency::make_free_balance_be( + &>::account_id(), + T::RingCurrency::minimum_balance().max(config.ring_locked), + ); + + let _ = T::KtonCurrency::make_free_balance_be( + &>::account_id(), + T::KtonCurrency::minimum_balance().max(config.kton_locked), + ); + }); + } +} + decl_module! { pub struct Module for enum Call where @@ -220,12 +172,6 @@ decl_module! { fn deposit_event() = default; - fn on_runtime_upgrade() -> frame_support::weights::Weight { - migration::migrate::(); - - 0 - } - /// Redeem balances /// /// # @@ -658,12 +604,22 @@ impl Module { } } +// TODO: https://github.com/darwinia-network/darwinia-common/issues/209 +pub trait WeightInfo {} +impl WeightInfo for () {} + +#[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug)] +pub enum RedeemFor { + Ring, + Kton, + Deposit, +} + pub trait AccountIdFor { fn account_id_for(decoded_sub_key: &[u8]) -> Result; } pub struct AccountIdDeterminator(PhantomData); - impl AccountIdFor for AccountIdDeterminator where T::AccountId: sp_std::convert::From<[u8; 32]> + AsRef<[u8]>, diff --git a/frame/bridge/ethereum/backing/src/mock.rs b/frame/bridge/ethereum/backing/src/mock.rs index b5119a6994..015800ee26 100644 --- a/frame/bridge/ethereum/backing/src/mock.rs +++ b/frame/bridge/ethereum/backing/src/mock.rs @@ -49,7 +49,7 @@ thread_local! { } impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } impl_outer_dispatch! { @@ -102,6 +102,7 @@ impl Trait for Test { type RingCurrency = Ring; type KtonCurrency = Kton; type SubKeyPrefix = SubKeyPrefix; + type WeightInfo = (); } parameter_types! { @@ -135,12 +136,14 @@ impl frame_system::Trait for Test { type AccountData = AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl pallet_timestamp::Trait for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = (); + type WeightInfo = (); } parameter_types! { @@ -157,6 +160,7 @@ impl pallet_session::Trait for Test { type SessionHandler = TestSessionHandler; type Keys = UintAuthorityId; type DisabledValidatorsThreshold = (); + type WeightInfo = (); } impl pallet_session::historical::Trait for Test { @@ -174,6 +178,7 @@ impl darwinia_ethereum_linear_relay::Trait for Test { type EthereumNetwork = EthereumNetwork; type Call = Call; type Currency = Ring; + type WeightInfo = (); } impl darwinia_balances::Trait for Test { @@ -183,6 +188,7 @@ impl darwinia_balances::Trait for Test { type ExistentialDeposit = (); type BalanceInfo = AccountData; type AccountStore = System; + type WeightInfo = (); type DustCollector = (); } impl darwinia_balances::Trait for Test { @@ -192,6 +198,7 @@ impl darwinia_balances::Trait for Test { type ExistentialDeposit = (); type BalanceInfo = AccountData; type AccountStore = System; + type WeightInfo = (); type DustCollector = (); } @@ -202,7 +209,7 @@ impl darwinia_staking::Trait for Test { type BondingDurationInEra = (); type BondingDurationInBlockNumber = (); type SlashDeferDuration = (); - type SlashCancelOrigin = system::EnsureRoot; + type SlashCancelOrigin = frame_system::EnsureRoot; type SessionInterface = Self; type NextNewSession = Session; type ElectionLookahead = (); @@ -211,6 +218,7 @@ impl darwinia_staking::Trait for Test { type MinSolutionScoreBump = (); type MaxNominatorRewardedPerValidator = (); type UnsignedPriority = (); + type WeightInfo = (); type RingCurrency = Ring; type RingRewardRemainder = (); type RingSlash = (); @@ -238,7 +246,7 @@ impl Default for ExtBuilder { } impl ExtBuilder { pub fn build(self) -> sp_io::TestExternalities { - let mut t = system::GenesisConfig::default() + let mut t = frame_system::GenesisConfig::default() .build_storage::() .unwrap(); diff --git a/frame/bridge/ethereum/linear-relay/Cargo.toml b/frame/bridge/ethereum/linear-relay/Cargo.toml index 36f75a9118..8c25ad3363 100644 --- a/frame/bridge/ethereum/linear-relay/Cargo.toml +++ b/frame/bridge/ethereum/linear-relay/Cargo.toml @@ -21,10 +21,10 @@ ethereum-primitives = { default-features = false, path = "../../../../primitives ethereum-types = { default-features = false, git = "https://github.com/darwinia-network/parity-common.git" } rlp = { default-features = false, git = "https://github.com/darwinia-network/parity-common.git" } # substrate -frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [dev-dependencies] # darwinia @@ -32,8 +32,8 @@ array-bytes = { path = "../../../../primitives/array-bytes" } darwinia-balances = { path = "../../../../frame/balances" } ethereum-primitives = { features = ["easy-testing"], path = "../../../../primitives/ethereum-primitives" } # substrate -sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-io = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-io = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [features] default = ["std"] diff --git a/frame/bridge/ethereum/linear-relay/src/lib.rs b/frame/bridge/ethereum/linear-relay/src/lib.rs index 109d0f3b31..49408534a6 100644 --- a/frame/bridge/ethereum/linear-relay/src/lib.rs +++ b/frame/bridge/ethereum/linear-relay/src/lib.rs @@ -39,7 +39,7 @@ mod types { pub type Balance = as Currency>>::Balance; - type AccountId = ::AccountId; + type AccountId = ::AccountId; type CurrencyT = ::Currency; } @@ -56,7 +56,7 @@ use frame_support::{ traits::{Currency, ExistenceRequirement::KeepAlive, ReservableCurrency}, IsSubType, }; -use frame_system::{self as system, ensure_root, ensure_signed}; +use frame_system::{ensure_root, ensure_signed}; use sp_runtime::{ traits::{AccountIdConversion, DispatchInfoOf, Dispatchable, Saturating, SignedExtension}, transaction_validity::{ @@ -89,10 +89,13 @@ pub trait Trait: frame_system::Trait { type EthereumNetwork: Get; - type Call: Dispatchable + From> + IsSubType, Self> + Clone; + type Call: Dispatchable + From> + IsSubType> + Clone; type Currency: LockableCurrency + ReservableCurrency; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } decl_event! { @@ -750,6 +753,10 @@ impl EthereumReceipt> for Module { } } +// TODO: https://github.com/darwinia-network/darwinia-common/issues/209 +pub trait WeightInfo {} +impl WeightInfo for () {} + /// `SignedExtension` that checks if a transaction has duplicate header hash to avoid coincidence /// header between several relayers #[derive(Encode, Decode, Clone, Eq, PartialEq)] diff --git a/frame/bridge/ethereum/linear-relay/src/mock.rs b/frame/bridge/ethereum/linear-relay/src/mock.rs index 92e92c2dac..b8af9ea7b0 100644 --- a/frame/bridge/ethereum/linear-relay/src/mock.rs +++ b/frame/bridge/ethereum/linear-relay/src/mock.rs @@ -27,6 +27,21 @@ pub type Ring = darwinia_balances::Module; pub(crate) type RingError = darwinia_balances::Error; +thread_local! { + static ETH_NETWORK: RefCell = RefCell::new(EthereumNetworkType::Ropsten); +} + +impl_outer_origin! { + pub enum Origin for Test where system = frame_system {} +} + +impl_outer_dispatch! { + pub enum Call for Test where origin: Origin { + frame_system::System, + darwinia_ethereum_relay::EthereumRelay, + } +} + darwinia_support::impl_account_data! { pub struct AccountData for @@ -39,8 +54,64 @@ darwinia_support::impl_account_data! { } } -thread_local! { - static ETH_NETWORK: RefCell = RefCell::new(EthereumNetworkType::Ropsten); +// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct Test; +parameter_types! { + pub const EthereumRelayModuleId: ModuleId = ModuleId(*b"da/ethli"); +} +impl Trait for Test { + type ModuleId = EthereumRelayModuleId; + type Event = (); + type EthereumNetwork = EthereumNetwork; + type Call = Call; + type Currency = Ring; + type WeightInfo = (); +} + +parameter_types! { + pub const BlockHashCount: BlockNumber = 250; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} +impl frame_system::Trait for Test { + type BaseCallFilter = (); + type Origin = Origin; + type Call = Call; + type Index = u64; + type BlockNumber = BlockNumber; + type Hash = H256; + type Hashing = sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); + type BlockExecutionWeight = (); + type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + type ModuleToIndex = (); + type AccountData = AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); +} + +impl darwinia_balances::Trait for Test { + type Balance = Balance; + type DustRemoval = (); + type Event = (); + type ExistentialDeposit = (); + type BalanceInfo = AccountData; + type AccountStore = System; + type WeightInfo = (); + type DustCollector = (); } #[derive(Debug)] @@ -179,80 +250,9 @@ impl Get for EthereumNetwork { } } -// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct Test; - -parameter_types! { - pub const BlockHashCount: BlockNumber = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); -} -impl frame_system::Trait for Test { - type BaseCallFilter = (); - type Origin = Origin; - type Call = Call; - type Index = u64; - type BlockNumber = BlockNumber; - type Hash = H256; - type Hashing = sp_runtime::traits::BlakeTwo256; - type AccountId = AccountId; - type Lookup = IdentityLookup; - type Header = Header; - type Event = (); - type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; - type Version = (); - type ModuleToIndex = (); - type AccountData = AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); -} - -impl darwinia_balances::Trait for Test { - type Balance = Balance; - type DustRemoval = (); - type Event = (); - type ExistentialDeposit = (); - type BalanceInfo = AccountData; - type AccountStore = System; - type DustCollector = (); -} - -impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} -} - -impl_outer_dispatch! { - pub enum Call for Test where origin: Origin { - frame_system::System, - darwinia_ethereum_relay::EthereumRelay, - } -} - -parameter_types! { - pub const EthereumRelayModuleId: ModuleId = ModuleId(*b"da/ethli"); -} - -impl Trait for Test { - type ModuleId = EthereumRelayModuleId; - type Event = (); - type EthereumNetwork = EthereumNetwork; - type Call = Call; - type Currency = Ring; -} - pub struct ExtBuilder { eth_network: EthereumNetworkType, } - impl Default for ExtBuilder { fn default() -> Self { Self { @@ -260,7 +260,6 @@ impl Default for ExtBuilder { } } } - impl ExtBuilder { pub fn eth_network(mut self, eth_network: EthereumNetworkType) -> Self { self.eth_network = eth_network; @@ -273,7 +272,7 @@ impl ExtBuilder { pub fn build(self) -> sp_io::TestExternalities { self.set_associated_constants(); - let mut storage = system::GenesisConfig::default() + let mut storage = frame_system::GenesisConfig::default() .build_storage::() .unwrap(); diff --git a/frame/bridge/ethereum/offchain/Cargo.toml b/frame/bridge/ethereum/offchain/Cargo.toml index 156183804e..6e100c4f0a 100644 --- a/frame/bridge/ethereum/offchain/Cargo.toml +++ b/frame/bridge/ethereum/offchain/Cargo.toml @@ -19,11 +19,11 @@ ethereum-primitives = { default-features = false, path = "../../../../primitives # github rlp = { default-features = false, git = "https://github.com/darwinia-network/parity-common.git" } # substrate -frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-core = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-core = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [dev-dependencies] # crates @@ -32,8 +32,8 @@ serde_json = { version = "1.0.57" } darwinia-balances = { path = "../../../../frame/balances" } ethereum-primitives = { features = ["easy-testing"], path = "../../../../primitives/ethereum-primitives" } # substrate -sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-io = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-io = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [features] default = ["std"] diff --git a/frame/bridge/ethereum/offchain/src/lib.rs b/frame/bridge/ethereum/offchain/src/lib.rs index 3f9daef5c8..c2a103f53c 100644 --- a/frame/bridge/ethereum/offchain/src/lib.rs +++ b/frame/bridge/ethereum/offchain/src/lib.rs @@ -81,84 +81,6 @@ pub const ETH_OFFCHAIN: KeyTypeId = KeyTypeId(*b"etho"); /// A dummy endpoint, point this to shadow service const ETH_RESOURCE: &'static [u8] = b"http://shadow.darwinia.network/"; -#[derive(Default)] -pub struct OffchainRequest { - location: Vec, - payload: Vec, - redirect_times: u8, - cookie: Option>, -} - -pub trait OffchainRequestTrait { - fn send(&mut self) -> Option>; -} - -impl OffchainRequest { - fn new(url: Vec, payload: Vec) -> Self { - OffchainRequest { - location: url.clone(), - payload, - ..Default::default() - } - } -} - -/// The OffchainRequest handle the request session -/// - set cookie if returns -/// - handle the redirect actions if happened -#[cfg(not(test))] -impl OffchainRequestTrait for OffchainRequest { - fn send(&mut self) -> Option> { - for _ in 0..=3 { - let p = self.payload.clone(); - let request = sp_runtime::offchain::http::Request::post( - from_utf8(&self.location).unwrap_or_default(), - vec![&p[..]], - ) - .add_header("Content-Type", "application/json"); - if let Ok(pending) = request.send() { - if let Ok(mut resp) = pending.wait() { - if resp.code == 200 { - return Some(resp.body().collect::>()); - } else if resp.code == 301 || resp.code == 302 { - self.redirect_times += 1; - trace!( - target: "ethereum-offchain", - "[ethereum-offchain] Redirect({}), Request Header: {:?}", - self.redirect_times, resp.headers(), - ); - - let headers = resp.headers(); - if let Some(cookie) = headers.find("set-cookie") { - self.cookie = Some(cookie.as_bytes().to_vec()); - } - if let Some(location) = headers.find("location") { - self.location = location.as_bytes().to_vec(); - trace!( - target: "ethereum-offchain", - "[ethereum-offchain] Redirect({}), Location: {:?}", - self.redirect_times, - self.location, - ); - } - } else { - trace!(target: "ethereum-offchain", "[ethereum-offchain] Status Code: {}", resp.code); - trace!( - target: "ethereum-offchain", - "[ethereum-offchain] Response: {}", - from_utf8(&resp.body().collect::>()).unwrap_or_default(), - ); - - return None; - } - } - } - } - - None - } -} - pub trait Trait: CreateSignedTransaction> + darwinia_ethereum_linear_relay::Trait { @@ -394,3 +316,79 @@ impl Module { Ok(Decode::decode::<&[u8]>(&mut &proof_scale_bytes[..]).unwrap_or_default()) } } + +#[derive(Default)] +pub struct OffchainRequest { + location: Vec, + payload: Vec, + redirect_times: u8, + cookie: Option>, +} +impl OffchainRequest { + fn new(url: Vec, payload: Vec) -> Self { + OffchainRequest { + location: url.clone(), + payload, + ..Default::default() + } + } +} + +pub trait OffchainRequestTrait { + fn send(&mut self) -> Option>; +} +/// The OffchainRequest handle the request session +/// - set cookie if returns +/// - handle the redirect actions if happened +#[cfg(not(test))] +impl OffchainRequestTrait for OffchainRequest { + fn send(&mut self) -> Option> { + for _ in 0..=3 { + let p = self.payload.clone(); + let request = sp_runtime::offchain::http::Request::post( + from_utf8(&self.location).unwrap_or_default(), + vec![&p[..]], + ) + .add_header("Content-Type", "application/json"); + if let Ok(pending) = request.send() { + if let Ok(mut resp) = pending.wait() { + if resp.code == 200 { + return Some(resp.body().collect::>()); + } else if resp.code == 301 || resp.code == 302 { + self.redirect_times += 1; + trace!( + target: "ethereum-offchain", + "[ethereum-offchain] Redirect({}), Request Header: {:?}", + self.redirect_times, resp.headers(), + ); + + let headers = resp.headers(); + if let Some(cookie) = headers.find("set-cookie") { + self.cookie = Some(cookie.as_bytes().to_vec()); + } + if let Some(location) = headers.find("location") { + self.location = location.as_bytes().to_vec(); + trace!( + target: "ethereum-offchain", + "[ethereum-offchain] Redirect({}), Location: {:?}", + self.redirect_times, + self.location, + ); + } + } else { + trace!(target: "ethereum-offchain", "[ethereum-offchain] Status Code: {}", resp.code); + trace!( + target: "ethereum-offchain", + "[ethereum-offchain] Response: {}", + from_utf8(&resp.body().collect::>()).unwrap_or_default(), + ); + + return None; + } + } + } + } + + None + } +} diff --git a/frame/bridge/ethereum/offchain/src/mock.rs b/frame/bridge/ethereum/offchain/src/mock.rs index 19d9f668d0..107249c8c1 100644 --- a/frame/bridge/ethereum/offchain/src/mock.rs +++ b/frame/bridge/ethereum/offchain/src/mock.rs @@ -54,13 +54,16 @@ pub type _OffchainError = Error; static mut SHADOW_SERVICE: Option = None; -pub enum ShadowService { - Scale, - Json, -} - #[derive(Clone, Debug, Eq, PartialEq)] pub struct Test; +parameter_types! { + pub const FetchInterval: u64 = 3; +} +impl Trait for Test { + type AuthorityId = crypto::AuthorityId; + type FetchInterval = FetchInterval; +} + parameter_types! { pub const BlockHashCount: u64 = 250; pub const MaximumBlockWeight: Weight = 1024; @@ -92,6 +95,7 @@ impl frame_system::Trait for Test { type AccountData = AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl darwinia_balances::Trait for Test { @@ -102,6 +106,7 @@ impl darwinia_balances::Trait for Test { type BalanceInfo = AccountData; type AccountStore = System; type DustCollector = (); + type WeightInfo = (); } parameter_types! { @@ -114,14 +119,7 @@ impl darwinia_ethereum_linear_relay::Trait for Test { type EthereumNetwork = EthereumNetwork; type Call = Call; type Currency = Ring; -} - -parameter_types! { - pub const FetchInterval: u64 = 3; -} -impl Trait for Test { - type AuthorityId = crypto::AuthorityId; - type FetchInterval = FetchInterval; + type WeightInfo = (); } impl frame_system::offchain::SigningTypes for Test { @@ -154,7 +152,6 @@ where pub struct ExtBuilder { genesis_header: Option<(u64, Vec)>, } - impl Default for ExtBuilder { fn default() -> Self { Self { @@ -162,7 +159,6 @@ impl Default for ExtBuilder { } } } - impl ExtBuilder { pub fn set_genesis_header(mut self) -> Self { let genesis_header = EthHeader::from_str_unchecked(SUPPOSED_ETH_HEADER); @@ -197,6 +193,11 @@ impl OffchainRequestTrait for OffchainRequest { } } +pub enum ShadowService { + Scale, + Json, +} + pub(crate) fn set_shadow_service(s: Option) { unsafe { SHADOW_SERVICE = s; diff --git a/frame/bridge/ethereum/relay/Cargo.toml b/frame/bridge/ethereum/relay/Cargo.toml index 4828227bc9..9878541eac 100644 --- a/frame/bridge/ethereum/relay/Cargo.toml +++ b/frame/bridge/ethereum/relay/Cargo.toml @@ -25,11 +25,11 @@ ckb-merkle-mountain-range = { default-features = false, git= "https://github.com ethereum-types = { default-features = false, git = "https://github.com/darwinia-network/parity-common.git" } rlp = { default-features = false, git = "https://github.com/darwinia-network/parity-common.git" } # substrate -frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-core = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-core = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [dev-dependencies] # crates @@ -38,8 +38,8 @@ serde_json = { version = "1.0.57" } darwinia-balances = { path = "../../../../frame/balances" } ethereum-primitives = { features = ["easy-testing"], path = "../../../../primitives/ethereum-primitives" } # substrate -sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-io = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-io = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [features] default = ["std"] diff --git a/frame/bridge/ethereum/relay/src/lib.rs b/frame/bridge/ethereum/relay/src/lib.rs index 0e728e92f5..73b23be919 100644 --- a/frame/bridge/ethereum/relay/src/lib.rs +++ b/frame/bridge/ethereum/relay/src/lib.rs @@ -2,72 +2,6 @@ #![cfg_attr(not(feature = "std"), no_std)] -mod migration { - // --- substrate --- - use frame_support::migration::*; - // --- darwinia --- - use crate::*; - - pub fn migrate() { - sp_runtime::print("Migrating DarwiniaEthereumLinearRelay..."); - - let new_module: &[u8] = b"DarwiniaEthereumRelay"; - let old_module: &[u8] = b"DarwiniaEthRelay"; - let value_items: &[&[u8]] = &[ - // pub GenesisHeader get(fn begin_header): Option; - b"GenesisHeader", - // pub BestHeaderHash get(fn best_header_hash): H256; - b"BestHeaderHash", - // pub NumberOfBlocksFinality get(fn number_of_blocks_finality) config(): u64; - b"NumberOfBlocksFinality", - // pub NumberOfBlocksSafe get(fn number_of_blocks_safe) config(): u64; - b"NumberOfBlocksSafe", - // pub CheckAuthority get(fn check_authority) config(): bool = true; - b"CheckAuthority", - // pub Authorities get(fn authorities) config(): Vec; - b"Authorities", - // pub ReceiptVerifyFee get(fn receipt_verify_fee) config(): Balance; - b"ReceiptVerifyFee", - // pub TotalRelayerPoints get(fn total_points): u64 = 0; - b"TotalRelayerPoints", - ]; - let map_items: &[&[u8]] = &[ - // pub CanonicalHeaderHashes get(fn canonical_header_hash): map hasher(identity) u64 => H256; - b"CanonicalHeaderHashes", - // pub Headers get(fn header): map hasher(identity) H256 => Option; - b"Headers", - // pub HeaderBriefs get(fn header_brief): map hasher(identity) H256 => Option>; - b"HeaderBriefs", - // pub RelayerPoints get(fn relayer_points): map hasher(blake2_128_concat) T::AccountId => u64; - b"RelayerPoints", - ]; - let hash: &[u8] = &[]; - - for item in value_items { - // --- substrate --- - use frame_support::{storage::unhashed::kill, StorageHasher, Twox128}; - - let mut key = vec![0u8; 32 + hash.len()]; - key[0..16].copy_from_slice(&Twox128::hash(old_module)); - key[16..32].copy_from_slice(&Twox128::hash(item)); - key[32..].copy_from_slice(hash); - kill(&key); - } - for item in map_items { - remove_storage_prefix(old_module, item, hash); - } - - // pub DagsMerkleRoots get(fn dag_merkle_root): map hasher(identity) u64 => H128; - { - let item: &[u8] = b"DagsMerkleRoots"; - - for (hash, value) in >::new(old_module, item) { - put_storage_value(new_module, item, &hash, value); - } - } - } -} - mod mmr; #[cfg(test)] mod mock; @@ -82,7 +16,7 @@ mod types { pub type MMRHash = H256; pub type MMRProof = Vec; - type AccountId = ::AccountId; + type AccountId = ::AccountId; type CurrencyT = ::Currency; } @@ -96,7 +30,7 @@ use frame_support::{ traits::Get, traits::{Currency, ExistenceRequirement::KeepAlive, ReservableCurrency}, }; -use frame_system::{self as system, ensure_root, ensure_signed}; +use frame_system::{ensure_root, ensure_signed}; use sp_runtime::{ traits::AccountIdConversion, DispatchError, DispatchResult, ModuleId, RuntimeDebug, }; @@ -128,6 +62,9 @@ pub trait Trait: frame_system::Trait { type Currency: LockableCurrency + ReservableCurrency; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } decl_event! { @@ -135,23 +72,23 @@ decl_event! { where ::AccountId, { - PhantomEvent(AccountId), - /// The specific confirmed block is removed + /// The specific confirmed block is removed. [block height] RemoveConfirmedBlock(EthBlockNumber), - /// The range of confirmed blocks are removed + /// The range of confirmed blocks are removed. [block height, block height] RemoveConfirmedBlockRang(EthBlockNumber, EthBlockNumber), - /// The block confimed block parameters are changed + /// The block confimed block parameters are changed. [block height, block height] UpdateConfrimedBlockCleanCycle(EthBlockNumber, EthBlockNumber), - /// This Error event is caused by unreasonable Confirm block delete parameter set + /// This Error event is caused by unreasonable Confirm block delete parameter set. /// /// ConfirmBlockKeepInMonth should be greator then 1 to avoid the relayer game cross the - /// month + /// month. + /// [block height] ConfirmBlockManagementError(EthBlockNumber), - /// Receipt Verification + /// Receipt Verification. [account, receipt, header] VerifyReceipt(AccountId, Receipt, EthHeader), } } @@ -234,12 +171,6 @@ decl_module! { fn deposit_event() = default; - fn on_runtime_upgrade() -> frame_support::weights::Weight { - migration::migrate::(); - - 0 - } - /// Check and verify the receipt /// /// `check_receipt` will verify the validation of the ethereum receipt proof from ethereum. @@ -702,6 +633,10 @@ impl EthereumReceipt> for Module { } } +// TODO: https://github.com/darwinia-network/darwinia-common/issues/209 +pub trait WeightInfo {} +impl WeightInfo for () {} + #[derive(Encode, Decode, Default, RuntimeDebug)] pub struct EthHeaderThing { eth_header: EthHeader, diff --git a/frame/bridge/ethereum/relay/src/mock/mod.rs b/frame/bridge/ethereum/relay/src/mock/mod.rs index 67c7af6c4d..d160e9e63c 100644 --- a/frame/bridge/ethereum/relay/src/mock/mod.rs +++ b/frame/bridge/ethereum/relay/src/mock/mod.rs @@ -1,4 +1,5 @@ //! Mock file for ethereum-relay. + // --- crates --- use codec::Error; // --- substrate --- @@ -32,6 +33,17 @@ pub type KtonInstance = darwinia_balances::Instance1; pub type System = frame_system::Module; pub type EthereumRelay = Module; +pub type Ring = darwinia_balances::Module; + +impl_outer_origin! { + pub enum Origin for Test where system = frame_system {} +} + +impl_outer_dispatch! { + pub enum Call for Test where origin: Origin { + frame_system::System, + } +} darwinia_support::impl_account_data! { pub struct AccountData @@ -47,6 +59,15 @@ darwinia_support::impl_account_data! { // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Test; +parameter_types! { + pub const EthereumRelayModuleId: ModuleId = ModuleId(*b"da/ethrl"); +} +impl Trait for Test { + type ModuleId = EthereumRelayModuleId; + type Event = (); + type Currency = Ring; + type WeightInfo = (); +} parameter_types! { pub const BlockHashCount: BlockNumber = 250; @@ -79,6 +100,7 @@ impl frame_system::Trait for Test { type AccountData = AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl darwinia_balances::Trait for Test { @@ -88,41 +110,19 @@ impl darwinia_balances::Trait for Test { type ExistentialDeposit = (); type BalanceInfo = AccountData; type AccountStore = System; + type WeightInfo = (); type DustCollector = (); } -impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} -} - -impl_outer_dispatch! { - pub enum Call for Test where origin: Origin { - frame_system::System, - } -} - -parameter_types! { - pub const EthereumRelayModuleId: ModuleId = ModuleId(*b"da/ethrl"); -} - -pub type Ring = darwinia_balances::Module; -impl Trait for Test { - type ModuleId = EthereumRelayModuleId; - type Event = (); - type Currency = Ring; -} - pub struct ExtBuilder {} - impl Default for ExtBuilder { fn default() -> Self { Self {} } } - impl ExtBuilder { pub fn build(self) -> sp_io::TestExternalities { - let mut storage = system::GenesisConfig::default() + let mut storage = frame_system::GenesisConfig::default() .build_storage::() .unwrap(); diff --git a/frame/bridge/relayer-game/Cargo.toml b/frame/bridge/relayer-game/Cargo.toml index cd5082a185..c2b6b673c1 100644 --- a/frame/bridge/relayer-game/Cargo.toml +++ b/frame/bridge/relayer-game/Cargo.toml @@ -15,10 +15,10 @@ serde = { version = "1.0.114", optional = true } # darwinia darwinia-support = { default-features = false, path = "../../support" } # substrate -frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [dev-dependencies] # --- crates --- @@ -26,8 +26,8 @@ env_logger = { version = "0.7.1" } # --- darwinia --- darwinia-balances = { path = "../../balances" } # --- substrate --- -sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-io = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-io = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [features] default = ["std"] diff --git a/frame/bridge/relayer-game/src/lib.rs b/frame/bridge/relayer-game/src/lib.rs index 3008067aea..c919a09bc2 100644 --- a/frame/bridge/relayer-game/src/lib.rs +++ b/frame/bridge/relayer-game/src/lib.rs @@ -52,7 +52,7 @@ use frame_support::{ traits::{Currency, EnsureOrigin, ExistenceRequirement, Get, OnUnbalanced}, weights::Weight, }; -use frame_system::{self as system, ensure_signed}; +use frame_system::ensure_signed; use sp_runtime::{ traits::{SaturatedConversion, Saturating, Zero}, DispatchResult, RuntimeDebug, @@ -91,6 +91,9 @@ pub trait Trait: frame_system::Trait { type ApproveOrigin: EnsureOrigin; type RejectOrigin: EnsureOrigin; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } decl_event! { @@ -99,11 +102,10 @@ decl_event! { TcBlockNumber = TcBlockNumber, GameId = GameId>, { - /// A new round started. - /// GameId(MMR Last Leaf), Samples, MMR Members + /// A new round started. [game id, samples, mmr members] NewRound(GameId, Vec, Vec), - /// A game has been settled. + /// A game has been settled. [game id] GameOver(GameId), } } @@ -887,6 +889,10 @@ impl, I: Instance> Module { } } +// TODO: https://github.com/darwinia-network/darwinia-common/issues/209 +pub trait WeightInfo {} +impl WeightInfo for () {} + #[derive(Clone, Encode, Decode, RuntimeDebug)] pub struct Proposal { // TODO: Can this proposal submit by other relayers? diff --git a/frame/bridge/relayer-game/src/mock.rs b/frame/bridge/relayer-game/src/mock.rs index cfb2a02a02..9dc631016c 100644 --- a/frame/bridge/relayer-game/src/mock.rs +++ b/frame/bridge/relayer-game/src/mock.rs @@ -259,7 +259,7 @@ thread_local! { } impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } darwinia_support::impl_account_data! { @@ -292,6 +292,7 @@ impl Trait for Test { type ConfirmPeriod = ConfirmPeriod; type ApproveOrigin = EnsureRoot; type RejectOrigin = EnsureRoot; + type WeightInfo = (); } parameter_types! { @@ -326,6 +327,7 @@ impl frame_system::Trait for Test { type AccountData = AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { @@ -338,6 +340,7 @@ impl darwinia_balances::Trait for Test { type ExistentialDeposit = ExistentialDeposit; type BalanceInfo = AccountData; type AccountStore = System; + type WeightInfo = (); type DustCollector = (Kton,); } impl darwinia_balances::Trait for Test { @@ -347,6 +350,7 @@ impl darwinia_balances::Trait for Test { type ExistentialDeposit = ExistentialDeposit; type BalanceInfo = AccountData; type AccountStore = System; + type WeightInfo = (); type DustCollector = (Ring,); } diff --git a/frame/claims/Cargo.toml b/frame/claims/Cargo.toml index 0c9967523f..2e888f2307 100644 --- a/frame/claims/Cargo.toml +++ b/frame/claims/Cargo.toml @@ -17,11 +17,11 @@ serde_json = { version = "1.0.57", optional = true } array-bytes = { default-features = false, path = "../../primitives/array-bytes" } darwinia-support = { default-features = false, path = "../support" } # substrate -frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-io = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-io = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [dev-dependencies] # crates @@ -30,7 +30,7 @@ tiny-keccak = { version = "1.5.0" } # darwinia darwinia-balances = { path = "../balances" } # substrate -sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [features] default = ["std"] diff --git a/frame/claims/src/lib.rs b/frame/claims/src/lib.rs index 66d5b478ae..e0d03075ec 100644 --- a/frame/claims/src/lib.rs +++ b/frame/claims/src/lib.rs @@ -17,7 +17,7 @@ mod types { // TODO: support *KTON* // pub type KtonBalance = as Currency>>::Balance; - type AccountId = ::AccountId; + type AccountId = ::AccountId; type RingCurrency = ::RingCurrency; // TODO: support *KTON* // type KtonCurrency = ::KtonCurrency; @@ -33,7 +33,7 @@ use frame_support::{ traits::{Currency, ExistenceRequirement::KeepAlive, Get}, {decl_error, decl_event, decl_module, decl_storage}, }; -use frame_system::{self as system, ensure_none, ensure_root}; +use frame_system::{ensure_none, ensure_root}; use sp_io::{crypto::secp256k1_ecdsa_recover, hashing::keccak_256}; #[cfg(feature = "std")] use sp_runtime::traits::{SaturatedConversion, Zero}; @@ -50,41 +50,6 @@ use sp_std::prelude::*; use darwinia_support::balance::lock::*; use types::*; -#[repr(u8)] -enum ValidityError { - /// The signature is invalid. - InvalidSignature = 0, - /// The signer has no claim. - SignerHasNoClaim = 1, -} - -#[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug)] -pub enum OtherSignature { - Eth(EcdsaSignature), - Tron(EcdsaSignature), -} - -#[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug)] -pub enum OtherAddress { - Eth(AddressT), - Tron(AddressT), -} - -#[derive(Clone, Encode, Decode)] -pub struct EcdsaSignature(pub [u8; 65]); - -impl PartialEq for EcdsaSignature { - fn eq(&self, other: &Self) -> bool { - &self.0[..] == &other.0[..] - } -} - -impl sp_std::fmt::Debug for EcdsaSignature { - fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result { - write!(f, "EcdsaSignature({:?})", &self.0[..]) - } -} - pub trait Trait: frame_system::Trait { type Event: From> + Into<::Event>; @@ -106,7 +71,7 @@ decl_event!( ::AccountId, RingBalance = RingBalance, { - /// Someone claimed some *RING*s. + /// Someone claimed some *RING*s. [account, address, amount] Claimed(AccountId, AddressT, RingBalance), } ); @@ -403,6 +368,39 @@ impl sp_runtime::traits::ValidateUnsigned for Module { } } +#[repr(u8)] +enum ValidityError { + /// The signature is invalid. + InvalidSignature = 0, + /// The signer has no claim. + SignerHasNoClaim = 1, +} + +#[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug)] +pub enum OtherSignature { + Eth(EcdsaSignature), + Tron(EcdsaSignature), +} + +#[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug)] +pub enum OtherAddress { + Eth(AddressT), + Tron(AddressT), +} + +#[derive(Clone, Encode, Decode)] +pub struct EcdsaSignature(pub [u8; 65]); +impl PartialEq for EcdsaSignature { + fn eq(&self, other: &Self) -> bool { + &self.0[..] == &other.0[..] + } +} +impl sp_std::fmt::Debug for EcdsaSignature { + fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result { + write!(f, "EcdsaSignature({:?})", &self.0[..]) + } +} + /// Converts the given binary data into ASCII-encoded hex. It will be twice the length. fn to_ascii_hex(data: &[u8]) -> Vec { let mut r = Vec::with_capacity(data.len() * 2); @@ -499,6 +497,7 @@ mod tests { type AccountData = AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { @@ -511,6 +510,7 @@ mod tests { type ExistentialDeposit = ExistentialDeposit; type BalanceInfo = AccountData; type AccountStore = System; + type WeightInfo = (); type DustCollector = (); } diff --git a/frame/elections-phragmen/Cargo.toml b/frame/elections-phragmen/Cargo.toml index 64044ac19f..a2ba4164d3 100644 --- a/frame/elections-phragmen/Cargo.toml +++ b/frame/elections-phragmen/Cargo.toml @@ -15,11 +15,11 @@ serde = { version = "1.0.114", optional = true } # darwinia darwinia-support = { default-features = false, path = "../support" } # substrate -frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-npos-elections = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-npos-elections = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [dev-dependencies] # crates @@ -27,9 +27,9 @@ hex-literal = { version = "0.3.1" } # darwinia darwinia-balances = { path = "../balances" } # substrate -sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-io = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -substrate-test-utils = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-io = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +substrate-test-utils = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [features] default = ["std"] diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index c09b8c5bff..4e48b7ec55 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -83,7 +83,7 @@ use frame_support::{ Weight, }, }; -use frame_system::{self as system, ensure_root, ensure_signed}; +use frame_system::{ensure_root, ensure_signed}; use sp_npos_elections::{build_support_map, ElectionResult, ExtendedBalance, VoteWeight}; use sp_runtime::{ traits::{Convert, StaticLookup, Zero}, @@ -125,6 +125,63 @@ pub struct DefunctVoter { pub candidate_count: u32, } +pub trait WeightInfo { + fn vote(u: u32) -> Weight; + fn vote_update(u: u32) -> Weight; + fn remove_voter(u: u32) -> Weight; + fn report_defunct_voter_correct(c: u32, v: u32) -> Weight; + fn report_defunct_voter_incorrect(c: u32, v: u32) -> Weight; + fn submit_candidacy(c: u32) -> Weight; + fn renounce_candidacy_candidate(c: u32) -> Weight; + fn renounce_candidacy_member_runner_up(u: u32) -> Weight; + fn remove_member_without_replacement(c: u32) -> Weight; + fn remove_member_with_replacement(u: u32) -> Weight; + fn remove_member_wrong_refund(u: u32) -> Weight; + fn on_initialize(c: u32) -> Weight; + fn phragmen(c: u32, v: u32, e: u32) -> Weight; +} +impl WeightInfo for () { + fn vote(_u: u32) -> Weight { + 1_000_000_000 + } + fn vote_update(_u: u32) -> Weight { + 1_000_000_000 + } + fn remove_voter(_u: u32) -> Weight { + 1_000_000_000 + } + fn report_defunct_voter_correct(_c: u32, _v: u32) -> Weight { + 1_000_000_000 + } + fn report_defunct_voter_incorrect(_c: u32, _v: u32) -> Weight { + 1_000_000_000 + } + fn submit_candidacy(_c: u32) -> Weight { + 1_000_000_000 + } + fn renounce_candidacy_candidate(_c: u32) -> Weight { + 1_000_000_000 + } + fn renounce_candidacy_member_runner_up(_u: u32) -> Weight { + 1_000_000_000 + } + fn remove_member_without_replacement(_c: u32) -> Weight { + 1_000_000_000 + } + fn remove_member_with_replacement(_u: u32) -> Weight { + 1_000_000_000 + } + fn remove_member_wrong_refund(_u: u32) -> Weight { + 1_000_000_000 + } + fn on_initialize(_c: u32) -> Weight { + 1_000_000_000 + } + fn phragmen(_c: u32, _v: u32, _e: u32) -> Weight { + 1_000_000_000 + } +} + pub trait Trait: frame_system::Trait { /// The overarching event type.c type Event: From> + Into<::Event>; @@ -172,6 +229,9 @@ pub trait Trait: frame_system::Trait { /// round will happen. If set to zero, no elections are ever triggered and the module will /// be in passive mode. type TermDuration: Get; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } decl_storage! { @@ -662,7 +722,7 @@ decl_event!( Balance = BalanceOf, ::AccountId, { - /// A new term with new members. This indicates that enough candidates existed to run the + /// A new term with [new_members]. This indicates that enough candidates existed to run the /// election, not that enough have has been elected. The inner value must be examined for /// this purpose. A `NewTerm([])` indicates that some candidates got their bond slashed and /// none were elected, whilst `EmptyTerm` means that no candidates existed to begin with. @@ -670,13 +730,13 @@ decl_event!( /// No (or not enough) candidates existed for this round. This is different from /// `NewTerm([])`. See the description of `NewTerm`. EmptyTerm, - /// A member has been removed. This should always be followed by either `NewTerm` ot + /// A [member] has been removed. This should always be followed by either `NewTerm` ot /// `EmptyTerm`. MemberKicked(AccountId), - /// A member has renounced their candidacy. + /// A [member] has renounced their candidacy. MemberRenounced(AccountId), - /// A voter (first element) was reported (byt the second element) with the the report being - /// successful or not (third element). + /// A voter was reported with the the report being successful or not. + /// [voter, reporter, success] VoterReported(AccountId, AccountId, bool), } ); @@ -1130,6 +1190,7 @@ mod tests { type AccountData = AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { @@ -1142,6 +1203,7 @@ mod tests { type ExistentialDeposit = ExistentialDeposit; type BalanceInfo = AccountData; type AccountStore = frame_system::Module; + type WeightInfo = (); type DustCollector = (); } @@ -1260,6 +1322,7 @@ mod tests { type DesiredMembers = DesiredMembers; type DesiredRunnersUp = DesiredRunnersUp; type TermDuration = TermDuration; + type WeightInfo = (); } pub type Block = sp_runtime::generic::Block; diff --git a/frame/header-mmr/Cargo.toml b/frame/header-mmr/Cargo.toml index a2a9ab0619..73a31fcbb3 100644 --- a/frame/header-mmr/Cargo.toml +++ b/frame/header-mmr/Cargo.toml @@ -18,10 +18,10 @@ darwinia-support = { default-features = false, path = "../support" } # github merkle-mountain-range = { package = "ckb-merkle-mountain-range", default-features = false, git = "https://github.com/darwinia-network/merkle-mountain-range.git" } # substrate -frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [dev-dependencies] # crates @@ -29,8 +29,8 @@ serde_json = { version = "1.0.57" } # darwinia array-bytes = { path = "../../primitives/array-bytes" } # substrate -sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-io = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-io = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [features] default = ["std"] diff --git a/frame/header-mmr/rpc/Cargo.toml b/frame/header-mmr/rpc/Cargo.toml index c3fed9d470..55c562251a 100644 --- a/frame/header-mmr/rpc/Cargo.toml +++ b/frame/header-mmr/rpc/Cargo.toml @@ -17,6 +17,6 @@ jsonrpc-derive = "14.2.1" # darwinia darwinia-header-mmr-rpc-runtime-api = { path = "./runtime-api" } # substrate -sp-api = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-blockchain = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +sp-api = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-blockchain = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } diff --git a/frame/header-mmr/rpc/runtime-api/Cargo.toml b/frame/header-mmr/rpc/runtime-api/Cargo.toml index 448daebb3e..f76fc427e5 100644 --- a/frame/header-mmr/rpc/runtime-api/Cargo.toml +++ b/frame/header-mmr/rpc/runtime-api/Cargo.toml @@ -15,9 +15,9 @@ serde = { version = "1.0.114", optional = true, features = ["derive"] } # darwinia darwinia-support = { default-features = false, path = "../../../support" } # substrate -sp-api = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +sp-api = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [features] default = ["std"] diff --git a/frame/header-mmr/src/mock.rs b/frame/header-mmr/src/mock.rs index 3a84574306..74cdc5d514 100644 --- a/frame/header-mmr/src/mock.rs +++ b/frame/header-mmr/src/mock.rs @@ -12,7 +12,7 @@ use sp_runtime::{testing::Header, traits::IdentityLookup, DigestItem, Perbill}; use crate::*; impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } // --- substrate --- @@ -58,6 +58,7 @@ impl frame_system::Trait for Test { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } pub fn new_test_ext() -> sp_io::TestExternalities { diff --git a/frame/header-mmr/src/tests.rs b/frame/header-mmr/src/tests.rs index 86633d3332..da51d7bade 100644 --- a/frame/header-mmr/src/tests.rs +++ b/frame/header-mmr/src/tests.rs @@ -4,10 +4,7 @@ // --- substrate --- use frame_support::traits::OnFinalize; -use sp_runtime::{ - testing::{Digest, H256}, - traits::Header, -}; +use sp_runtime::testing::{Digest, H256}; // --- darwinia --- use crate::{mock::*, *}; diff --git a/frame/staking/Cargo.toml b/frame/staking/Cargo.toml index 36cfb1e2f2..dc6958245e 100644 --- a/frame/staking/Cargo.toml +++ b/frame/staking/Cargo.toml @@ -19,16 +19,16 @@ static_assertions = { version = "1.1.0" } darwinia-staking-rpc-runtime-api = { default-features = false, path = "./rpc/runtime-api" } darwinia-support = { default-features = false, path = "../support" } # substrate -frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-authorship = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -pallet-session = { default-features = false, features = ["historical"], git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-core = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-io = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-npos-elections = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-staking = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-authorship = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +pallet-session = { default-features = false, features = ["historical"], git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-core = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-io = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-npos-elections = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-staking = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [dev-dependencies] # crates @@ -38,9 +38,9 @@ rand_chacha = { version = "0.2" } darwinia-balances = { path = "../../frame/balances" } darwinia-support = { features = ["easy-testing"], path = "../support" } # substrate -pallet-timestamp = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-storage = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -substrate-test-utils = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +pallet-timestamp = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-storage = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +substrate-test-utils = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [features] default = ["std"] diff --git a/frame/staking/rpc/Cargo.toml b/frame/staking/rpc/Cargo.toml index 0653a30ec9..b38f4576fb 100644 --- a/frame/staking/rpc/Cargo.toml +++ b/frame/staking/rpc/Cargo.toml @@ -17,6 +17,6 @@ jsonrpc-derive = "14.2.1" # darwinia darwinia-staking-rpc-runtime-api = { path = "./runtime-api" } # substrate -sp-api = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-blockchain = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +sp-api = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-blockchain = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } diff --git a/frame/staking/rpc/runtime-api/Cargo.toml b/frame/staking/rpc/runtime-api/Cargo.toml index 2cfb9aabe2..7c517a74f8 100644 --- a/frame/staking/rpc/runtime-api/Cargo.toml +++ b/frame/staking/rpc/runtime-api/Cargo.toml @@ -15,8 +15,8 @@ serde = { version = "1.0.114", optional = true, features = ["derive"] } # darwinia darwinia-support = { default-features = false, path = "../../../support" } # substrate -sp-api = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +sp-api = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [features] default = ["std"] diff --git a/frame/staking/src/darwinia_tests.rs b/frame/staking/src/darwinia_tests.rs index 52b462585c..88be297252 100644 --- a/frame/staking/src/darwinia_tests.rs +++ b/frame/staking/src/darwinia_tests.rs @@ -119,6 +119,48 @@ fn kton_should_reward_even_does_not_own_kton_before() { }); } +#[test] +fn migration_should_fix_broken_ledger() { + let mut s = sp_storage::Storage::default(); + let id: mock::AccountId = 777; + let mut broken_ledger = + StakingLedger:: { + stash: id, + active_ring: 500, + active_deposit_ring: 1000, + deposit_items: vec![TimeDepositItem { + value: 1000, + start_time: 0, + expire_time: 1, + }], + ring_staking_lock: StakingLock { + staking_amount: 500, + unbondings: vec![], + }, + ..Default::default() + }; + let data = vec![( + >::hashed_key_for(id), + broken_ledger.encode().to_vec(), + )]; + + s.top = data.into_iter().collect(); + sp_io::TestExternalities::new(s).execute_with(|| { + let _ = Ring::deposit_creating(&id, 200); + + assert_eq!(Staking::ledger(&id).unwrap(), broken_ledger); + + crate::migration::migrate::(); + + broken_ledger.active_ring = 200; + broken_ledger.active_deposit_ring = 200; + broken_ledger.deposit_items[0].value = 200; + broken_ledger.ring_staking_lock.staking_amount = 200; + + assert_eq!(Staking::ledger(&id).unwrap(), broken_ledger); + }); +} + #[cfg(feature = "backup")] mod backup { /// gen_paired_account!(a(1), b(2), m(12)); diff --git a/frame/staking/src/inflation.rs b/frame/staking/src/inflation.rs index 38431eafc9..235dfdd650 100644 --- a/frame/staking/src/inflation.rs +++ b/frame/staking/src/inflation.rs @@ -1,6 +1,7 @@ // --- crates --- use num_integer::Roots; // --- substrate --- +use frame_support::debug::*; use sp_core::U256; use sp_runtime::{Perbill, Perquintill}; use sp_std::convert::TryInto; @@ -26,6 +27,15 @@ pub fn compute_total_payout( // Milliseconds per year for the Julian year (365.25 days). const MILLISECONDS_PER_YEAR: TsInMs = ((36525 * 24 * 60 * 60) / 100) * 1000; + info!( + target: "darwinia-staking", + "era_duration: {}, living_time: {}, total_left: {:?}, payout_fraction: {:?}", + era_duration, + living_time, + total_left, + payout_fraction, + ); + let maximum = { let maximum = { let portion = diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index e048b5f6c9..ac06c87bf7 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -133,7 +133,7 @@ //! //! ``` //! use frame_support::{decl_module, dispatch}; -//! use frame_system::{self as system, ensure_signed}; +//! use frame_system::ensure_signed; //! use darwinia_staking as staking; //! //! pub trait Trait: staking::Trait {} @@ -271,12 +271,7 @@ mod migration { // pub Ledger get(fn ledger): map hasher(blake2_128_concat) T::AccountId => Option>; let item: &[u8] = b"Ledger"; - for (hash, value) in >>>::new(module, item) { - if value.is_none() { - continue; - } - - let mut value = value.unwrap(); + for (hash, mut value) in >>::new(module, item) { let StakingLedger { stash, active_ring, @@ -501,9 +496,7 @@ use frame_support::{ Weight, }, }; -use frame_system::{ - self as system, ensure_none, ensure_root, ensure_signed, offchain::SendTransactionTypes, -}; +use frame_system::{ensure_none, ensure_root, ensure_signed, offchain::SendTransactionTypes}; use sp_npos_elections::{ build_support_map, evaluate_support, generate_compact_solution_type, is_score_better, seq_phragmen, Assignment, ElectionResult as PrimitiveElectionResult, ElectionScore, @@ -565,598 +558,124 @@ const MONTH_IN_MINUTES: TsInMs = 30 * 24 * 60; const MONTH_IN_MILLISECONDS: TsInMs = MONTH_IN_MINUTES * 60 * 1000; const STAKING_ID: LockIdentifier = *b"da/staki"; -// --- enum --- +pub trait Trait: frame_system::Trait + SendTransactionTypes> { + /// The overarching event type. + type Event: From> + Into<::Event>; -/// Indicates the initial status of the staker. -#[derive(RuntimeDebug)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub enum StakerStatus { - /// Chilling. - Idle, - /// Declared desire in validating or already participating in it. - Validator, - /// Nominating for a group of other stakers. - Nominator(Vec), -} + /// Time used for computing era duration. + /// + /// It is guaranteed to start being called from the first `on_finalize`. Thus value at genesis + /// is not used. + type UnixTime: UnixTime; -/// A destination account for payment. -#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, RuntimeDebug)] -pub enum RewardDestination { - /// Pay into the stash account, increasing the amount at stake accordingly. - Staked { promise_month: u8 }, - /// Pay into the stash account, not increasing the amount at stake. - Stash, - /// Pay into the controller account. - Controller, -} + /// Number of sessions per era. + type SessionsPerEra: Get; -impl Default for RewardDestination { - fn default() -> Self { - RewardDestination::Staked { promise_month: 0 } - } -} + /// Number of eras that staked funds must remain bonded for. + type BondingDurationInEra: Get; + /// Number of eras that staked funds must remain bonded for. + type BondingDurationInBlockNumber: Get; -/// Mode of era-forcing. -#[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub enum Forcing { - /// Not forcing anything - just let whatever happen. - NotForcing, - /// Force a new era, then reset to `NotForcing` as soon as it is done. - ForceNew, - /// Avoid a new era indefinitely. - ForceNone, - /// Force a new era at the end of all sessions indefinitely. - ForceAlways, -} + /// Number of eras that slashes are deferred by, after computation. + /// + /// This should be less than the bonding duration. Set to 0 if slashes + /// should be applied immediately, without opportunity for intervention. + type SlashDeferDuration: Get; -impl Default for Forcing { - fn default() -> Self { - Forcing::NotForcing - } -} + /// The origin which can cancel a deferred slash. Root can always do this. + type SlashCancelOrigin: EnsureOrigin; -/// Indicate how an election round was computed. -#[derive(PartialEq, Eq, Clone, Copy, Encode, Decode, RuntimeDebug)] -pub enum ElectionCompute { - /// Result was forcefully computed on chain at the end of the session. - OnChain, - /// Result was submitted and accepted to the chain via a signed transaction. - Signed, - /// Result was submitted and accepted to the chain via an unsigned transaction (by an - /// authority). - Unsigned, -} + /// Interface for interacting with a session module. + type SessionInterface: self::SessionInterface; -/// The status of the upcoming (offchain) election. -#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] -pub enum ElectionStatus { - /// Nothing has and will happen for now. submission window is not open. - Closed, - /// The submission window has been open since the contained block number. - Open(BlockNumber), -} + /// Something that can estimate the next session change, accurately or as a best effort guess. + type NextNewSession: EstimateNextNewSession; -impl ElectionStatus { - fn is_open_at(&self, n: BlockNumber) -> bool { - *self == Self::Open(n) - } + /// The number of blocks before the end of the era from which election submissions are allowed. + /// + /// Setting this to zero will disable the offchain compute and only on-chain seq-phragmen will + /// be used. + /// + /// This is bounded by being within the last session. Hence, setting it to a value more than the + /// length of a session will be pointless. + type ElectionLookahead: Get; - fn is_closed(&self) -> bool { - match self { - Self::Closed => true, - _ => false, - } - } + /// The overarching call type. + type Call: Dispatchable + From> + IsSubType> + Clone; - fn is_open(&self) -> bool { - !self.is_closed() - } -} + /// Maximum number of balancing iterations to run in the offchain submission. + /// + /// If set to 0, balance_solution will not be executed at all. + type MaxIterations: Get; -impl Default for ElectionStatus { - fn default() -> Self { - Self::Closed - } -} + /// The threshold of improvement that should be provided for a new solution to be accepted. + type MinSolutionScoreBump: Get; -/// To unify *RING* and *KTON* balances. -#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] -pub enum StakingBalance -where - RingBalance: HasCompact, - KtonBalance: HasCompact, -{ - RingBalance(RingBalance), - KtonBalance(KtonBalance), -} + /// The maximum number of nominators rewarded for each validator. + /// + /// For each validator only the `$MaxNominatorRewardedPerValidator` biggest stakers can claim + /// their reward. This used to limit the i/o cost for the nominator payout. + type MaxNominatorRewardedPerValidator: Get; -impl Default for StakingBalance -where - RingBalance: Default + HasCompact, - KtonBalance: Default + HasCompact, -{ - fn default() -> Self { - StakingBalance::RingBalance(Default::default()) - } -} + /// A configuration for base priority of unsigned transactions. + /// + /// This is exposed so that it can be tuned for particular runtime, when + /// multiple pallets send unsigned transactions. + type UnsignedPriority: Get; -// --- struct --- + /// The *RING* currency. + type RingCurrency: LockableCurrency; + /// Tokens have been minted and are unused for validator-reward. + /// See [Era payout](./index.html#era-payout). + type RingRewardRemainder: OnUnbalanced>; + /// Handler for the unbalanced *RING* reduction when slashing a staker. + type RingSlash: OnUnbalanced>; + /// Handler for the unbalanced *RING* increment when rewarding a staker. + type RingReward: OnUnbalanced>; -/// Information regarding the active era (era in used in session). -#[derive(Debug, Encode, Decode)] -pub struct ActiveEraInfo { - /// Index of era. - pub index: EraIndex, - /// Moment of start expressed as millisecond from `$UNIX_EPOCH`. - /// - /// Start can be none if start hasn't been set for the era yet, - /// Start is set on the first on_finalize of the era to guarantee usage of `Time`. - start: Option, -} + /// The *KTON* currency. + type KtonCurrency: LockableCurrency; + // FIXME: Ugly hack due to https://github.com/rust-lang/rust/issues/31844#issuecomment-557918823 + /// Handler for the unbalanced *KTON* reduction when slashing a staker. + type KtonSlash: OnUnbalancedKton>; + /// Handler for the unbalanced *KTON* increment when rewarding a staker. + type KtonReward: OnUnbalanced>; -/// Reward points of an era. Used to split era total payout between validators. -/// -/// This points will be used to reward validators and their respective nominators. -#[derive(PartialEq, Encode, Decode, Default, Debug)] -pub struct EraRewardPoints { - /// Total number of points. Equals the sum of reward points for each validator. - total: RewardPoint, - /// The reward points earned by a given validator. - individual: BTreeMap, -} + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; -/// Preference of what happens regarding validation. -#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] -pub struct ValidatorPrefs { - /// Reward that validator takes up-front; only the rest is split between themselves and - /// nominators. - #[codec(compact)] - pub commission: Perbill, + // TODO: doc + type Cap: Get>; + // TODO: doc + type TotalPower: Get; } -impl Default for ValidatorPrefs { - fn default() -> Self { - ValidatorPrefs { - commission: Default::default(), - } - } -} +decl_storage! { + trait Store for Module as DarwiniaStaking { + /// Number of eras to keep in history. + /// + /// Information is kept for eras in `[current_era - history_depth; current_era]`. + /// + /// Must be more than the number of eras delayed by session otherwise. I.e. active era must + /// always be in history. I.e. `active_era > current_era - history_depth` must be + /// guaranteed. + HistoryDepth get(fn history_depth) config(): u32 = 336; -/// The ledger of a (bonded) stash. -#[derive(PartialEq, Eq, Clone, Default, Encode, Decode, RuntimeDebug)] -pub struct StakingLedger -where - RingBalance: HasCompact, - KtonBalance: HasCompact, -{ - /// The stash account whose balance is actually locked and at stake. - pub stash: AccountId, + /// The ideal number of staking participants. + pub ValidatorCount get(fn validator_count) config(): u32; - /// The total amount of the stash's *RING* that will be at stake in any forthcoming - /// rounds. - #[codec(compact)] - pub active_ring: RingBalance, - // active time-deposit ring - #[codec(compact)] - pub active_deposit_ring: RingBalance, + /// Minimum number of staking participants before emergency conditions are imposed. + pub MinimumValidatorCount + get(fn minimum_validator_count) config() + : u32 = DEFAULT_MINIMUM_VALIDATOR_COUNT; - /// The total amount of the stash's *KTON* that will be at stake in any forthcoming - /// rounds. - #[codec(compact)] - pub active_kton: KtonBalance, + /// Any validators that may never be slashed or forcibly kicked. It's a Vec since they're + /// easy to initialize and the performance hit is minimal (we expect no more than four + /// invulnerables) and restricted to testnets. + pub Invulnerables get(fn invulnerables) config(): Vec; - // If you deposit *RING* for a minimum period, - // you can get *KTON* as bonus which can also be used for staking. - pub deposit_items: Vec>, - - // TODO doc - pub ring_staking_lock: StakingLock, - // TODO doc - pub kton_staking_lock: StakingLock, - - /// List of eras for which the stakers behind a validator have claimed rewards. Only updated - /// for validators. - pub claimed_rewards: Vec, -} - -impl - StakingLedger -where - RingBalance: AtLeast32BitUnsigned + Saturating + Copy, - KtonBalance: AtLeast32BitUnsigned + Saturating + Copy, - BlockNumber: PartialOrd, - TsInMs: PartialOrd, -{ - /// Slash the validator for a given amount of balance. This can grow the value - /// of the slash in the case that the validator has less than `minimum_balance` - /// active funds. Returns the amount of funds actually slashed. - /// - /// Slashes from `active` funds first, and then `unlocking`, starting with the - /// chunks that are closest to unlocking. - fn slash( - &mut self, - slash_ring: RingBalance, - slash_kton: KtonBalance, - bn: BlockNumber, - ts: TsInMs, - ) -> (RingBalance, KtonBalance) { - let slash_out_of = |active_ring: &mut RingBalance, - active_deposit_ring: &mut RingBalance, - deposit_item: &mut Vec>, - active_kton: &mut KtonBalance, - slash_ring: &mut RingBalance, - slash_kton: &mut KtonBalance| { - let slashable_active_ring = (*slash_ring).min(*active_ring); - let slashable_active_kton = (*slash_kton).min(*active_kton); - - if !slashable_active_ring.is_zero() { - let slashable_normal_ring = *active_ring - *active_deposit_ring; - if let Some(mut slashable_deposit_ring) = - slashable_active_ring.checked_sub(&slashable_normal_ring) - { - *active_deposit_ring -= slashable_deposit_ring; - - deposit_item.drain_filter(|item| { - if ts >= item.expire_time { - true - } else { - if slashable_deposit_ring.is_zero() { - false - } else { - if let Some(new_slashable_deposit_ring) = - slashable_deposit_ring.checked_sub(&item.value) - { - slashable_deposit_ring = new_slashable_deposit_ring; - true - } else { - item.value -= sp_std::mem::replace( - &mut slashable_deposit_ring, - Zero::zero(), - ); - false - } - } - } - }); - } - - *active_ring -= slashable_active_ring; - *slash_ring -= slashable_active_ring; - } - - if !slashable_active_kton.is_zero() { - *active_kton -= slashable_active_kton; - *slash_kton -= slashable_active_kton; - } - }; - - let (mut apply_slash_ring, mut apply_slash_kton) = (slash_ring, slash_kton); - let StakingLedger { - active_ring, - active_deposit_ring, - deposit_items, - active_kton, - ring_staking_lock, - kton_staking_lock, - .. - } = self; - - slash_out_of( - active_ring, - active_deposit_ring, - deposit_items, - active_kton, - &mut apply_slash_ring, - &mut apply_slash_kton, - ); - - if !apply_slash_ring.is_zero() { - ring_staking_lock.unbondings.drain_filter(|lock| { - if bn >= lock.until { - true - } else { - if apply_slash_ring.is_zero() { - false - } else { - if apply_slash_ring > lock.amount { - apply_slash_ring -= lock.amount; - true - } else { - lock.amount -= - sp_std::mem::replace(&mut apply_slash_ring, Zero::zero()); - false - } - } - } - }); - } - if !apply_slash_kton.is_zero() { - kton_staking_lock.unbondings.drain_filter(|lock| { - if bn >= lock.until { - true - } else { - if apply_slash_kton.is_zero() { - false - } else { - if apply_slash_kton > lock.amount { - apply_slash_kton -= lock.amount; - - true - } else { - lock.amount -= - sp_std::mem::replace(&mut apply_slash_kton, Zero::zero()); - false - } - } - } - }); - } - - (slash_ring - apply_slash_ring, slash_kton - apply_slash_kton) - } -} - -/// The *RING* under deposit. -#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] -pub struct TimeDepositItem { - #[codec(compact)] - pub value: RingBalance, - #[codec(compact)] - pub start_time: TsInMs, - #[codec(compact)] - pub expire_time: TsInMs, -} - -/// A record of the nominations made by a specific account. -#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] -pub struct Nominations { - /// The targets of nomination. - pub targets: Vec, - /// The era the nominations were submitted. - /// - /// Except for initial nominations which are considered submitted at era 0. - pub submitted_in: EraIndex, - /// Whether the nominations have been suppressed. - pub suppressed: bool, -} - -/// A snapshot of the stake backing a single validator in the system. -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, RuntimeDebug)] -pub struct Exposure -where - RingBalance: HasCompact, - KtonBalance: HasCompact, -{ - /// The validator's own stash that is exposed. - #[codec(compact)] - pub own_ring_balance: RingBalance, - #[codec(compact)] - pub own_kton_balance: KtonBalance, - pub own_power: Power, - /// The total balance backing this validator. - pub total_power: Power, - /// The portions of nominators stashes that are exposed. - pub others: Vec>, -} - -/// The amount of exposure (to slashing) than an individual nominator has. -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, RuntimeDebug)] -pub struct IndividualExposure -where - RingBalance: HasCompact, - KtonBalance: HasCompact, -{ - /// The stash account of the nominator in question. - who: AccountId, - /// Amount of funds exposed. - #[codec(compact)] - ring_balance: RingBalance, - #[codec(compact)] - kton_balance: KtonBalance, - power: Power, -} - -/// A pending slash record. The value of the slash has been computed but not applied yet, -/// rather deferred for several eras. -#[derive(Encode, Decode, Default, RuntimeDebug)] -pub struct UnappliedSlash { - /// The stash ID of the offending validator. - validator: AccountId, - /// The validator's own slash. - own: slashing::RK, - /// All other slashed stakers and amounts. - others: Vec<(AccountId, slashing::RK)>, - /// Reporters of the offence; bounty payout recipients. - reporters: Vec, - /// The amount of payout. - payout: slashing::RK, -} - -/// Some indications about the size of the election. This must be submitted with the solution. -/// -/// Note that these values must reflect the __total__ number, not only those that are present in the -/// solution. In short, these should be the same size as the size of the values dumped in -/// `SnapshotValidators` and `SnapshotNominators`. -#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, Default)] -pub struct ElectionSize { - /// Number of validators in the snapshot of the current election round. - #[codec(compact)] - pub validators: ValidatorIndex, - /// Number of nominators in the snapshot of the current election round. - #[codec(compact)] - pub nominators: NominatorIndex, -} - -/// The result of an election round. -#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] -pub struct ElectionResult { - /// Flat list of validators who have been elected. - elected_stashes: Vec, - /// Flat list of new exposures, to be updated in the [`Exposure`] storage. - exposures: Vec<(AccountId, Exposure)>, - /// Type of the result. This is kept on chain only to track and report the best score's - /// submission type. An optimisation could remove this. - compute: ElectionCompute, -} - -// --- trait --- - -/// Means for interacting with a specialized version of the `session` trait. -/// -/// This is needed because `Staking` sets the `ValidatorIdOf` of the `pallet_session::Trait` -pub trait SessionInterface: frame_system::Trait { - /// Disable a given validator by stash ID. - /// - /// Returns `true` if new era should be forced at the end of this session. - /// This allows preventing a situation where there is too many validators - /// disabled and block production stalls. - fn disable_validator(validator: &AccountId) -> Result; - /// Get the validators from session. - fn validators() -> Vec; - /// Prune historical session tries up to but not including the given index. - fn prune_historical_up_to(up_to: SessionIndex); -} - -impl SessionInterface> for T -where - T: pallet_session::Trait>, - T: pallet_session::historical::Trait< - FullIdentification = Exposure, RingBalance, KtonBalance>, - FullIdentificationOf = ExposureOf, - >, - T::SessionHandler: pallet_session::SessionHandler>, - T::SessionManager: pallet_session::SessionManager>, - T::ValidatorIdOf: Convert, Option>>, -{ - fn disable_validator(validator: &AccountId) -> Result { - >::disable(validator) - } - - fn validators() -> Vec> { - >::validators() - } - - fn prune_historical_up_to(up_to: SessionIndex) { - >::prune_up_to(up_to); - } -} - -pub trait Trait: frame_system::Trait + SendTransactionTypes> { - /// The overarching event type. - type Event: From> + Into<::Event>; - - /// Time used for computing era duration. - /// - /// It is guaranteed to start being called from the first `on_finalize`. Thus value at genesis - /// is not used. - type UnixTime: UnixTime; - - /// Number of sessions per era. - type SessionsPerEra: Get; - - /// Number of eras that staked funds must remain bonded for. - type BondingDurationInEra: Get; - /// Number of eras that staked funds must remain bonded for. - type BondingDurationInBlockNumber: Get; - - /// Number of eras that slashes are deferred by, after computation. - /// - /// This should be less than the bonding duration. Set to 0 if slashes - /// should be applied immediately, without opportunity for intervention. - type SlashDeferDuration: Get; - - /// The origin which can cancel a deferred slash. Root can always do this. - type SlashCancelOrigin: EnsureOrigin; - - /// Interface for interacting with a session module. - type SessionInterface: self::SessionInterface; - - /// Something that can estimate the next session change, accurately or as a best effort guess. - type NextNewSession: EstimateNextNewSession; - - /// The number of blocks before the end of the era from which election submissions are allowed. - /// - /// Setting this to zero will disable the offchain compute and only on-chain seq-phragmen will - /// be used. - /// - /// This is bounded by being within the last session. Hence, setting it to a value more than the - /// length of a session will be pointless. - type ElectionLookahead: Get; - - /// The overarching call type. - type Call: Dispatchable + From> + IsSubType, Self> + Clone; - - /// Maximum number of balancing iterations to run in the offchain submission. - /// - /// If set to 0, balance_solution will not be executed at all. - type MaxIterations: Get; - - /// The threshold of improvement that should be provided for a new solution to be accepted. - type MinSolutionScoreBump: Get; - - /// The maximum number of nominators rewarded for each validator. - /// - /// For each validator only the `$MaxNominatorRewardedPerValidator` biggest stakers can claim - /// their reward. This used to limit the i/o cost for the nominator payout. - type MaxNominatorRewardedPerValidator: Get; - - /// A configuration for base priority of unsigned transactions. - /// - /// This is exposed so that it can be tuned for particular runtime, when - /// multiple pallets send unsigned transactions. - type UnsignedPriority: Get; - - /// The *RING* currency. - type RingCurrency: LockableCurrency; - /// Tokens have been minted and are unused for validator-reward. - /// See [Era payout](./index.html#era-payout). - type RingRewardRemainder: OnUnbalanced>; - /// Handler for the unbalanced *RING* reduction when slashing a staker. - type RingSlash: OnUnbalanced>; - /// Handler for the unbalanced *RING* increment when rewarding a staker. - type RingReward: OnUnbalanced>; - - /// The *KTON* currency. - type KtonCurrency: LockableCurrency; - // FIXME: Ugly hack due to https://github.com/rust-lang/rust/issues/31844#issuecomment-557918823 - /// Handler for the unbalanced *KTON* reduction when slashing a staker. - type KtonSlash: OnUnbalancedKton>; - /// Handler for the unbalanced *KTON* increment when rewarding a staker. - type KtonReward: OnUnbalanced>; - - // TODO: doc - type Cap: Get>; - // TODO: doc - type TotalPower: Get; -} - -decl_storage! { - trait Store for Module as DarwiniaStaking { - /// Number of eras to keep in history. - /// - /// Information is kept for eras in `[current_era - history_depth; current_era]`. - /// - /// Must be more than the number of eras delayed by session otherwise. I.e. active era must - /// always be in history. I.e. `active_era > current_era - history_depth` must be - /// guaranteed. - HistoryDepth get(fn history_depth) config(): u32 = 336; - - /// The ideal number of staking participants. - pub ValidatorCount get(fn validator_count) config(): u32; - - /// Minimum number of staking participants before emergency conditions are imposed. - pub MinimumValidatorCount - get(fn minimum_validator_count) config() - : u32 = DEFAULT_MINIMUM_VALIDATOR_COUNT; - - /// Any validators that may never be slashed or forcibly kicked. It's a Vec since they're - /// easy to initialize and the performance hit is minimal (we expect no more than four - /// invulnerables) and restricted to testnets. - pub Invulnerables get(fn invulnerables) config(): Vec; - - /// Map from all locked "stash" accounts to the controller account. - pub Bonded get(fn bonded): map hasher(twox_64_concat) T::AccountId => Option; + /// Map from all locked "stash" accounts to the controller account. + pub Bonded get(fn bonded): map hasher(twox_64_concat) T::AccountId => Option; /// Map from all (unlocked) "controller" accounts to the info regarding the staking. pub Ledger get(fn ledger): map hasher(blake2_128_concat) T::AccountId => Option>; @@ -1381,38 +900,42 @@ decl_event!( { /// The era payout has been set; the first balance is the validator-payout; the second is /// the remainder from the maximum amount of reward. + /// [era_index, validator_payout, remainder] EraPayout(EraIndex, RingBalance, RingBalance), - /// The staker has been rewarded by this amount. `AccountId` is the stash account. + /// The staker has been rewarded by this amount. [stash, amount] Reward(AccountId, RingBalance), /// One validator (and its nominators) has been slashed by the given amount. + /// [validator, amount, amount] Slash(AccountId, RingBalance, KtonBalance), /// An old slashing report from a prior era was discarded because it could - /// not be processed. + /// not be processed. [session_index] OldSlashingReportDiscarded(SessionIndex), - /// A new set of stakers was elected with the given computation method. + /// A new set of stakers was elected with the given [compute]. StakingElection(ElectionCompute), - /// A new solution for the upcoming election has been stored. + /// A new solution for the upcoming election has been stored. [compute] SolutionStored(ElectionCompute), - /// Bond succeed. - /// `amount` in `RingBalance`, `start_time` in `TsInMs`, `expired_time` in `TsInMs` + /// An account has bonded this amount. [amount, start, end] + /// + /// NOTE: This event is only emitted when funds are bonded via a dispatchable. Notably, + /// it will not be emitted for staking rewards when they are added to stake. BondRing(RingBalance, TsInMs, TsInMs), - /// Bond succeed. - /// `amount` + /// An account has bonded this amount. [amount, start, end] + /// + /// NOTE: This event is only emitted when funds are bonded via a dispatchable. Notably, + /// it will not be emitted for staking rewards when they are added to stake. BondKton(KtonBalance), - /// Unbond succeed. - /// `amount` in `RingBalance`, `now` in `BlockNumber` + /// An account has unbonded this amount. [amount, now] UnbondRing(RingBalance, BlockNumber), - /// Unbond succeed. - /// `amount` om `KtonBalance`, `now` in `BlockNumber` + /// An account has unbonded this amount. [amount, now] UnbondKton(KtonBalance, BlockNumber), - /// Someone claimed his deposits with some *KTON*s punishment + /// Someone claimed his deposits with some *KTON*s punishment. [stash, forfeit] ClaimDepositsWithPunish(AccountId, KtonBalance), } ); @@ -2912,7 +2435,7 @@ impl Module { } // Lets now calculate how this is split to the nominators. - // Sort nominators by highest to lowest exposure, but only keep `max_nominator_payouts` of them. + // Reward only the clipped exposures. Note this is not necessarily sorted. for nominator in exposure.others.iter() { let nominator_exposure_part = Perbill::from_rational_approximation(nominator.power, exposure.total_power); @@ -3232,910 +2755,1493 @@ impl Module { >::PhragmenBogusScore ); - // At last, alles Ok. Exposures and store the result. - let exposures = Self::collect_exposure(supports); - log!( - info, - "💸 A better solution (with compute {:?} and score {:?}) has been validated and stored on chain.", - compute, - submitted_score, - ); + // At last, alles Ok. Exposures and store the result. + let exposures = Self::collect_exposure(supports); + log!( + info, + "💸 A better solution (with compute {:?} and score {:?}) has been validated and stored on chain.", + compute, + submitted_score, + ); + + // write new results. + >::put(ElectionResult { + elected_stashes: winners, + compute, + exposures, + }); + QueuedScore::put(submitted_score); + + // emit event. + Self::deposit_event(RawEvent::SolutionStored(compute)); + + Ok(Some(adjusted_weight).into()) + } + + /// Start a session potentially starting an era. + fn start_session(start_session: SessionIndex) { + let next_active_era = Self::active_era().map(|e| e.index + 1).unwrap_or(0); + if let Some(next_active_era_start_session_index) = + Self::eras_start_session_index(next_active_era) + { + if next_active_era_start_session_index == start_session { + Self::start_era(start_session); + } else if next_active_era_start_session_index < start_session { + // This arm should never happen, but better handle it than to stall the + // staking pallet. + frame_support::print("Warning: A session appears to have been skipped."); + Self::start_era(start_session); + } + } + } + + /// End a session potentially ending an era. + fn end_session(session_index: SessionIndex) { + if let Some(active_era) = Self::active_era() { + let next_active_era_start_session_index = + Self::eras_start_session_index(active_era.index + 1).unwrap_or_else(|| { + frame_support::print( + "Error: start_session_index must be set for active_era + 1", + ); + 0 + }); + + if next_active_era_start_session_index == session_index + 1 { + Self::end_era(active_era, session_index); + } + } + } + + /// * Increment `active_era.index`, + /// * reset `active_era.start`, + /// * update `BondedEras` and apply slashes. + fn start_era(start_session: SessionIndex) { + let active_era = ActiveEra::mutate(|active_era| { + let new_index = active_era.as_ref().map(|info| info.index + 1).unwrap_or(0); + *active_era = Some(ActiveEraInfo { + index: new_index, + // Set new active era start in next `on_finalize`. To guarantee usage of `Time` + start: None, + }); + new_index + }); + + let bonding_duration = T::BondingDurationInEra::get(); + + BondedEras::mutate(|bonded| { + bonded.push((active_era, start_session)); + + if active_era > bonding_duration { + let first_kept = active_era - bonding_duration; + + // prune out everything that's from before the first-kept index. + let n_to_prune = bonded + .iter() + .take_while(|&&(era_idx, _)| era_idx < first_kept) + .count(); + + // kill slashing metadata. + for (pruned_era, _) in bonded.drain(..n_to_prune) { + slashing::clear_era_metadata::(pruned_era); + } + + if let Some(&(_, first_session)) = bonded.first() { + T::SessionInterface::prune_historical_up_to(first_session); + } + } + }); + + Self::apply_unapplied_slashes(active_era); + } + + /// Compute payout for era. + fn end_era(active_era: ActiveEraInfo, _session_index: SessionIndex) { + // Note: active_era_start can be None if end era is called during genesis config. + if let Some(active_era_start) = active_era.start { + let now = T::UnixTime::now().as_millis().saturated_into::(); + let living_time = Self::living_time(); + let era_duration = now - active_era_start; + + let (validator_payout, max_payout) = inflation::compute_total_payout::( + era_duration, + Self::living_time(), + T::Cap::get().saturating_sub(T::RingCurrency::total_issuance()), + PayoutFraction::get(), + ); + let rest = max_payout.saturating_sub(validator_payout); + + Self::deposit_event(RawEvent::EraPayout( + active_era.index, + validator_payout, + rest, + )); + + LivingTime::put(living_time + era_duration); + // Set ending era reward. + >::insert(&active_era.index, validator_payout); + T::RingRewardRemainder::on_unbalanced(T::RingCurrency::issue(rest)); + } + } + + /// Plan a new era. Return the potential new staking set. + fn new_era(start_session_index: SessionIndex) -> Option> { + // Increment or set current era. + let current_era = CurrentEra::mutate(|s| { + *s = Some(s.map(|s| s + 1).unwrap_or(0)); + s.unwrap() + }); + ErasStartSessionIndex::insert(¤t_era, &start_session_index); + + // Clean old era information. + if let Some(old_era) = current_era.checked_sub(Self::history_depth() + 1) { + Self::clear_era_information(old_era); + } + + // Set staking information for new era. + let maybe_new_validators = Self::select_and_update_validators(current_era); + + maybe_new_validators + } + + /// Remove all the storage items associated with the election. + fn close_election_window() { + // Close window. + >::put(ElectionStatus::Closed); + // Kill snapshots. + Self::kill_stakers_snapshot(); + // Don't track final session. + IsCurrentSessionFinal::put(false); + } + + /// Select the new validator set at the end of the era. + /// + /// Runs [`try_do_phragmen`] and updates the following storage items: + /// - [`EraElectionStatus`]: with `None`. + /// - [`ErasStakers`]: with the new staker set. + /// - [`ErasStakersClipped`]. + /// - [`ErasValidatorPrefs`]. + /// - [`ErasTotalStake`]: with the new total stake. + /// - [`SnapshotValidators`] and [`SnapshotNominators`] are both removed. + /// + /// Internally, [`QueuedElected`], snapshots and [`QueuedScore`] are also consumed. + /// + /// If the election has been successful, It passes the new set upwards. + /// + /// This should only be called at the end of an era. + fn select_and_update_validators(current_era: EraIndex) -> Option> { + if let Some(ElectionResultT:: { + elected_stashes, + exposures, + compute, + }) = Self::try_do_election() + { + // Totally close the election round and data. + Self::close_election_window(); + + // Populate Stakers and write slot stake. + let mut total_stake = 0; + exposures.into_iter().for_each(|(stash, exposure)| { + // Total `Power` is `1_000_000_000`, never get overflow; qed + total_stake += exposure.total_power; + >::insert(current_era, &stash, &exposure); + + let mut exposure_clipped = exposure; + let clipped_max_len = T::MaxNominatorRewardedPerValidator::get() as usize; + if exposure_clipped.others.len() > clipped_max_len { + exposure_clipped + .others + .sort_by(|a, b| a.power.cmp(&b.power).reverse()); + exposure_clipped.others.truncate(clipped_max_len); + } + >::insert(¤t_era, &stash, exposure_clipped); + }); + // Insert current era staking information + ErasTotalStake::insert(¤t_era, total_stake); + + // collect the pref of all winners + for stash in &elected_stashes { + let pref = Self::validators(stash); + >::insert(¤t_era, stash, pref); + } + + // emit event + Self::deposit_event(RawEvent::StakingElection(compute)); + + log!( + info, + "💸 new validator set of size {:?} has been elected via {:?} for era {:?}", + elected_stashes.len(), + compute, + current_era, + ); + + Some(elected_stashes) + } else { + None + } + } - // write new results. - >::put(ElectionResult { - elected_stashes: winners, - compute, - exposures, + /// Select a new validator set from the assembled stakers and their role preferences. It tries + /// first to peek into [`QueuedElected`]. Otherwise, it runs a new on-chain phragmen election. + /// + /// If [`QueuedElected`] and [`QueuedScore`] exists, they are both removed. No further storage + /// is updated. + fn try_do_election() -> Option> { + // an election result from either a stored submission or locally executed one. + let next_result = >::take().or_else(|| { + Self::do_phragmen_with_post_processing::(ElectionCompute::OnChain) }); - QueuedScore::put(submitted_score); - // emit event. - Self::deposit_event(RawEvent::SolutionStored(compute)); + // either way, kill this. We remove it here to make sure it always has the exact same + // lifetime as `QueuedElected`. + QueuedScore::kill(); - Ok(Some(adjusted_weight).into()) + next_result } - /// Start a session potentially starting an era. - fn start_session(start_session: SessionIndex) { - let next_active_era = Self::active_era().map(|e| e.index + 1).unwrap_or(0); - if let Some(next_active_era_start_session_index) = - Self::eras_start_session_index(next_active_era) - { - if next_active_era_start_session_index == start_session { - Self::start_era(start_session); - } else if next_active_era_start_session_index < start_session { - // This arm should never happen, but better handle it than to stall the - // staking pallet. - frame_support::print("Warning: A session appears to have been skipped."); - Self::start_era(start_session); - } - } - } + /// Execute election and return the new results. The edge weights are processed into support + /// values. + /// + /// This is basically a wrapper around [`do_phragmen`] which translates + /// `PrimitiveElectionResult` into `ElectionResult`. + /// + /// No storage item is updated. + fn do_phragmen_with_post_processing( + compute: ElectionCompute, + ) -> Option> + where + Accuracy: sp_std::ops::Mul, + ExtendedBalance: From<::Inner>, + { + if let Some(phragmen_result) = Self::do_phragmen::() { + let elected_stashes = phragmen_result + .winners + .iter() + .map(|(s, _)| s.clone()) + .collect::>(); + let assignments = phragmen_result.assignments; - /// End a session potentially ending an era. - fn end_session(session_index: SessionIndex) { - if let Some(active_era) = Self::active_era() { - let next_active_era_start_session_index = - Self::eras_start_session_index(active_era.index + 1).unwrap_or_else(|| { - frame_support::print( - "Error: start_session_index must be set for active_era + 1", - ); - 0 + let staked_assignments = + sp_npos_elections::assignment_ratio_to_staked(assignments, |s| { + Self::power_of(s) as _ }); - if next_active_era_start_session_index == session_index + 1 { - Self::end_era(active_era, session_index); - } + let (supports, _) = + build_support_map::(&elected_stashes, &staked_assignments); + + // collect exposures + let exposures = Self::collect_exposure(supports); + + // In order to keep the property required by `on_session_ending` that we must return the + // new validator set even if it's the same as the old, as long as any underlying + // economic conditions have changed, we don't attempt to do any optimization where we + // compare against the prior set. + Some(ElectionResultT:: { + elected_stashes, + exposures, + compute, + }) + } else { + // There were not enough candidates for even our minimal level of functionality. This is + // bad. We should probably disable all functionality except for block production and let + // the chain keep producing blocks until we can decide on a sufficiently substantial + // set. TODO: #2494 + None } } - /// * Increment `active_era.index`, - /// * reset `active_era.start`, - /// * update `BondedEras` and apply slashes. - fn start_era(start_session: SessionIndex) { - let active_era = ActiveEra::mutate(|active_era| { - let new_index = active_era.as_ref().map(|info| info.index + 1).unwrap_or(0); - *active_era = Some(ActiveEraInfo { - index: new_index, - // Set new active era start in next `on_finalize`. To guarantee usage of `Time` - start: None, + /// Execute phragmen election and return the new results. No post-processing is applied and the + /// raw edge weights are returned. + /// + /// Self votes are added and nominations before the most recent slashing span are reaped. + /// + /// No storage item is updated. + fn do_phragmen() -> Option> + { + let mut all_nominators: Vec<(T::AccountId, VoteWeight, Vec)> = vec![]; + let mut all_validators = vec![]; + for (validator, _) in >::iter() { + // append self vote + let self_vote = ( + validator.clone(), + Self::power_of(&validator) as _, + vec![validator.clone()], + ); + all_nominators.push(self_vote); + all_validators.push(validator); + } + + let nominator_votes = >::iter().map(|(nominator, nominations)| { + let Nominations { + submitted_in, + mut targets, + suppressed: _, + } = nominations; + + // Filter out nomination targets which were nominated before the most recent + // slashing span. + targets.retain(|stash| { + ::SlashingSpans::get(&stash) + .map_or(true, |spans| submitted_in >= spans.last_nonzero_slash()) }); - new_index + + (nominator, targets) }); + all_nominators.extend(nominator_votes.map(|(n, ns)| { + let s = Self::power_of(&n) as _; + (n, s, ns) + })); - let bonding_duration = T::BondingDurationInEra::get(); + seq_phragmen::<_, Accuracy>( + Self::validator_count() as usize, + Self::minimum_validator_count().max(1) as usize, + all_validators, + all_nominators, + ) + } - BondedEras::mutate(|bonded| { - bonded.push((active_era, start_session)); + /// Consume a set of [`Supports`] from [`sp_npos_elections`] and collect them into a [`Exposure`] + fn collect_exposure(supports: SupportMap) -> Vec<(T::AccountId, ExposureT)> { + supports + .into_iter() + .map(|(validator, support)| { + // build `struct exposure` from `support` + let mut own_ring_balance: RingBalance = Zero::zero(); + let mut own_kton_balance: KtonBalance = Zero::zero(); + let mut own_power = 0; + let mut total_power = 0; + let mut others = Vec::with_capacity(support.voters.len()); + support.voters.into_iter().for_each(|(nominator, weight)| { + let origin_weight = Self::power_of(&nominator) as ExtendedBalance; + let (origin_ring_balance, origin_kton_balance) = Self::stake_of(&nominator); + + let ring_balance = if let Ok(ring_balance) = multiply_by_rational( + origin_ring_balance.saturated_into(), + weight, + origin_weight, + ) { + ring_balance.saturated_into() + } else { + log!( + error, + "[staking] Origin RING: {:?}, Weight: {:?}, Origin Weight: {:?}", + origin_ring_balance, + weight, + origin_weight + ); + Zero::zero() + }; + let kton_balance = if let Ok(kton_balance) = multiply_by_rational( + origin_kton_balance.saturated_into(), + weight, + origin_weight, + ) { + kton_balance.saturated_into() + } else { + log!( + error, + "[staking] Origin KTON: {:?}, Weight: {:?}, Origin Weight: {:?}", + origin_kton_balance, + weight, + origin_weight + ); + Zero::zero() + }; + let power = weight as Power; + + if nominator == validator { + own_ring_balance = own_ring_balance.saturating_add(ring_balance); + own_kton_balance = own_kton_balance.saturating_add(kton_balance); + own_power = own_power.saturating_add(power); + } else { + others.push(IndividualExposure { + who: nominator, + ring_balance, + kton_balance, + power, + }); + } + total_power = total_power.saturating_add(power); + }); + + let exposure = Exposure { + own_ring_balance, + own_kton_balance, + own_power, + total_power, + others, + }; + + (validator, exposure) + }) + .collect::)>>() + } + + /// Remove all associated data of a stash account from the staking system. + /// + /// Assumes storage is upgraded before calling. + /// + /// This is called: + /// - after a `withdraw_unbond()` call that frees all of a stash's bonded balance. + /// - through `reap_stash()` if the balance has fallen to zero (through slashing). + fn kill_stash(stash: &T::AccountId, num_slashing_spans: u32) -> DispatchResult { + let controller = >::get(stash).ok_or(>::NotStash)?; - if active_era > bonding_duration { - let first_kept = active_era - bonding_duration; + slashing::clear_stash_metadata::(stash, num_slashing_spans)?; - // prune out everything that's from before the first-kept index. - let n_to_prune = bonded - .iter() - .take_while(|&&(era_idx, _)| era_idx < first_kept) - .count(); + >::remove(stash); + >::remove(&controller); - // kill slashing metadata. - for (pruned_era, _) in bonded.drain(..n_to_prune) { - slashing::clear_era_metadata::(pruned_era); - } + >::remove(stash); + >::remove(stash); + >::remove(stash); - if let Some(&(_, first_session)) = bonded.first() { - T::SessionInterface::prune_historical_up_to(first_session); - } - } - }); + >::dec_ref(stash); - Self::apply_unapplied_slashes(active_era); + Ok(()) } - /// Compute payout for era. - fn end_era(active_era: ActiveEraInfo, _session_index: SessionIndex) { - // Note: active_era_start can be None if end era is called during genesis config. - if let Some(active_era_start) = active_era.start { - let now = T::UnixTime::now().as_millis().saturated_into::(); - let living_time = Self::living_time(); - let era_duration = now - active_era_start; + /// Clear all era information for given era. + fn clear_era_information(era_index: EraIndex) { + >::remove_prefix(era_index); + >::remove_prefix(era_index); + >::remove_prefix(era_index); + >::remove(era_index); + >::remove(era_index); + ::remove(era_index); + ErasStartSessionIndex::remove(era_index); + } - let (validator_payout, max_payout) = inflation::compute_total_payout::( - era_duration, - Self::living_time(), - T::Cap::get().saturating_sub(T::RingCurrency::total_issuance()), - PayoutFraction::get(), - ); - let rest = max_payout.saturating_sub(validator_payout); + /// Apply previously-unapplied slashes on the beginning of a new era, after a delay. + fn apply_unapplied_slashes(active_era: EraIndex) { + let slash_defer_duration = T::SlashDeferDuration::get(); + ::EarliestUnappliedSlash::mutate(|earliest| { + if let Some(ref mut earliest) = earliest { + let keep_from = active_era.saturating_sub(slash_defer_duration); + for era in (*earliest)..keep_from { + let era_slashes = ::UnappliedSlashes::take(&era); + for slash in era_slashes { + slashing::apply_slash::(slash); + } + } - Self::deposit_event(RawEvent::EraPayout( - active_era.index, - validator_payout, - rest, - )); + *earliest = (*earliest).max(keep_from) + } + }) + } - LivingTime::put(living_time + era_duration); - // Set ending era reward. - >::insert(&active_era.index, validator_payout); - T::RingRewardRemainder::on_unbalanced(T::RingCurrency::issue(rest)); + /// Add reward points to validators using their stash account ID. + /// + /// Validators are keyed by stash account ID and must be in the current elected set. + /// + /// For each element in the iterator the given number of points in u32 is added to the + /// validator, thus duplicates are handled. + /// + /// At the end of the era each the total payout will be distributed among validator + /// relatively to their points. + /// + /// COMPLEXITY: Complexity is `number_of_validator_to_reward x current_elected_len`. + /// If you need to reward lots of validator consider using `reward_by_indices`. + pub fn reward_by_ids(validators_points: impl IntoIterator) { + if let Some(active_era) = Self::active_era() { + >::mutate(active_era.index, |era_rewards| { + for (validator, points) in validators_points.into_iter() { + *era_rewards.individual.entry(validator).or_default() += points; + era_rewards.total += points; + } + }); } } - /// Plan a new era. Return the potential new staking set. - fn new_era(start_session_index: SessionIndex) -> Option> { - // Increment or set current era. - let current_era = CurrentEra::mutate(|s| { - *s = Some(s.map(|s| s + 1).unwrap_or(0)); - s.unwrap() - }); - ErasStartSessionIndex::insert(¤t_era, &start_session_index); - - // Clean old era information. - if let Some(old_era) = current_era.checked_sub(Self::history_depth() + 1) { - Self::clear_era_information(old_era); + /// Ensures that at the end of the current session there will be a new era. + fn ensure_new_era() { + match ForceEra::get() { + Forcing::ForceAlways | Forcing::ForceNew => (), + _ => ForceEra::put(Forcing::ForceNew), } - - // Set staking information for new era. - let maybe_new_validators = Self::select_and_update_validators(current_era); - - maybe_new_validators } - /// Remove all the storage items associated with the election. - fn close_election_window() { - // Close window. - >::put(ElectionStatus::Closed); - // Kill snapshots. - Self::kill_stakers_snapshot(); - // Don't track final session. - IsCurrentSessionFinal::put(false); + fn will_era_be_forced() -> bool { + match ForceEra::get() { + Forcing::ForceAlways | Forcing::ForceNew => true, + Forcing::ForceNone | Forcing::NotForcing => false, + } } - /// Select the new validator set at the end of the era. - /// - /// Runs [`try_do_phragmen`] and updates the following storage items: - /// - [`EraElectionStatus`]: with `None`. - /// - [`ErasStakers`]: with the new staker set. - /// - [`ErasStakersClipped`]. - /// - [`ErasValidatorPrefs`]. - /// - [`ErasTotalStake`]: with the new total stake. - /// - [`SnapshotValidators`] and [`SnapshotNominators`] are both removed. - /// - /// Internally, [`QueuedElected`], snapshots and [`QueuedScore`] are also consumed. - /// - /// If the election has been successful, It passes the new set upwards. - /// - /// This should only be called at the end of an era. - fn select_and_update_validators(current_era: EraIndex) -> Option> { - if let Some(ElectionResultT:: { - elected_stashes, - exposures, - compute, - }) = Self::try_do_election() - { - // Totally close the election round and data. - Self::close_election_window(); + #[cfg(feature = "runtime-benchmarks")] + pub fn add_era_stakers( + current_era: EraIndex, + controller: T::AccountId, + exposure: ExposureT, + ) { + >::insert(¤t_era, &controller, &exposure); + } - // Populate Stakers and write slot stake. - let mut total_stake = 0; - exposures.into_iter().for_each(|(stash, exposure)| { - // Total `Power` is `1_000_000_000`, never get overflow; qed - total_stake += exposure.total_power; - >::insert(current_era, &stash, &exposure); + #[cfg(feature = "runtime-benchmarks")] + pub fn put_election_status(status: ElectionStatus) { + >::put(status); + } - let mut exposure_clipped = exposure; - let clipped_max_len = T::MaxNominatorRewardedPerValidator::get() as usize; - if exposure_clipped.others.len() > clipped_max_len { - exposure_clipped - .others - .sort_by(|a, b| a.power.cmp(&b.power).reverse()); - exposure_clipped.others.truncate(clipped_max_len); - } - >::insert(¤t_era, &stash, exposure_clipped); - }); - // Insert current era staking information - ErasTotalStake::insert(¤t_era, total_stake); + #[cfg(feature = "runtime-benchmarks")] + pub fn set_slash_reward_fraction(fraction: Perbill) { + SlashRewardFraction::put(fraction); + } +} - // collect the pref of all winners - for stash in &elected_stashes { - let pref = Self::validators(stash); - >::insert(¤t_era, stash, pref); - } +impl pallet_session::SessionManager for Module { + fn new_session(new_index: SessionIndex) -> Option> { + Self::new_session(new_index) + } + fn end_session(end_index: SessionIndex) { + Self::end_session(end_index) + } + fn start_session(start_index: SessionIndex) { + Self::start_session(start_index) + } +} - // emit event - Self::deposit_event(RawEvent::StakingElection(compute)); +impl pallet_session::historical::SessionManager> + for Module +{ + fn new_session(new_index: SessionIndex) -> Option)>> { + >::new_session(new_index).map(|validators| { + let current_era = Self::current_era() + // Must be some as a new era has been created. + .unwrap_or(0); - log!( - info, - "💸 new validator set of size {:?} has been elected via {:?} for era {:?}", - elected_stashes.len(), - compute, - current_era, - ); + validators + .into_iter() + .map(|v| { + let exposure = Self::eras_stakers(current_era, &v); + (v, exposure) + }) + .collect() + }) + } + fn start_session(start_index: SessionIndex) { + >::start_session(start_index) + } + fn end_session(end_index: SessionIndex) { + >::end_session(end_index) + } +} - Some(elected_stashes) - } else { - None - } +/// Add reward points to block authors: +/// * 20 points to the block producer for producing a (non-uncle) block in the relay chain, +/// * 2 points to the block producer for each reference to a previously unreferenced uncle, and +/// * 1 point to the producer of each referenced uncle block. +impl pallet_authorship::EventHandler for Module +where + T: Trait + pallet_authorship::Trait + pallet_session::Trait, +{ + fn note_author(author: T::AccountId) { + Self::reward_by_ids(vec![(author, 20)]); + } + fn note_uncle(author: T::AccountId, _age: T::BlockNumber) { + Self::reward_by_ids(vec![ + (>::author(), 2), + (author, 1), + ]); } +} - /// Select a new validator set from the assembled stakers and their role preferences. It tries - /// first to peek into [`QueuedElected`]. Otherwise, it runs a new on-chain phragmen election. - /// - /// If [`QueuedElected`] and [`QueuedScore`] exists, they are both removed. No further storage - /// is updated. - fn try_do_election() -> Option> { - // an election result from either a stored submission or locally executed one. - let next_result = >::take().or_else(|| { - Self::do_phragmen_with_post_processing::(ElectionCompute::OnChain) - }); - - // either way, kill this. We remove it here to make sure it always has the exact same - // lifetime as `QueuedElected`. - QueuedScore::kill(); +/// A `Convert` implementation that finds the stash of the given controller account, +/// if any. +pub struct StashOf(PhantomData); - next_result +impl Convert> for StashOf { + fn convert(controller: T::AccountId) -> Option { + >::ledger(&controller).map(|l| l.stash) } +} - /// Execute election and return the new results. The edge weights are processed into support - /// values. - /// - /// This is basically a wrapper around [`do_phragmen`] which translates - /// `PrimitiveElectionResult` into `ElectionResult`. - /// - /// No storage item is updated. - fn do_phragmen_with_post_processing( - compute: ElectionCompute, - ) -> Option> - where - Accuracy: sp_std::ops::Mul, - ExtendedBalance: From<::Inner>, - { - if let Some(phragmen_result) = Self::do_phragmen::() { - let elected_stashes = phragmen_result - .winners - .iter() - .map(|(s, _)| s.clone()) - .collect::>(); - let assignments = phragmen_result.assignments; - - let staked_assignments = - sp_npos_elections::assignment_ratio_to_staked(assignments, |s| { - Self::power_of(s) as _ - }); - - let (supports, _) = - build_support_map::(&elected_stashes, &staked_assignments); - - // collect exposures - let exposures = Self::collect_exposure(supports); +/// A typed conversion from stash account ID to the active exposure of nominators +/// on that account. +/// +/// Active exposure is the exposure of the validator set currently validating, i.e. in +/// `active_era`. It can differ from the latest planned exposure in `current_era`. +pub struct ExposureOf(PhantomData); - // In order to keep the property required by `on_session_ending` that we must return the - // new validator set even if it's the same as the old, as long as any underlying - // economic conditions have changed, we don't attempt to do any optimization where we - // compare against the prior set. - Some(ElectionResultT:: { - elected_stashes, - exposures, - compute, - }) +impl Convert>> for ExposureOf { + fn convert(validator: T::AccountId) -> Option> { + if let Some(active_era) = >::active_era() { + Some(>::eras_stakers(active_era.index, &validator)) } else { - // There were not enough candidates for even our minimal level of functionality. This is - // bad. We should probably disable all functionality except for block production and let - // the chain keep producing blocks until we can decide on a sufficiently substantial - // set. TODO: #2494 None } } +} - /// Execute phragmen election and return the new results. No post-processing is applied and the - /// raw edge weights are returned. - /// - /// Self votes are added and nominations before the most recent slashing span are reaped. - /// - /// No storage item is updated. - fn do_phragmen() -> Option> - { - let mut all_nominators: Vec<(T::AccountId, VoteWeight, Vec)> = vec![]; - let mut all_validators = vec![]; - for (validator, _) in >::iter() { - // append self vote - let self_vote = ( - validator.clone(), - Self::power_of(&validator) as _, - vec![validator.clone()], - ); - all_nominators.push(self_vote); - all_validators.push(validator); +/// This is intended to be used with `FilterHistoricalOffences`. +impl + OnOffenceHandler, Weight> + for Module +where + T: pallet_session::Trait>, + T: pallet_session::historical::Trait< + FullIdentification = ExposureT, + FullIdentificationOf = ExposureOf, + >, + T::SessionHandler: pallet_session::SessionHandler>, + T::SessionManager: pallet_session::SessionManager>, + T::ValidatorIdOf: Convert, Option>>, +{ + fn on_offence( + offenders: &[OffenceDetails< + T::AccountId, + pallet_session::historical::IdentificationTuple, + >], + slash_fraction: &[Perbill], + slash_session: SessionIndex, + ) -> Result { + if !Self::can_report() { + return Err(()); } - let nominator_votes = >::iter().map(|(nominator, nominations)| { - let Nominations { - submitted_in, - mut targets, - suppressed: _, - } = nominations; + let reward_proportion = SlashRewardFraction::get(); + let mut consumed_weight: Weight = 0; + let mut add_db_reads_writes = |reads, writes| { + consumed_weight += T::DbWeight::get().reads_writes(reads, writes); + }; - // Filter out nomination targets which were nominated before the most recent - // slashing span. - targets.retain(|stash| { - ::SlashingSpans::get(&stash) - .map_or(true, |spans| submitted_in >= spans.last_nonzero_slash()) + let active_era = { + let active_era = Self::active_era(); + add_db_reads_writes(1, 0); + if active_era.is_none() { + // this offence need not be re-submitted. + return Ok(consumed_weight); + } + active_era + .expect("value checked not to be `None`; qed") + .index + }; + let active_era_start_session_index = Self::eras_start_session_index(active_era) + .unwrap_or_else(|| { + frame_support::print("Error: start_session_index must be set for current_era"); + 0 }); + add_db_reads_writes(1, 0); - (nominator, targets) + let window_start = active_era.saturating_sub(T::BondingDurationInEra::get()); + + // fast path for active-era report - most likely. + // `slash_session` cannot be in a future active era. It must be in `active_era` or before. + let slash_era = if slash_session >= active_era_start_session_index { + active_era + } else { + let eras = BondedEras::get(); + add_db_reads_writes(1, 0); + + // reverse because it's more likely to find reports from recent eras. + match eras + .iter() + .rev() + .filter(|&&(_, ref sesh)| sesh <= &slash_session) + .next() + { + Some(&(ref slash_era, _)) => *slash_era, + // before bonding period. defensive - should be filtered out. + None => return Ok(consumed_weight), + } + }; + + ::EarliestUnappliedSlash::mutate(|earliest| { + if earliest.is_none() { + *earliest = Some(active_era) + } }); - all_nominators.extend(nominator_votes.map(|(n, ns)| { - let s = Self::power_of(&n) as _; - (n, s, ns) - })); + add_db_reads_writes(1, 1); - seq_phragmen::<_, Accuracy>( - Self::validator_count() as usize, - Self::minimum_validator_count().max(1) as usize, - all_validators, - all_nominators, - ) - } + let slash_defer_duration = T::SlashDeferDuration::get(); - /// Consume a set of [`Supports`] from [`sp_npos_elections`] and collect them into a [`Exposure`] - fn collect_exposure(supports: SupportMap) -> Vec<(T::AccountId, ExposureT)> { - supports - .into_iter() - .map(|(validator, support)| { - // build `struct exposure` from `support` - let mut own_ring_balance: RingBalance = Zero::zero(); - let mut own_kton_balance: KtonBalance = Zero::zero(); - let mut own_power = 0; - let mut total_power = 0; - let mut others = Vec::with_capacity(support.voters.len()); - support.voters.into_iter().for_each(|(nominator, weight)| { - let origin_weight = Self::power_of(&nominator) as ExtendedBalance; - let (origin_ring_balance, origin_kton_balance) = Self::stake_of(&nominator); + let invulnerables = Self::invulnerables(); + add_db_reads_writes(1, 0); - let ring_balance = if let Ok(ring_balance) = multiply_by_rational( - origin_ring_balance.saturated_into(), - weight, - origin_weight, - ) { - ring_balance.saturated_into() - } else { - log!( - error, - "[staking] Origin RING: {:?}, Weight: {:?}, Origin Weight: {:?}", - origin_ring_balance, - weight, - origin_weight - ); - Zero::zero() - }; - let kton_balance = if let Ok(kton_balance) = multiply_by_rational( - origin_kton_balance.saturated_into(), - weight, - origin_weight, - ) { - kton_balance.saturated_into() - } else { - log!( - error, - "[staking] Origin KTON: {:?}, Weight: {:?}, Origin Weight: {:?}", - origin_kton_balance, - weight, - origin_weight - ); - Zero::zero() - }; - let power = weight as Power; + for (details, slash_fraction) in offenders.iter().zip(slash_fraction) { + let (stash, exposure) = &details.offender; + + // Skip if the validator is invulnerable. + if invulnerables.contains(stash) { + continue; + } + + let unapplied = slashing::compute_slash::(slashing::SlashParams { + stash, + slash: *slash_fraction, + exposure, + slash_era, + window_start, + now: active_era, + reward_proportion, + }); - if nominator == validator { - own_ring_balance = own_ring_balance.saturating_add(ring_balance); - own_kton_balance = own_kton_balance.saturating_add(kton_balance); - own_power = own_power.saturating_add(power); - } else { - others.push(IndividualExposure { - who: nominator, - ring_balance, - kton_balance, - power, - }); + if let Some(mut unapplied) = unapplied { + let nominators_len = unapplied.others.len() as u64; + let reporters_len = details.reporters.len() as u64; + + { + let upper_bound = 1 /* Validator/NominatorSlashInEra */ + 2 /* fetch_spans */; + let rw = upper_bound + nominators_len * upper_bound; + add_db_reads_writes(rw, rw); + } + unapplied.reporters = details.reporters.clone(); + if slash_defer_duration == 0 { + // apply right away. + slashing::apply_slash::(unapplied); + { + let slash_cost = (6, 5); + let reward_cost = (2, 2); + add_db_reads_writes( + (1 + nominators_len) * slash_cost.0 + reward_cost.0 * reporters_len, + (1 + nominators_len) * slash_cost.1 + reward_cost.1 * reporters_len, + ); } - total_power = total_power.saturating_add(power); - }); + } else { + // defer to end of some `slash_defer_duration` from now. + ::UnappliedSlashes::mutate(active_era, move |for_later| { + for_later.push(unapplied) + }); + add_db_reads_writes(1, 1); + } + } else { + add_db_reads_writes(4 /* fetch_spans */, 5 /* kick_out_if_recent */) + } + } - let exposure = Exposure { - own_ring_balance, - own_kton_balance, - own_power, - total_power, - others, - }; + Ok(consumed_weight) + } - (validator, exposure) - }) - .collect::)>>() + fn can_report() -> bool { + Self::era_election_status().is_closed() + } +} + +/// Filter historical offences out and only allow those from the bonding period. +pub struct FilterHistoricalOffences { + _inner: PhantomData<(T, R)>, +} +impl ReportOffence + for FilterHistoricalOffences, R> +where + T: Trait, + R: ReportOffence, + O: Offence, +{ + fn report_offence(reporters: Vec, offence: O) -> Result<(), OffenceError> { + // disallow any slashing from before the current bonding period. + let offence_session = offence.session_index(); + let bonded_eras = BondedEras::get(); + + if bonded_eras + .first() + .filter(|(_, start)| offence_session >= *start) + .is_some() + { + R::report_offence(reporters, offence) + } else { + >::deposit_event(RawEvent::OldSlashingReportDiscarded(offence_session)); + Ok(()) + } } - /// Remove all associated data of a stash account from the staking system. - /// - /// Assumes storage is upgraded before calling. - /// - /// This is called: - /// - after a `withdraw_unbond()` call that frees all of a stash's bonded balance. - /// - through `reap_stash()` if the balance has fallen to zero (through slashing). - fn kill_stash(stash: &T::AccountId, num_slashing_spans: u32) -> DispatchResult { - let controller = >::get(stash).ok_or(>::NotStash)?; + fn is_known_offence(offenders: &[Offender], time_slot: &O::TimeSlot) -> bool { + R::is_known_offence(offenders, time_slot) + } +} - slashing::clear_stash_metadata::(stash, num_slashing_spans)?; +impl OnDepositRedeem> for Module { + fn on_deposit_redeem( + backing: &T::AccountId, + start_time: TsInMs, + months: u8, + amount: RingBalance, + stash: &T::AccountId, + ) -> DispatchResult { + let controller = Self::bonded(&stash).ok_or(>::NotStash)?; + let ledger = Self::ledger(&controller).ok_or(>::NotController)?; - >::remove(stash); - >::remove(&controller); + // The timestamp unit is different between Ethereum and Darwinia, converting from seconds to milliseconds + let start_time = start_time * 1000; + let promise_month = months.min(36); - >::remove(stash); - >::remove(stash); - >::remove(stash); + // let stash_balance = T::Ring::free_balance(&stash); + + // TODO: Lock but no kton reward because this is a deposit redeem + // let extra = extra.min(r); + + T::RingCurrency::transfer(&backing, &stash, amount, KeepAlive)?; - system::Module::::dec_ref(stash); + let (start_time, expire_time) = Self::bond_ring_for_deposit_redeem( + &controller, + amount, + start_time, + promise_month, + ledger, + ); + + >::mutate(|r| *r += amount); + // TODO: Should we deposit an different event? + >::deposit_event(RawEvent::BondRing(amount, start_time, expire_time)); Ok(()) } +} - /// Clear all era information for given era. - fn clear_era_information(era_index: EraIndex) { - >::remove_prefix(era_index); - >::remove_prefix(era_index); - >::remove_prefix(era_index); - >::remove(era_index); - >::remove(era_index); - ::remove(era_index); - ErasStartSessionIndex::remove(era_index); - } +#[allow(deprecated)] +impl frame_support::unsigned::ValidateUnsigned for Module { + type Call = Call; + fn validate_unsigned(source: TransactionSource, call: &Self::Call) -> TransactionValidity { + if let Call::submit_election_solution_unsigned(_, _, score, era, _) = call { + // --- substrate --- + use offchain_election::DEFAULT_LONGEVITY; - /// Apply previously-unapplied slashes on the beginning of a new era, after a delay. - fn apply_unapplied_slashes(active_era: EraIndex) { - let slash_defer_duration = T::SlashDeferDuration::get(); - ::EarliestUnappliedSlash::mutate(|earliest| { - if let Some(ref mut earliest) = earliest { - let keep_from = active_era.saturating_sub(slash_defer_duration); - for era in (*earliest)..keep_from { - let era_slashes = ::UnappliedSlashes::take(&era); - for slash in era_slashes { - slashing::apply_slash::(slash); - } + // discard solution not coming from the local OCW. + match source { + TransactionSource::Local | TransactionSource::InBlock => { /* allowed */ } + _ => { + log!( + debug, + "rejecting unsigned transaction because it is not local/in-block." + ); + return InvalidTransaction::Call.into(); } + } - *earliest = (*earliest).max(keep_from) + if let Err(error_with_post_info) = Self::pre_dispatch_checks(*score, *era) { + let invalid = to_invalid(error_with_post_info); + log!( + debug, + "validate unsigned pre dispatch checks failed due to error #{:?}.", + invalid, + ); + return invalid.into(); } - }) - } - /// Add reward points to validators using their stash account ID. - /// - /// Validators are keyed by stash account ID and must be in the current elected set. - /// - /// For each element in the iterator the given number of points in u32 is added to the - /// validator, thus duplicates are handled. - /// - /// At the end of the era each the total payout will be distributed among validator - /// relatively to their points. - /// - /// COMPLEXITY: Complexity is `number_of_validator_to_reward x current_elected_len`. - /// If you need to reward lots of validator consider using `reward_by_indices`. - pub fn reward_by_ids(validators_points: impl IntoIterator) { - if let Some(active_era) = Self::active_era() { - >::mutate(active_era.index, |era_rewards| { - for (validator, points) in validators_points.into_iter() { - *era_rewards.individual.entry(validator).or_default() += points; - era_rewards.total += points; - } - }); + log!( + debug, + "validateUnsigned succeeded for a solution at era {}.", + era + ); + + ValidTransaction::with_tag_prefix("StakingOffchain") + // The higher the score[0], the better a solution is. + .priority(T::UnsignedPriority::get().saturating_add(score[0].saturated_into())) + // Defensive only. A single solution can exist in the pool per era. Each validator + // will run OCW at most once per era, hence there should never exist more than one + // transaction anyhow. + .and_provides(era) + // Note: this can be more accurate in the future. We do something like + // `era_end_block - current_block` but that is not needed now as we eagerly run + // offchain workers now and the above should be same as `T::ElectionLookahead` + // without the need to query more storage in the validation phase. If we randomize + // offchain worker, then we might re-consider this. + .longevity( + TryInto::::try_into(T::ElectionLookahead::get()) + .unwrap_or(DEFAULT_LONGEVITY), + ) + // We don't propagate this. This can never the validated at a remote node. + .propagate(false) + .build() + } else { + InvalidTransaction::Call.into() } } - /// Ensures that at the end of the current session there will be a new era. - fn ensure_new_era() { - match ForceEra::get() { - Forcing::ForceAlways | Forcing::ForceNew => (), - _ => ForceEra::put(Forcing::ForceNew), + fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError> { + if let Call::submit_election_solution_unsigned(_, _, score, era, _) = call { + // IMPORTANT NOTE: These checks are performed in the dispatch call itself, yet we need + // to duplicate them here to prevent a block producer from putting a previously + // validated, yet no longer valid solution on chain. + // OPTIMISATION NOTE: we could skip this in the `submit_election_solution_unsigned` + // since we already do it here. The signed version needs it though. Yer for now we keep + // this duplicate check here so both signed and unsigned can use a singular + // `check_and_replace_solution`. + Self::pre_dispatch_checks(*score, *era) + .map(|_| ()) + .map_err(to_invalid) + .map_err(Into::into) + } else { + Err(InvalidTransaction::Call.into()) } } +} - fn will_era_be_forced() -> bool { - match ForceEra::get() { - Forcing::ForceAlways | Forcing::ForceNew => true, - Forcing::ForceNone | Forcing::NotForcing => false, - } +pub trait WeightInfo { + fn bond(u: u32) -> Weight; + fn bond_extra(u: u32) -> Weight; + fn unbond(u: u32) -> Weight; + fn claim_mature_deposits(u: u32) -> Weight; + fn try_claim_deposits_with_punish(u: u32) -> Weight; + fn validate(u: u32) -> Weight; + fn nominate(n: u32) -> Weight; + fn chill(u: u32) -> Weight; + fn set_payee(u: u32) -> Weight; + fn set_controller(u: u32) -> Weight; + fn set_validator_count(c: u32) -> Weight; + fn force_no_eras(i: u32) -> Weight; + fn force_new_era(i: u32) -> Weight; + fn force_new_era_always(i: u32) -> Weight; + fn set_invulnerables(v: u32) -> Weight; + fn force_unstake(s: u32) -> Weight; + fn cancel_deferred_slash(s: u32) -> Weight; + fn payout_stakers(n: u32) -> Weight; + fn payout_stakers_alive_controller(n: u32) -> Weight; + fn set_history_depth(e: u32) -> Weight; + fn reap_stash(s: u32) -> Weight; + fn new_era(v: u32, n: u32) -> Weight; + fn do_slash(l: u32) -> Weight; + fn payout_all(v: u32, n: u32) -> Weight; + fn submit_solution_initial(v: u32, n: u32, a: u32, w: u32) -> Weight; + fn submit_solution_better(v: u32, n: u32, a: u32, w: u32) -> Weight; + fn submit_solution_weaker(v: u32, n: u32) -> Weight; +} +impl WeightInfo for () { + fn bond(_u: u32) -> Weight { + 1_000_000_000 } - - #[cfg(feature = "runtime-benchmarks")] - pub fn add_era_stakers( - current_era: EraIndex, - controller: T::AccountId, - exposure: ExposureT, - ) { - >::insert(¤t_era, &controller, &exposure); + fn bond_extra(_u: u32) -> Weight { + 1_000_000_000 } - - #[cfg(feature = "runtime-benchmarks")] - pub fn put_election_status(status: ElectionStatus) { - >::put(status); + fn unbond(_u: u32) -> Weight { + 1_000_000_000 } - - #[cfg(feature = "runtime-benchmarks")] - pub fn set_slash_reward_fraction(fraction: Perbill) { - SlashRewardFraction::put(fraction); + fn claim_mature_deposits(_u: u32) -> Weight { + 1_000_000_000 + } + fn try_claim_deposits_with_punish(_u: u32) -> Weight { + 1_000_000_000 + } + fn validate(_u: u32) -> Weight { + 1_000_000_000 + } + fn nominate(_n: u32) -> Weight { + 1_000_000_000 + } + fn chill(_u: u32) -> Weight { + 1_000_000_000 + } + fn set_payee(_u: u32) -> Weight { + 1_000_000_000 + } + fn set_controller(_u: u32) -> Weight { + 1_000_000_000 + } + fn set_validator_count(_c: u32) -> Weight { + 1_000_000_000 + } + fn force_no_eras(_i: u32) -> Weight { + 1_000_000_000 + } + fn force_new_era(_i: u32) -> Weight { + 1_000_000_000 + } + fn force_new_era_always(_i: u32) -> Weight { + 1_000_000_000 + } + fn set_invulnerables(_v: u32) -> Weight { + 1_000_000_000 + } + fn force_unstake(_s: u32) -> Weight { + 1_000_000_000 + } + fn cancel_deferred_slash(_s: u32) -> Weight { + 1_000_000_000 + } + fn payout_stakers(_n: u32) -> Weight { + 1_000_000_000 + } + fn payout_stakers_alive_controller(_n: u32) -> Weight { + 1_000_000_000 + } + fn set_history_depth(_e: u32) -> Weight { + 1_000_000_000 + } + fn reap_stash(_s: u32) -> Weight { + 1_000_000_000 + } + fn new_era(_v: u32, _n: u32) -> Weight { + 1_000_000_000 + } + fn do_slash(_l: u32) -> Weight { + 1_000_000_000 + } + fn payout_all(_v: u32, _n: u32) -> Weight { + 1_000_000_000 + } + fn submit_solution_initial(_v: u32, _n: u32, _a: u32, _w: u32) -> Weight { + 1_000_000_000 + } + fn submit_solution_better(_v: u32, _n: u32, _a: u32, _w: u32) -> Weight { + 1_000_000_000 + } + fn submit_solution_weaker(_v: u32, _n: u32) -> Weight { + 1_000_000_000 } } -impl pallet_session::SessionManager for Module { - fn new_session(new_index: SessionIndex) -> Option> { - Self::new_session(new_index) - } - fn end_session(end_index: SessionIndex) { - Self::end_session(end_index) +/// Indicates the initial status of the staker. +#[derive(RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum StakerStatus { + /// Chilling. + Idle, + /// Declared desire in validating or already participating in it. + Validator, + /// Nominating for a group of other stakers. + Nominator(Vec), +} + +/// A destination account for payment. +#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, RuntimeDebug)] +pub enum RewardDestination { + /// Pay into the stash account, increasing the amount at stake accordingly. + Staked { promise_month: u8 }, + /// Pay into the stash account, not increasing the amount at stake. + Stash, + /// Pay into the controller account. + Controller, +} +impl Default for RewardDestination { + fn default() -> Self { + RewardDestination::Staked { promise_month: 0 } } - fn start_session(start_index: SessionIndex) { - Self::start_session(start_index) +} + +/// Mode of era-forcing. +#[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum Forcing { + /// Not forcing anything - just let whatever happen. + NotForcing, + /// Force a new era, then reset to `NotForcing` as soon as it is done. + ForceNew, + /// Avoid a new era indefinitely. + ForceNone, + /// Force a new era at the end of all sessions indefinitely. + ForceAlways, +} +impl Default for Forcing { + fn default() -> Self { + Forcing::NotForcing } } -impl pallet_session::historical::SessionManager> - for Module -{ - fn new_session(new_index: SessionIndex) -> Option)>> { - >::new_session(new_index).map(|validators| { - let current_era = Self::current_era() - // Must be some as a new era has been created. - .unwrap_or(0); +/// Indicate how an election round was computed. +#[derive(PartialEq, Eq, Clone, Copy, Encode, Decode, RuntimeDebug)] +pub enum ElectionCompute { + /// Result was forcefully computed on chain at the end of the session. + OnChain, + /// Result was submitted and accepted to the chain via a signed transaction. + Signed, + /// Result was submitted and accepted to the chain via an unsigned transaction (by an + /// authority). + Unsigned, +} - validators - .into_iter() - .map(|v| { - let exposure = Self::eras_stakers(current_era, &v); - (v, exposure) - }) - .collect() - }) +/// The status of the upcoming (offchain) election. +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +pub enum ElectionStatus { + /// Nothing has and will happen for now. submission window is not open. + Closed, + /// The submission window has been open since the contained block number. + Open(BlockNumber), +} +impl ElectionStatus { + fn is_open_at(&self, n: BlockNumber) -> bool { + *self == Self::Open(n) } - fn start_session(start_index: SessionIndex) { - >::start_session(start_index) + + fn is_closed(&self) -> bool { + match self { + Self::Closed => true, + _ => false, + } } - fn end_session(end_index: SessionIndex) { - >::end_session(end_index) + + fn is_open(&self) -> bool { + !self.is_closed() + } +} +impl Default for ElectionStatus { + fn default() -> Self { + Self::Closed } } -/// Add reward points to block authors: -/// * 20 points to the block producer for producing a (non-uncle) block in the relay chain, -/// * 2 points to the block producer for each reference to a previously unreferenced uncle, and -/// * 1 point to the producer of each referenced uncle block. -impl pallet_authorship::EventHandler for Module +/// To unify *RING* and *KTON* balances. +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +pub enum StakingBalance where - T: Trait + pallet_authorship::Trait + pallet_session::Trait, + RingBalance: HasCompact, + KtonBalance: HasCompact, { - fn note_author(author: T::AccountId) { - Self::reward_by_ids(vec![(author, 20)]); - } - fn note_uncle(author: T::AccountId, _age: T::BlockNumber) { - Self::reward_by_ids(vec![ - (>::author(), 2), - (author, 1), - ]); + RingBalance(RingBalance), + KtonBalance(KtonBalance), +} +impl Default for StakingBalance +where + RingBalance: Default + HasCompact, + KtonBalance: Default + HasCompact, +{ + fn default() -> Self { + StakingBalance::RingBalance(Default::default()) } } -/// A `Convert` implementation that finds the stash of the given controller account, -/// if any. -pub struct StashOf(PhantomData); - -impl Convert> for StashOf { - fn convert(controller: T::AccountId) -> Option { - >::ledger(&controller).map(|l| l.stash) - } +/// Information regarding the active era (era in used in session). +#[derive(Debug, Encode, Decode)] +pub struct ActiveEraInfo { + /// Index of era. + pub index: EraIndex, + /// Moment of start expressed as millisecond from `$UNIX_EPOCH`. + /// + /// Start can be none if start hasn't been set for the era yet, + /// Start is set on the first on_finalize of the era to guarantee usage of `Time`. + start: Option, } -/// A typed conversion from stash account ID to the active exposure of nominators -/// on that account. +/// Reward points of an era. Used to split era total payout between validators. /// -/// Active exposure is the exposure of the validator set currently validating, i.e. in -/// `active_era`. It can differ from the latest planned exposure in `current_era`. -pub struct ExposureOf(PhantomData); +/// This points will be used to reward validators and their respective nominators. +#[derive(PartialEq, Encode, Decode, Default, Debug)] +pub struct EraRewardPoints { + /// Total number of points. Equals the sum of reward points for each validator. + total: RewardPoint, + /// The reward points earned by a given validator. + individual: BTreeMap, +} -impl Convert>> for ExposureOf { - fn convert(validator: T::AccountId) -> Option> { - if let Some(active_era) = >::active_era() { - Some(>::eras_stakers(active_era.index, &validator)) - } else { - None - } - } +/// Preference of what happens regarding validation. +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +pub struct ValidatorPrefs { + /// Reward that validator takes up-front; only the rest is split between themselves and + /// nominators. + #[codec(compact)] + pub commission: Perbill, } -/// This is intended to be used with `FilterHistoricalOffences`. -impl - OnOffenceHandler, Weight> - for Module -where - T: pallet_session::Trait>, - T: pallet_session::historical::Trait< - FullIdentification = ExposureT, - FullIdentificationOf = ExposureOf, - >, - T::SessionHandler: pallet_session::SessionHandler>, - T::SessionManager: pallet_session::SessionManager>, - T::ValidatorIdOf: Convert, Option>>, -{ - fn on_offence( - offenders: &[OffenceDetails< - T::AccountId, - pallet_session::historical::IdentificationTuple, - >], - slash_fraction: &[Perbill], - slash_session: SessionIndex, - ) -> Result { - if !Self::can_report() { - return Err(()); +impl Default for ValidatorPrefs { + fn default() -> Self { + ValidatorPrefs { + commission: Default::default(), } + } +} - let reward_proportion = SlashRewardFraction::get(); - let mut consumed_weight: Weight = 0; - let mut add_db_reads_writes = |reads, writes| { - consumed_weight += T::DbWeight::get().reads_writes(reads, writes); - }; +/// The ledger of a (bonded) stash. +#[derive(PartialEq, Eq, Clone, Default, Encode, Decode, RuntimeDebug)] +pub struct StakingLedger +where + RingBalance: HasCompact, + KtonBalance: HasCompact, +{ + /// The stash account whose balance is actually locked and at stake. + pub stash: AccountId, - let active_era = { - let active_era = Self::active_era(); - add_db_reads_writes(1, 0); - if active_era.is_none() { - // this offence need not be re-submitted. - return Ok(consumed_weight); - } - active_era - .expect("value checked not to be `None`; qed") - .index - }; - let active_era_start_session_index = Self::eras_start_session_index(active_era) - .unwrap_or_else(|| { - frame_support::print("Error: start_session_index must be set for current_era"); - 0 - }); - add_db_reads_writes(1, 0); + /// The total amount of the stash's *RING* that will be at stake in any forthcoming + /// rounds. + #[codec(compact)] + pub active_ring: RingBalance, + // active time-deposit ring + #[codec(compact)] + pub active_deposit_ring: RingBalance, - let window_start = active_era.saturating_sub(T::BondingDurationInEra::get()); + /// The total amount of the stash's *KTON* that will be at stake in any forthcoming + /// rounds. + #[codec(compact)] + pub active_kton: KtonBalance, - // fast path for active-era report - most likely. - // `slash_session` cannot be in a future active era. It must be in `active_era` or before. - let slash_era = if slash_session >= active_era_start_session_index { - active_era - } else { - let eras = BondedEras::get(); - add_db_reads_writes(1, 0); + // If you deposit *RING* for a minimum period, + // you can get *KTON* as bonus which can also be used for staking. + pub deposit_items: Vec>, - // reverse because it's more likely to find reports from recent eras. - match eras - .iter() - .rev() - .filter(|&&(_, ref sesh)| sesh <= &slash_session) - .next() - { - Some(&(ref slash_era, _)) => *slash_era, - // before bonding period. defensive - should be filtered out. - None => return Ok(consumed_weight), - } - }; + // TODO doc + pub ring_staking_lock: StakingLock, + // TODO doc + pub kton_staking_lock: StakingLock, - ::EarliestUnappliedSlash::mutate(|earliest| { - if earliest.is_none() { - *earliest = Some(active_era) - } - }); - add_db_reads_writes(1, 1); + /// List of eras for which the stakers behind a validator have claimed rewards. Only updated + /// for validators. + pub claimed_rewards: Vec, +} +impl + StakingLedger +where + RingBalance: AtLeast32BitUnsigned + Saturating + Copy, + KtonBalance: AtLeast32BitUnsigned + Saturating + Copy, + BlockNumber: PartialOrd, + TsInMs: PartialOrd, +{ + /// Slash the validator for a given amount of balance. This can grow the value + /// of the slash in the case that the validator has less than `minimum_balance` + /// active funds. Returns the amount of funds actually slashed. + /// + /// Slashes from `active` funds first, and then `unlocking`, starting with the + /// chunks that are closest to unlocking. + fn slash( + &mut self, + slash_ring: RingBalance, + slash_kton: KtonBalance, + bn: BlockNumber, + ts: TsInMs, + ) -> (RingBalance, KtonBalance) { + let slash_out_of = |active_ring: &mut RingBalance, + active_deposit_ring: &mut RingBalance, + deposit_item: &mut Vec>, + active_kton: &mut KtonBalance, + slash_ring: &mut RingBalance, + slash_kton: &mut KtonBalance| { + let slashable_active_ring = (*slash_ring).min(*active_ring); + let slashable_active_kton = (*slash_kton).min(*active_kton); - let slash_defer_duration = T::SlashDeferDuration::get(); + if !slashable_active_ring.is_zero() { + let slashable_normal_ring = *active_ring - *active_deposit_ring; + if let Some(mut slashable_deposit_ring) = + slashable_active_ring.checked_sub(&slashable_normal_ring) + { + *active_deposit_ring -= slashable_deposit_ring; - let invulnerables = Self::invulnerables(); - add_db_reads_writes(1, 0); + deposit_item.drain_filter(|item| { + if ts >= item.expire_time { + true + } else { + if slashable_deposit_ring.is_zero() { + false + } else { + if let Some(new_slashable_deposit_ring) = + slashable_deposit_ring.checked_sub(&item.value) + { + slashable_deposit_ring = new_slashable_deposit_ring; + true + } else { + item.value -= sp_std::mem::replace( + &mut slashable_deposit_ring, + Zero::zero(), + ); + false + } + } + } + }); + } - for (details, slash_fraction) in offenders.iter().zip(slash_fraction) { - let (stash, exposure) = &details.offender; + *active_ring -= slashable_active_ring; + *slash_ring -= slashable_active_ring; + } - // Skip if the validator is invulnerable. - if invulnerables.contains(stash) { - continue; + if !slashable_active_kton.is_zero() { + *active_kton -= slashable_active_kton; + *slash_kton -= slashable_active_kton; } + }; - let unapplied = slashing::compute_slash::(slashing::SlashParams { - stash, - slash: *slash_fraction, - exposure, - slash_era, - window_start, - now: active_era, - reward_proportion, - }); + let (mut apply_slash_ring, mut apply_slash_kton) = (slash_ring, slash_kton); + let StakingLedger { + active_ring, + active_deposit_ring, + deposit_items, + active_kton, + ring_staking_lock, + kton_staking_lock, + .. + } = self; - if let Some(mut unapplied) = unapplied { - let nominators_len = unapplied.others.len() as u64; - let reporters_len = details.reporters.len() as u64; + slash_out_of( + active_ring, + active_deposit_ring, + deposit_items, + active_kton, + &mut apply_slash_ring, + &mut apply_slash_kton, + ); - { - let upper_bound = 1 /* Validator/NominatorSlashInEra */ + 2 /* fetch_spans */; - let rw = upper_bound + nominators_len * upper_bound; - add_db_reads_writes(rw, rw); - } - unapplied.reporters = details.reporters.clone(); - if slash_defer_duration == 0 { - // apply right away. - slashing::apply_slash::(unapplied); - { - let slash_cost = (6, 5); - let reward_cost = (2, 2); - add_db_reads_writes( - (1 + nominators_len) * slash_cost.0 + reward_cost.0 * reporters_len, - (1 + nominators_len) * slash_cost.1 + reward_cost.1 * reporters_len, - ); - } + if !apply_slash_ring.is_zero() { + ring_staking_lock.unbondings.drain_filter(|lock| { + if bn >= lock.until { + true } else { - // defer to end of some `slash_defer_duration` from now. - ::UnappliedSlashes::mutate(active_era, move |for_later| { - for_later.push(unapplied) - }); - add_db_reads_writes(1, 1); + if apply_slash_ring.is_zero() { + false + } else { + if apply_slash_ring > lock.amount { + apply_slash_ring -= lock.amount; + true + } else { + lock.amount -= + sp_std::mem::replace(&mut apply_slash_ring, Zero::zero()); + false + } + } } - } else { - add_db_reads_writes(4 /* fetch_spans */, 5 /* kick_out_if_recent */) - } + }); } + if !apply_slash_kton.is_zero() { + kton_staking_lock.unbondings.drain_filter(|lock| { + if bn >= lock.until { + true + } else { + if apply_slash_kton.is_zero() { + false + } else { + if apply_slash_kton > lock.amount { + apply_slash_kton -= lock.amount; - Ok(consumed_weight) - } - - fn can_report() -> bool { - Self::era_election_status().is_closed() - } -} - -/// Filter historical offences out and only allow those from the bonding period. -pub struct FilterHistoricalOffences { - _inner: PhantomData<(T, R)>, -} -impl ReportOffence - for FilterHistoricalOffences, R> -where - T: Trait, - R: ReportOffence, - O: Offence, -{ - fn report_offence(reporters: Vec, offence: O) -> Result<(), OffenceError> { - // disallow any slashing from before the current bonding period. - let offence_session = offence.session_index(); - let bonded_eras = BondedEras::get(); - - if bonded_eras - .first() - .filter(|(_, start)| offence_session >= *start) - .is_some() - { - R::report_offence(reporters, offence) - } else { - >::deposit_event(RawEvent::OldSlashingReportDiscarded(offence_session)); - Ok(()) + true + } else { + lock.amount -= + sp_std::mem::replace(&mut apply_slash_kton, Zero::zero()); + false + } + } + } + }); } + + (slash_ring - apply_slash_ring, slash_kton - apply_slash_kton) } } -impl OnDepositRedeem> for Module { - fn on_deposit_redeem( - backing: &T::AccountId, - start_time: TsInMs, - months: u8, - amount: RingBalance, - stash: &T::AccountId, - ) -> DispatchResult { - let controller = Self::bonded(&stash).ok_or(>::NotStash)?; - let ledger = Self::ledger(&controller).ok_or(>::NotController)?; - - // The timestamp unit is different between Ethereum and Darwinia, converting from seconds to milliseconds - let start_time = start_time * 1000; - let promise_month = months.min(36); - - // let stash_balance = T::Ring::free_balance(&stash); - - // TODO: Lock but no kton reward because this is a deposit redeem - // let extra = extra.min(r); +/// The *RING* under deposit. +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +pub struct TimeDepositItem { + #[codec(compact)] + pub value: RingBalance, + #[codec(compact)] + pub start_time: TsInMs, + #[codec(compact)] + pub expire_time: TsInMs, +} - T::RingCurrency::transfer(&backing, &stash, amount, KeepAlive)?; +/// A record of the nominations made by a specific account. +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +pub struct Nominations { + /// The targets of nomination. + pub targets: Vec, + /// The era the nominations were submitted. + /// + /// Except for initial nominations which are considered submitted at era 0. + pub submitted_in: EraIndex, + /// Whether the nominations have been suppressed. + pub suppressed: bool, +} - let (start_time, expire_time) = Self::bond_ring_for_deposit_redeem( - &controller, - amount, - start_time, - promise_month, - ledger, - ); +/// A snapshot of the stake backing a single validator in the system. +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, RuntimeDebug)] +pub struct Exposure +where + RingBalance: HasCompact, + KtonBalance: HasCompact, +{ + /// The validator's own stash that is exposed. + #[codec(compact)] + pub own_ring_balance: RingBalance, + #[codec(compact)] + pub own_kton_balance: KtonBalance, + pub own_power: Power, + /// The total balance backing this validator. + pub total_power: Power, + /// The portions of nominators stashes that are exposed. + pub others: Vec>, +} - >::mutate(|r| *r += amount); - // TODO: Should we deposit an different event? - >::deposit_event(RawEvent::BondRing(amount, start_time, expire_time)); +/// The amount of exposure (to slashing) than an individual nominator has. +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, RuntimeDebug)] +pub struct IndividualExposure +where + RingBalance: HasCompact, + KtonBalance: HasCompact, +{ + /// The stash account of the nominator in question. + who: AccountId, + /// Amount of funds exposed. + #[codec(compact)] + ring_balance: RingBalance, + #[codec(compact)] + kton_balance: KtonBalance, + power: Power, +} - Ok(()) - } +/// A pending slash record. The value of the slash has been computed but not applied yet, +/// rather deferred for several eras. +#[derive(Encode, Decode, Default, RuntimeDebug)] +pub struct UnappliedSlash { + /// The stash ID of the offending validator. + validator: AccountId, + /// The validator's own slash. + own: slashing::RK, + /// All other slashed stakers and amounts. + others: Vec<(AccountId, slashing::RK)>, + /// Reporters of the offence; bounty payout recipients. + reporters: Vec, + /// The amount of payout. + payout: slashing::RK, } -#[allow(deprecated)] -impl frame_support::unsigned::ValidateUnsigned for Module { - type Call = Call; - fn validate_unsigned(source: TransactionSource, call: &Self::Call) -> TransactionValidity { - if let Call::submit_election_solution_unsigned(_, _, score, era, _) = call { - // --- substrate --- - use offchain_election::DEFAULT_LONGEVITY; +/// Some indications about the size of the election. This must be submitted with the solution. +/// +/// Note that these values must reflect the __total__ number, not only those that are present in the +/// solution. In short, these should be the same size as the size of the values dumped in +/// `SnapshotValidators` and `SnapshotNominators`. +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, Default)] +pub struct ElectionSize { + /// Number of validators in the snapshot of the current election round. + #[codec(compact)] + pub validators: ValidatorIndex, + /// Number of nominators in the snapshot of the current election round. + #[codec(compact)] + pub nominators: NominatorIndex, +} - // discard solution not coming from the local OCW. - match source { - TransactionSource::Local | TransactionSource::InBlock => { /* allowed */ } - _ => { - log!( - debug, - "rejecting unsigned transaction because it is not local/in-block." - ); - return InvalidTransaction::Call.into(); - } - } +/// The result of an election round. +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +pub struct ElectionResult { + /// Flat list of validators who have been elected. + elected_stashes: Vec, + /// Flat list of new exposures, to be updated in the [`Exposure`] storage. + exposures: Vec<(AccountId, Exposure)>, + /// Type of the result. This is kept on chain only to track and report the best score's + /// submission type. An optimisation could remove this. + compute: ElectionCompute, +} - if let Err(error_with_post_info) = Self::pre_dispatch_checks(*score, *era) { - let invalid = to_invalid(error_with_post_info); - log!( - debug, - "validate unsigned pre dispatch checks failed due to error #{:?}.", - invalid, - ); - return invalid.into(); - } +// --- trait --- - log!( - debug, - "validateUnsigned succeeded for a solution at era {}.", - era - ); +/// Means for interacting with a specialized version of the `session` trait. +/// +/// This is needed because `Staking` sets the `ValidatorIdOf` of the `pallet_session::Trait` +pub trait SessionInterface: frame_system::Trait { + /// Disable a given validator by stash ID. + /// + /// Returns `true` if new era should be forced at the end of this session. + /// This allows preventing a situation where there is too many validators + /// disabled and block production stalls. + fn disable_validator(validator: &AccountId) -> Result; + /// Get the validators from session. + fn validators() -> Vec; + /// Prune historical session tries up to but not including the given index. + fn prune_historical_up_to(up_to: SessionIndex); +} +impl SessionInterface> for T +where + T: pallet_session::Trait>, + T: pallet_session::historical::Trait< + FullIdentification = Exposure, RingBalance, KtonBalance>, + FullIdentificationOf = ExposureOf, + >, + T::SessionHandler: pallet_session::SessionHandler>, + T::SessionManager: pallet_session::SessionManager>, + T::ValidatorIdOf: Convert, Option>>, +{ + fn disable_validator(validator: &AccountId) -> Result { + >::disable(validator) + } - ValidTransaction::with_tag_prefix("StakingOffchain") - // The higher the score[0], the better a solution is. - .priority(T::UnsignedPriority::get().saturating_add(score[0].saturated_into())) - // Defensive only. A single solution can exist in the pool per era. Each validator - // will run OCW at most once per era, hence there should never exist more than one - // transaction anyhow. - .and_provides(era) - // Note: this can be more accurate in the future. We do something like - // `era_end_block - current_block` but that is not needed now as we eagerly run - // offchain workers now and the above should be same as `T::ElectionLookahead` - // without the need to query more storage in the validation phase. If we randomize - // offchain worker, then we might re-consider this. - .longevity( - TryInto::::try_into(T::ElectionLookahead::get()) - .unwrap_or(DEFAULT_LONGEVITY), - ) - // We don't propagate this. This can never the validated at a remote node. - .propagate(false) - .build() - } else { - InvalidTransaction::Call.into() - } + fn validators() -> Vec> { + >::validators() } - fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError> { - if let Call::submit_election_solution_unsigned(_, _, score, era, _) = call { - // IMPORTANT NOTE: These checks are performed in the dispatch call itself, yet we need - // to duplicate them here to prevent a block producer from putting a previously - // validated, yet no longer valid solution on chain. - // OPTIMISATION NOTE: we could skip this in the `submit_election_solution_unsigned` - // since we already do it here. The signed version needs it though. Yer for now we keep - // this duplicate check here so both signed and unsigned can use a singular - // `check_and_replace_solution`. - Self::pre_dispatch_checks(*score, *era) - .map(|_| ()) - .map_err(to_invalid) - .map_err(Into::into) - } else { - Err(InvalidTransaction::Call.into()) - } + fn prune_historical_up_to(up_to: SessionIndex) { + >::prune_up_to(up_to); } } diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index ba5b717c0f..d7de61bfc7 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -100,7 +100,7 @@ impl_outer_event! { } impl_outer_origin! { - pub enum Origin for Test where system = system {} + pub enum Origin for Test where system = system {} } darwinia_support::impl_account_data! { @@ -257,6 +257,7 @@ impl frame_system::Trait for Test { type AccountData = AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } sp_runtime::impl_opaque_keys! { @@ -278,6 +279,7 @@ impl pallet_session::Trait for Test { type SessionHandler = (OtherSessionHandler,); type Keys = SessionKeys; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; + type WeightInfo = (); } impl pallet_session::historical::Trait for Test { @@ -302,6 +304,7 @@ impl pallet_timestamp::Trait for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); } impl darwinia_balances::Trait for Test { @@ -311,6 +314,7 @@ impl darwinia_balances::Trait for Test { type ExistentialDeposit = ExistentialDeposit; type BalanceInfo = AccountData; type AccountStore = System; + type WeightInfo = (); type DustCollector = (Kton,); } impl darwinia_balances::Trait for Test { @@ -320,6 +324,7 @@ impl darwinia_balances::Trait for Test { type ExistentialDeposit = ExistentialDeposit; type BalanceInfo = AccountData; type AccountStore = System; + type WeightInfo = (); type DustCollector = (Ring,); } @@ -339,7 +344,7 @@ impl Trait for Test { type BondingDurationInEra = BondingDurationInEra; type BondingDurationInBlockNumber = BondingDurationInBlockNumber; type SlashDeferDuration = SlashDeferDuration; - type SlashCancelOrigin = system::EnsureRoot; + type SlashCancelOrigin = frame_system::EnsureRoot; type SessionInterface = Self; type NextNewSession = Session; type ElectionLookahead = ElectionLookahead; @@ -348,6 +353,7 @@ impl Trait for Test { type MinSolutionScoreBump = MinSolutionScoreBump; type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; type UnsignedPriority = UnsignedPriority; + type WeightInfo = (); type RingCurrency = Ring; type RingRewardRemainder = RingRewardRemainderMock; type RingSlash = (); diff --git a/frame/staking/src/slashing.rs b/frame/staking/src/slashing.rs index be8797b42d..159841f68e 100644 --- a/frame/staking/src/slashing.rs +++ b/frame/staking/src/slashing.rs @@ -478,7 +478,7 @@ fn slash_nominators( let own_slash_difference = own_slash_by_validator.saturating_sub(own_slash_prior); let mut era_slash = as Store>::NominatorSlashInEra::get(&slash_era, stash) - .unwrap_or(Zero::zero()); + .unwrap_or_else(|| Zero::zero()); era_slash += own_slash_difference; diff --git a/frame/staking/src/substrate_tests.rs b/frame/staking/src/substrate_tests.rs index 815de6593a..9ecfc7c460 100644 --- a/frame/staking/src/substrate_tests.rs +++ b/frame/staking/src/substrate_tests.rs @@ -1732,7 +1732,7 @@ fn bond_with_no_staked_value() { } #[test] -fn bond_with_little_staked_value_bounded_by_slot_stake() { +fn bond_with_little_staked_value_bounded() { // Behavior when someone bonds with little staked value. // Particularly when she votes and the candidate is elected. ExtBuilder::default() @@ -1821,6 +1821,165 @@ fn bond_with_little_staked_value_bounded_by_slot_stake() { }); } +#[test] +fn bond_with_duplicate_vote_should_be_ignored_by_npos_election() { + ExtBuilder::default() + .validator_count(2) + .nominate(false) + .minimum_validator_count(1) + .build() + .execute_with(|| { + // disable the nominator + assert_ok!(Staking::chill(Origin::signed(100))); + // make stakes equal. + assert_ok!(Staking::bond_extra( + Origin::signed(31), + StakingBalance::RingBalance(999), + 0 + )); + + assert_eq!( + >::iter() + .map(|(v, _)| (v, Staking::ledger(v - 1).unwrap().active_ring)) + .collect::>(), + vec![(31, 1000), (21, 1000), (11, 1000)], + ); + assert_eq!( + >::iter() + .map(|(n, _)| n) + .collect::>(), + vec![] + ); + + // give the man some money + let initial_balance = 1000; + for i in [1, 2, 3, 4].iter() { + let _ = Ring::make_free_balance_be(i, initial_balance); + } + + assert_ok!(Staking::bond( + Origin::signed(1), + 2, + StakingBalance::RingBalance(1000), + RewardDestination::Controller, + 0 + )); + assert_ok!(Staking::nominate( + Origin::signed(2), + vec![11, 11, 11, 21, 31,] + )); + + assert_ok!(Staking::bond( + Origin::signed(3), + 4, + StakingBalance::RingBalance(1000), + RewardDestination::Controller, + 0 + )); + assert_ok!(Staking::nominate(Origin::signed(4), vec![21, 31])); + + // winners should be 21 and 31. Otherwise this election is taking duplicates into account. + + let sp_npos_elections::ElectionResult { + winners, + assignments, + } = Staking::do_phragmen::().unwrap(); + let winners = sp_npos_elections::to_without_backing(winners); + + assert_eq!(winners, vec![31, 21]); + // only distribution to 21 and 31. + assert_eq!( + assignments + .iter() + .find(|a| a.who == 1) + .unwrap() + .distribution + .len(), + 2 + ); + }); +} + +#[test] +fn bond_with_duplicate_vote_should_be_ignored_by_npos_election_elected() { + // same as above but ensures that even when the duple is being elected, everything is sane. + ExtBuilder::default() + .validator_count(2) + .nominate(false) + .minimum_validator_count(1) + .build() + .execute_with(|| { + // disable the nominator + assert_ok!(Staking::chill(Origin::signed(100))); + // make stakes equal. + assert_ok!(Staking::bond_extra( + Origin::signed(31), + StakingBalance::RingBalance(99), + 0 + )); + + assert_eq!( + >::iter() + .map(|(v, _)| (v, Staking::ledger(v - 1).unwrap().active_ring)) + .collect::>(), + vec![(31, 100), (21, 1000), (11, 1000)], + ); + assert_eq!( + >::iter() + .map(|(n, _)| n) + .collect::>(), + vec![] + ); + + // give the man some money + let initial_balance = 1000; + for i in [1, 2, 3, 4].iter() { + let _ = Ring::make_free_balance_be(i, initial_balance); + } + + assert_ok!(Staking::bond( + Origin::signed(1), + 2, + StakingBalance::RingBalance(1000), + RewardDestination::Controller, + 0 + )); + assert_ok!(Staking::nominate( + Origin::signed(2), + vec![11, 11, 11, 21, 31,] + )); + + assert_ok!(Staking::bond( + Origin::signed(3), + 4, + StakingBalance::RingBalance(1000), + RewardDestination::Controller, + 0 + )); + assert_ok!(Staking::nominate(Origin::signed(4), vec![21, 31])); + + // winners should be 21 and 31. Otherwise this election is taking duplicates into account. + + let sp_npos_elections::ElectionResult { + winners, + assignments, + } = Staking::do_phragmen::().unwrap(); + + let winners = sp_npos_elections::to_without_backing(winners); + assert_eq!(winners, vec![21, 11]); + // only distribution to 21 and 31. + assert_eq!( + assignments + .iter() + .find(|a| a.who == 1) + .unwrap() + .distribution + .len(), + 2 + ); + }); +} + #[test] fn new_era_elects_correct_number_of_validators() { ExtBuilder::default() diff --git a/frame/support/Cargo.toml b/frame/support/Cargo.toml index 0d2fb150a4..9e4f47dc5d 100644 --- a/frame/support/Cargo.toml +++ b/frame/support/Cargo.toml @@ -14,9 +14,9 @@ codec = { package = "parity-scale-codec", version = "1.3.4", default-features = num-traits = { version = "0.2.12", default-features = false } impl-trait-for-tuples = { version = "0.1.3" } # substrate -frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } ethereum-primitives = { default-features = false, path = "../../primitives/ethereum-primitives" } diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index d8e3275828..83f5922850 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -120,6 +120,16 @@ pub trait OnDepositRedeem { /// - Someone got slashed. /// - Someone paid for a transaction to be included. pub trait OnUnbalancedKton { + /// Handler for some imbalances. The different imbalances might have different origins or + /// meanings, dependent on the context. Will default to simply calling on_unbalanced for all + /// of them. Infallible. + fn on_unbalanceds(amounts: impl Iterator) + where + Imbalance: frame_support::traits::Imbalance, + { + Self::on_unbalanced(amounts.fold(Imbalance::zero(), |i, x| x.merge(i))) + } + /// Handler for some imbalance. Infallible. fn on_unbalanced(amount: Imbalance) { amount @@ -129,14 +139,11 @@ pub trait OnUnbalancedKton { /// Actually handle a non-zero imbalance. You probably want to implement this rather than /// `on_unbalanced`. - fn on_nonzero_unbalanced(amount: Imbalance); -} - -impl OnUnbalancedKton for () { fn on_nonzero_unbalanced(amount: Imbalance) { drop(amount); } } +impl OnUnbalancedKton for () {} // A regulator to adjust relay args for a specific chain // Implement this in runtime's impls diff --git a/frame/treasury/Cargo.toml b/frame/treasury/Cargo.toml index d82c0641de..d8790a649b 100644 --- a/frame/treasury/Cargo.toml +++ b/frame/treasury/Cargo.toml @@ -15,17 +15,18 @@ serde = { version = "1.0.114", optional = true, features = ["derive"] } # darwinia darwinia-support = { default-features = false, path = "../support" } # substrate -frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +frame-support = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +frame-system = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [dev-dependencies] # darwinia darwinia-balances = { path = "../balances" } # substrate -sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-io = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +sp-core = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-io = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-storage = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [features] default = ["std"] diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index 63591a05e0..2d0597c039 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -94,7 +94,7 @@ mod types { pub type KtonNegativeImbalance = as Currency>>::NegativeImbalance; - type AccountId = ::AccountId; + type AccountId = ::AccountId; type RingCurrency = ::RingCurrency; type KtonCurrency = ::KtonCurrency; } @@ -113,7 +113,7 @@ use frame_support::{ weights::{DispatchClass, Weight}, Parameter, }; -use frame_system::{self as system, ensure_signed}; +use frame_system::ensure_signed; use sp_runtime::{ traits::{ AccountIdConversion, AtLeast32BitUnsigned, BadOrigin, Hash, Saturating, StaticLookup, Zero, @@ -182,47 +182,15 @@ pub trait Trait: frame_system::Trait { /// Percentage of spare funds (if any) that are burnt per spend period. type Burn: Get; -} -/// A spending proposal. -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] -pub struct Proposal { - /// The account proposing it. - proposer: AccountId, - /// The account to whom the payment should be made if the proposal is accepted. - beneficiary: AccountId, - /// The (total) *RING* that should be paid if the proposal is accepted. - ring_value: RingBalance, - /// The (total) *KTON* that should be paid if the proposal is accepted. - kton_value: KtonBalance, - /// The *RING* held on deposit (reserved) for making this proposal. - ring_bond: RingBalance, - /// The *KTON* held on deposit (reserved) for making this proposal. - kton_bond: KtonBalance, -} + /// Handler for the unbalanced decrease when treasury funds are burned. + type RingBurnDestination: OnUnbalanced>; -/// An open tipping "motion". Retains all details of a tip including information on the finder -/// and the members who have voted. -#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] -pub struct OpenTip< - AccountId: Parameter, - RingBalance: Parameter, - BlockNumber: Parameter, - Hash: Parameter, -> { - /// The hash of the reason for the tip. The reason should be a human-readable UTF-8 encoded string. A URL would be - /// sensible. - reason: Hash, - /// The account to be tipped. - who: AccountId, - /// The account who began this tip and the amount held on deposit. - finder: Option<(AccountId, RingBalance)>, - /// The block number at which this tip will close if `Some`. If `None`, then no closing is - /// scheduled. - closes: Option, - /// The members who have voted for this tip. Sorted by AccountId. - tips: Vec<(AccountId, RingBalance)>, + /// Handler for the unbalanced decrease when treasury funds are burned. + type KtonBurnDestination: OnUnbalancedKton>; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } decl_storage! { @@ -269,29 +237,29 @@ decl_event!( RingBalance = RingBalance, KtonBalance = KtonBalance, { - /// New proposal. + /// New proposal. [proposal_index] Proposed(ProposalIndex), - /// We have ended a spend period and will now allocate funds. + /// We have ended a spend period and will now allocate funds. [budget_remaining] Spending(RingBalance, KtonBalance), - /// Some funds have been allocated. + /// Some funds have been allocated. [proposal_index, award, beneficiary] Awarded(ProposalIndex, RingBalance, KtonBalance, AccountId), - /// A proposal was rejected; funds were slashed. + /// A proposal was rejected; funds were slashed. [proposal_index, slashed] Rejected(ProposalIndex, RingBalance, KtonBalance), - /// Some of our funds have been burnt. + /// Some of our funds have been burnt. [burn] Burnt(RingBalance, KtonBalance), - /// Spending has finished; this is the amount that rolls over until next spend. + /// Spending has finished; this is the amount that rolls over until next spend. [budget_remaining] Rollover(RingBalance, KtonBalance), - /// Some *RING* have been deposited. + /// Some *RING* have been deposited. [deposit] DepositRing(RingBalance), - /// Some *KTON* have been deposited. + /// Some *KTON* have been deposited. [deposit] DepositKton(KtonBalance), - /// A new tip suggestion has been opened. + /// A new tip suggestion has been opened. [tip_hash] NewTip(Hash), - /// A tip suggestion has reached threshold and is closing. + /// A tip suggestion has reached threshold and is closing. [tip_hash] TipClosing(Hash), - /// A tip suggestion has been closed. + /// A tip suggestion has been closed. [tip_hash, who, payout] TipClosed(Hash, AccountId, RingBalance), - /// A tip suggestion has been retracted. + /// A tip suggestion has been retracted. [tip_hash] TipRetracted(Hash), } ); @@ -475,8 +443,15 @@ decl_module! { T::RingCurrency::reserve(&finder, deposit)?; >::insert(&reason_hash, &reason); - let finder = Some((finder, deposit)); - let tip = OpenTip { reason: reason_hash, who, finder, closes: None, tips: vec![] }; + let tip = OpenTip { + reason: reason_hash, + who, + finder, + deposit, + closes: None, + tips: vec![], + finders_fee: true + }; >::insert(&hash, tip); Self::deposit_event(RawEvent::NewTip(hash)); } @@ -504,12 +479,13 @@ decl_module! { fn retract_tip(origin, hash: T::Hash) { let who = ensure_signed(origin)?; let tip = >::get(&hash).ok_or(>::UnknownTip)?; - let (finder, deposit) = tip.finder.ok_or(>::NotFinder)?; - ensure!(finder == who, >::NotFinder); + ensure!(tip.finder == who, >::NotFinder); >::remove(&tip.reason); >::remove(&hash); - let _ = T::RingCurrency::unreserve(&who, deposit); + if !tip.deposit.is_zero() { + let _ = T::RingCurrency::unreserve(&who, tip.deposit); + } Self::deposit_event(RawEvent::TipRetracted(hash)); } @@ -548,8 +524,16 @@ decl_module! { >::insert(&reason_hash, &reason); Self::deposit_event(RawEvent::NewTip(hash.clone())); - let tips = vec![(tipper, tip_value)]; - let tip = OpenTip { reason: reason_hash, who, finder: None, closes: None, tips }; + let tips = vec![(tipper.clone(), tip_value)]; + let tip = OpenTip { + reason: reason_hash, + who, + finder: tipper, + deposit: Zero::zero(), + closes: None, + tips, + finders_fee: false, + }; >::insert(&hash, tip); } @@ -728,15 +712,17 @@ impl Module { let treasury = Self::account_id(); let max_payout = Self::pot::(); let mut payout = tips[tips.len() / 2].1.min(max_payout); - if let Some((finder, deposit)) = tip.finder { - let _ = T::RingCurrency::unreserve(&finder, deposit); - if finder != tip.who { + if !tip.deposit.is_zero() { + let _ = T::RingCurrency::unreserve(&tip.finder, tip.deposit); + } + if tip.finders_fee { + if tip.finder != tip.who { // pay out the finder's fee. let finders_fee = T::TipFindersFee::get() * payout; payout -= finders_fee; // this should go through given we checked it's at most the free balance, but still // we only make a best-effort. - let _ = T::RingCurrency::transfer(&treasury, &finder, finders_fee, KeepAlive); + let _ = T::RingCurrency::transfer(&treasury, &tip.finder, finders_fee, KeepAlive); } } // same as above: best-effort only. @@ -824,7 +810,10 @@ impl Module { // burn some proportion of the remaining budget if we run a surplus. let burn = (T::Burn::get() * budget_remaining_ring).min(budget_remaining_ring); budget_remaining_ring -= burn; - imbalance_ring.subsume(T::RingCurrency::burn(burn)); + + let (debit, credit) = T::RingCurrency::pair(burn); + imbalance_ring.subsume(debit); + T::RingBurnDestination::on_unbalanced(credit); burn } else { @@ -833,7 +822,10 @@ impl Module { let burn_kton = if !miss_any_kton { let burn = (T::Burn::get() * budget_remaining_kton).min(budget_remaining_kton); budget_remaining_kton -= burn; - imbalance_kton.subsume(T::KtonCurrency::burn(burn)); + + let (debit, credit) = T::KtonCurrency::pair(burn); + imbalance_kton.subsume(debit); + T::KtonBurnDestination::on_unbalanced(credit); burn } else { @@ -876,6 +868,57 @@ impl Module { prior_approvals_len } + + pub fn migrate_retract_tip_for_tip_new() { + /// An open tipping "motion". Retains all details of a tip including information on the finder + /// and the members who have voted. + #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] + pub struct OldOpenTip< + AccountId: Parameter, + RingBalance: Parameter, + BlockNumber: Parameter, + Hash: Parameter, + > { + /// The hash of the reason for the tip. The reason should be a human-readable UTF-8 encoded string. A URL would be + /// sensible. + reason: Hash, + /// The account to be tipped. + who: AccountId, + /// The account who began this tip and the amount held on deposit. + finder: Option<(AccountId, RingBalance)>, + /// The block number at which this tip will close if `Some`. If `None`, then no closing is + /// scheduled. + closes: Option, + /// The members who have voted for this tip. Sorted by AccountId. + tips: Vec<(AccountId, RingBalance)>, + } + + // --- substrate --- + use frame_support::{migration::StorageKeyIterator, Twox64Concat}; + + for (hash, old_tip) in StorageKeyIterator::< + T::Hash, + OldOpenTip, T::BlockNumber, T::Hash>, + Twox64Concat, + >::new(b"DarwiniaTreasury", b"Tips") + .drain() + { + let (finder, deposit, finders_fee) = match old_tip.finder { + Some((finder, deposit)) => (finder, deposit, true), + None => (T::AccountId::default(), Zero::zero(), false), + }; + let new_tip = OpenTip { + reason: old_tip.reason, + who: old_tip.who, + finder, + deposit, + closes: old_tip.closes, + tips: old_tip.tips, + finders_fee, + }; + >::insert(hash, new_tip) + } + } } impl OnUnbalanced> for Module { @@ -888,7 +931,6 @@ impl OnUnbalanced> for Module { Self::deposit_event(RawEvent::DepositRing(numeric_amount)); } } - // FIXME: Ugly hack due to https://github.com/rust-lang/rust/issues/31844#issuecomment-557918823 impl OnUnbalancedKton> for Module { fn on_nonzero_unbalanced(amount: KtonNegativeImbalance) { @@ -900,3 +942,90 @@ impl OnUnbalancedKton> for Module { Self::deposit_event(RawEvent::DepositKton(numeric_amount)); } } + +pub trait WeightInfo { + fn propose_spend(u: u32) -> Weight; + fn reject_proposal(u: u32) -> Weight; + fn approve_proposal(u: u32) -> Weight; + fn report_awesome(r: u32) -> Weight; + fn retract_tip(r: u32) -> Weight; + fn tip_new(r: u32, t: u32) -> Weight; + fn tip(t: u32) -> Weight; + fn close_tip(t: u32) -> Weight; + fn on_initialize(p: u32) -> Weight; +} + +impl WeightInfo for () { + fn propose_spend(_u: u32) -> Weight { + 1_000_000_000 + } + fn reject_proposal(_u: u32) -> Weight { + 1_000_000_000 + } + fn approve_proposal(_u: u32) -> Weight { + 1_000_000_000 + } + fn report_awesome(_r: u32) -> Weight { + 1_000_000_000 + } + fn retract_tip(_r: u32) -> Weight { + 1_000_000_000 + } + fn tip_new(_r: u32, _t: u32) -> Weight { + 1_000_000_000 + } + fn tip(_t: u32) -> Weight { + 1_000_000_000 + } + fn close_tip(_t: u32) -> Weight { + 1_000_000_000 + } + fn on_initialize(_p: u32) -> Weight { + 1_000_000_000 + } +} + +/// A spending proposal. +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] +pub struct Proposal { + /// The account proposing it. + proposer: AccountId, + /// The account to whom the payment should be made if the proposal is accepted. + beneficiary: AccountId, + /// The (total) *RING* that should be paid if the proposal is accepted. + ring_value: RingBalance, + /// The (total) *KTON* that should be paid if the proposal is accepted. + kton_value: KtonBalance, + /// The *RING* held on deposit (reserved) for making this proposal. + ring_bond: RingBalance, + /// The *KTON* held on deposit (reserved) for making this proposal. + kton_bond: KtonBalance, +} + +/// An open tipping "motion". Retains all details of a tip including information on the finder +/// and the members who have voted. +#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] +pub struct OpenTip< + AccountId: Parameter, + RingBalance: Parameter, + BlockNumber: Parameter, + Hash: Parameter, +> { + /// The hash of the reason for the tip. The reason should be a human-readable UTF-8 encoded string. A URL would be + /// sensible. + reason: Hash, + /// The account to be tipped. + who: AccountId, + /// The account who began this tip. + finder: AccountId, + /// The amount held on deposit for this tip. + deposit: RingBalance, + /// The block number at which this tip will close if `Some`. If `None`, then no closing is + /// scheduled. + closes: Option, + /// The members who have voted for this tip. Sorted by AccountId. + tips: Vec<(AccountId, RingBalance)>, + /// Whether this tip should result in the finder taking a fee. + finders_fee: bool, +} diff --git a/frame/treasury/src/mock.rs b/frame/treasury/src/mock.rs index 03de66ea4f..ef6fdaf47f 100644 --- a/frame/treasury/src/mock.rs +++ b/frame/treasury/src/mock.rs @@ -50,7 +50,7 @@ thread_local! { impl_outer_event! { pub enum MockEvent for Test { - system, + frame_system, darwinia_balances Instance0, darwinia_balances Instance1, treasury, @@ -58,7 +58,7 @@ impl_outer_event! { } impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } #[derive(Clone, Eq, PartialEq)] @@ -95,6 +95,7 @@ impl frame_system::Trait for Test { type AccountData = AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } pub struct TenToFourteen; @@ -130,6 +131,7 @@ impl darwinia_balances::Trait for Test { type ExistentialDeposit = ExistentialDeposit; type BalanceInfo = AccountData; type AccountStore = System; + type WeightInfo = (); type DustCollector = (); } impl darwinia_balances::Trait for Test { @@ -139,6 +141,7 @@ impl darwinia_balances::Trait for Test { type ExistentialDeposit = ExistentialDeposit; type BalanceInfo = AccountData; type AccountStore = System; + type WeightInfo = (); type DustCollector = (); } @@ -173,6 +176,9 @@ impl Trait for Test { type KtonProposalBondMinimum = KtonProposalBondMinimum; type SpendPeriod = SpendPeriod; type Burn = Burn; + type RingBurnDestination = (); // Just gets burned. + type KtonBurnDestination = (); // Just gets burned. + type WeightInfo = (); } pub fn new_test_ext() -> sp_io::TestExternalities { diff --git a/frame/treasury/src/tests.rs b/frame/treasury/src/tests.rs index 8b1da58fe8..349fc0b11f 100644 --- a/frame/treasury/src/tests.rs +++ b/frame/treasury/src/tests.rs @@ -203,6 +203,28 @@ fn retract_tip_works() { Treasury::close_tip(Origin::signed(0), h.into()), >::UnknownTip ); + + // with tip new + Ring::make_free_balance_be(&Treasury::account_id(), 101); + assert_ok!(Treasury::tip_new( + Origin::signed(10), + b"awesome.darwinia".to_vec(), + 3, + 10 + )); + let h = tip_hash(); + assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); + assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); + assert_noop!( + Treasury::retract_tip(Origin::signed(0), h.clone()), + >::NotFinder + ); + assert_ok!(Treasury::retract_tip(Origin::signed(10), h.clone())); + System::set_block_number(2); + assert_noop!( + Treasury::close_tip(Origin::signed(10), h.into()), + >::UnknownTip + ); }); } @@ -727,3 +749,97 @@ fn no_accept_no_reject_keep_burning() { assert_eq!(Treasury::pot::(), 25); // No changes from last perid }); } + +#[test] +fn test_last_reward_migration() { + use sp_storage::Storage; + + let mut s = Storage::default(); + + #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] + pub struct OldOpenTip< + AccountId: Parameter, + RingBalance: Parameter, + BlockNumber: Parameter, + Hash: Parameter, + > { + /// The hash of the reason for the tip. The reason should be a human-readable UTF-8 encoded string. A URL would be + /// sensible. + reason: Hash, + /// The account to be tipped. + who: AccountId, + /// The account who began this tip and the amount held on deposit. + finder: Option<(AccountId, RingBalance)>, + /// The block number at which this tip will close if `Some`. If `None`, then no closing is + /// scheduled. + closes: Option, + /// The members who have voted for this tip. Sorted by AccountId. + tips: Vec<(AccountId, RingBalance)>, + } + + let reason1 = BlakeTwo256::hash(b"reason1"); + let hash1 = BlakeTwo256::hash_of(&(reason1, 10u64)); + + let old_tip_finder = OldOpenTip:: { + reason: reason1, + who: 10, + finder: Some((20, 30)), + closes: Some(13), + tips: vec![(40, 50), (60, 70)], + }; + + let reason2 = BlakeTwo256::hash(b"reason2"); + let hash2 = BlakeTwo256::hash_of(&(reason2, 20u64)); + + let old_tip_no_finder = OldOpenTip:: { + reason: reason2, + who: 20, + finder: None, + closes: Some(13), + tips: vec![(40, 50), (60, 70)], + }; + + let data = vec![ + ( + >::hashed_key_for(hash1), + old_tip_finder.encode().to_vec(), + ), + ( + >::hashed_key_for(hash2), + old_tip_no_finder.encode().to_vec(), + ), + ]; + + s.top = data.into_iter().collect(); + sp_io::TestExternalities::new(s).execute_with(|| { + Treasury::migrate_retract_tip_for_tip_new(); + + // Test w/ finder + assert_eq!( + >::get(hash1), + Some(OpenTip { + reason: reason1, + who: 10, + finder: 20, + deposit: 30, + closes: Some(13), + tips: vec![(40, 50), (60, 70)], + finders_fee: true, + }) + ); + + // Test w/o finder + assert_eq!( + >::get(hash2), + Some(OpenTip { + reason: reason2, + who: 20, + finder: Default::default(), + deposit: 0, + closes: Some(13), + tips: vec![(40, 50), (60, 70)], + finders_fee: false, + }) + ); + }); +} diff --git a/primitives/array-bytes/Cargo.toml b/primitives/array-bytes/Cargo.toml index 28b165cba6..be9d7966b8 100644 --- a/primitives/array-bytes/Cargo.toml +++ b/primitives/array-bytes/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/darwinia-network/darwinia-common/" [dependencies] # substrate -sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [features] default = ["std"] diff --git a/primitives/ethereum-primitives/Cargo.toml b/primitives/ethereum-primitives/Cargo.toml index 40377f1a00..5adc924d3d 100644 --- a/primitives/ethereum-primitives/Cargo.toml +++ b/primitives/ethereum-primitives/Cargo.toml @@ -27,9 +27,9 @@ primitive-types = { default-features = false, features = ["codec", "rlp"], git = rlp = { default-features = false, git = "https://github.com/darwinia-network/parity-common.git" } rlp-derive = { git = "https://github.com/darwinia-network/parity-common.git" } # substrate -sp-io = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } -sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +sp-io = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-runtime = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } +sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [dev-dependencies] # crates @@ -38,7 +38,7 @@ serde_json = { version = "1.0.57" } # github triehash = { git = "https://github.com/darwinia-network/parity-common.git" } # substrate -frame-support = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +frame-support = { git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [features] default = ["std"] diff --git a/primitives/merkle-patricia-trie/Cargo.toml b/primitives/merkle-patricia-trie/Cargo.toml index a93bddd884..e4806de2e5 100644 --- a/primitives/merkle-patricia-trie/Cargo.toml +++ b/primitives/merkle-patricia-trie/Cargo.toml @@ -15,7 +15,7 @@ hashbrown = { version = "0.8.1" } hash = { package = "keccak-hash", default-features = false, git = "https://github.com/darwinia-network/parity-common.git" } rlp = { default-features = false, git = "https://github.com/darwinia-network/parity-common.git" } # substrate -sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.3" } +sp-std = { default-features = false, git = "https://github.com/darwinia-network/substrate.git", tag = "v2.0.0-rc.darwinia.4" } [dev-dependencies] # crates