From dbd7f0e0fb8a28b70a84eb446f274312d157745b Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 3 Apr 2020 16:59:26 +0300 Subject: [PATCH 01/92] solidity contract --- Cargo.lock | 1840 ++++++++++++----- Cargo.toml | 1 + modules/ethereum-contract/builtin/Cargo.toml | 17 + modules/ethereum-contract/builtin/src/lib.rs | 50 + .../contracts/substrate-bridge.sol | 197 ++ 5 files changed, 1628 insertions(+), 477 deletions(-) create mode 100644 modules/ethereum-contract/builtin/Cargo.toml create mode 100644 modules/ethereum-contract/builtin/src/lib.rs create mode 100644 modules/ethereum-contract/contracts/substrate-bridge.sol diff --git a/Cargo.lock b/Cargo.lock index c45f4e0845..8d64574779 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -166,7 +166,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d0864d84b8e07b145449be9a8537db86bf9de5ce03b913214694643b4743502" dependencies = [ - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -219,7 +219,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25f9db3b38af870bf7e5cc649167533b493928e50744e2c30ae350230b414670" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -344,7 +344,7 @@ dependencies = [ "log 0.4.8", "peeking_take_while", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "regex", "rustc-hash", "shlex", @@ -371,9 +371,13 @@ checksum = "5da9b3d9f6f585199287a473f4f8dfab6566cf827d15c00c219f53c645687ead" [[package]] name = "bitvec" -version = "0.15.2" +version = "0.17.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a993f74b4c99c1908d156b8d2e0fb6277736b0ecbd833982fd1241d39b2766a6" +checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" +dependencies = [ + "either", + "radium", +] [[package]] name = "blake2" @@ -446,21 +450,21 @@ dependencies = [ "log 0.4.8", "sc-basic-authorship", "sc-cli", - "sc-client", + "sc-client 0.8.0-alpha.2", "sc-consensus-aura", - "sc-executor", - "sc-finality-grandpa", - "sc-network", + "sc-executor 0.8.0-alpha.2", + "sc-finality-grandpa 0.8.0-alpha.2", + "sc-network 0.8.0-alpha.2", "sc-service", "sc-transaction-pool", "sp-bridge-eth-poa", - "sp-consensus", + "sp-consensus 0.8.0-alpha.2", "sp-consensus-aura", - "sp-core", - "sp-finality-grandpa", - "sp-inherents", - "sp-runtime", - "sp-transaction-pool", + "sp-core 2.0.0-alpha.2", + "sp-finality-grandpa 2.0.0-alpha.2", + "sp-inherents 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-transaction-pool 2.0.0-alpha.2", "structopt", "substrate-build-script-utils", "vergen", @@ -483,19 +487,19 @@ dependencies = [ "pallet-transaction-payment", "parity-scale-codec", "serde", - "sp-api", - "sp-block-builder", + "sp-api 2.0.0-alpha.2", + "sp-block-builder 2.0.0-alpha.2", "sp-bridge-eth-poa", "sp-consensus-aura", - "sp-core", - "sp-inherents", - "sp-io", + "sp-core 2.0.0-alpha.2", + "sp-inherents 2.0.0-alpha.2", + "sp-io 2.0.0-alpha.2", "sp-offchain", - "sp-runtime", + "sp-runtime 2.0.0-alpha.2", "sp-session", - "sp-std", - "sp-transaction-pool", - "sp-version", + "sp-std 2.0.0-alpha.2", + "sp-transaction-pool 2.0.0-alpha.2", + "sp-version 2.0.0-alpha.2", "substrate-wasm-builder-runner", ] @@ -900,7 +904,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2323f3f47db9a0e77ce7a300605d8d2098597fc451ed1a97bb1f6411bb550a7" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -1031,6 +1035,15 @@ dependencies = [ "tiny-keccak 2.0.1", ] +[[package]] +name = "ethereum-contract-builtin" +version = "0.1.0" +dependencies = [ + "bridge-node-runtime", + "parity-scale-codec", + "sc-finality-grandpa 0.8.0-alpha.5", +] + [[package]] name = "ethereum-poa-relay" version = "0.1.0" @@ -1054,9 +1067,9 @@ dependencies = [ "serde", "serde_json", "sp-bridge-eth-poa", - "sp-core", - "sp-keyring", - "sp-runtime", + "sp-core 2.0.0-alpha.2", + "sp-keyring 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", "time 0.2.9", "web3", ] @@ -1143,7 +1156,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", "synstructure 0.12.3", ] @@ -1165,9 +1178,9 @@ dependencies = [ [[package]] name = "finality-grandpa" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cbb25bef9fcad97fb31e817da280b1c9174435b8769c770ee190a330dd181ea" +checksum = "024517816630be5204eba201e8d1d405042b1255a5e0e3f298b054fc24d59e1d" dependencies = [ "futures 0.3.4", "futures-timer 2.0.2", @@ -1250,16 +1263,25 @@ dependencies = [ "parity-scale-codec", ] +[[package]] +name = "fork-tree" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2b3ac9016db4aa757dcab0a52c6911e6c98820d29bc75092176b98e73582bb" +dependencies = [ + "parity-scale-codec", +] + [[package]] name = "frame-benchmarking" version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "parity-scale-codec", - "sp-api", - "sp-io", - "sp-runtime-interface", - "sp-std", + "sp-api 2.0.0-alpha.2", + "sp-io 2.0.0-alpha.2", + "sp-runtime-interface 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", ] [[package]] @@ -1271,9 +1293,9 @@ dependencies = [ "frame-system", "parity-scale-codec", "serde", - "sp-io", - "sp-runtime", - "sp-std", + "sp-io 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", ] [[package]] @@ -1283,8 +1305,8 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "parity-scale-codec", "serde", - "sp-core", - "sp-std", + "sp-core 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", ] [[package]] @@ -1301,13 +1323,13 @@ dependencies = [ "parity-scale-codec", "paste", "serde", - "sp-arithmetic", - "sp-core", - "sp-inherents", - "sp-io", - "sp-runtime", - "sp-state-machine", - "sp-std", + "sp-arithmetic 2.0.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-inherents 2.0.0-alpha.2", + "sp-io 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-state-machine 0.8.0-alpha.2", + "sp-std 2.0.0-alpha.2", "tracing", ] @@ -1318,7 +1340,7 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "frame-support-procedural-tools", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -1330,7 +1352,7 @@ dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -1340,7 +1362,7 @@ version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -1353,11 +1375,11 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-version", + "sp-core 2.0.0-alpha.2", + "sp-io 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", + "sp-version 2.0.0-alpha.2", ] [[package]] @@ -1498,7 +1520,7 @@ checksum = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7" dependencies = [ "proc-macro-hack", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -2011,7 +2033,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -2121,7 +2143,7 @@ checksum = "8609af8f63b626e8e211f52441fcdb6ec54f1a446606b10d5c89ae9bf8a20058" dependencies = [ "proc-macro-crate", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -2221,7 +2243,7 @@ source = "git+https://github.com/paritytech/jsonrpsee#a0bea41c4f37125fa742ec48b1 dependencies = [ "Inflector", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -2257,7 +2279,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03080afe6f42cd996da9f568d6add5d7fb5ee2ea7fb7802d2d2cbd836958fd87" dependencies = [ "parity-bytes", - "parity-util-mem", + "parity-util-mem 0.5.1", + "smallvec 1.2.0", +] + +[[package]] +name = "kvdb" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cad096c6849b2ef027fabe35c4aed356d0e3d3f586d0a8361e5e17f1e50a7ce5" +dependencies = [ + "parity-util-mem 0.6.0", "smallvec 1.2.0", ] @@ -2267,8 +2299,8 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9355274e5a9e0a7e8ef43916950eae3949024de2a8dffe4d5a6c13974a37c8e" dependencies = [ - "kvdb", - "parity-util-mem", + "kvdb 0.4.0", + "parity-util-mem 0.5.1", "parking_lot 0.10.0", ] @@ -2280,11 +2312,11 @@ checksum = "af36fd66ccd99f3f771ae39b75aaba28b952372b6debfb971134bf1f03466ab2" dependencies = [ "fs-swap", "interleaved-ordered", - "kvdb", + "kvdb 0.4.0", "log 0.4.8", "num_cpus", "owning_ref", - "parity-util-mem", + "parity-util-mem 0.5.1", "parking_lot 0.10.0", "regex", "rocksdb", @@ -2402,7 +2434,7 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d472e9d522f588805c77801de10b957be84e10f019ca5f869fa1825b15ea9b" dependencies = [ - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -2865,7 +2897,19 @@ dependencies = [ "ahash 0.2.18", "hash-db", "hashbrown 0.6.3", - "parity-util-mem", + "parity-util-mem 0.5.1", +] + +[[package]] +name = "memory-db" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f58381b20ebe2c578e75dececd9da411414903415349548ccc46aac3209cdfbc" +dependencies = [ + "ahash 0.2.18", + "hash-db", + "hashbrown 0.6.3", + "parity-util-mem 0.6.0", ] [[package]] @@ -2886,6 +2930,18 @@ dependencies = [ "zeroize 1.1.0", ] +[[package]] +name = "merlin" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6feca46f4fa3443a01769d768727f10c10a20fdb65e52dc16a81f0c8269bb78" +dependencies = [ + "byteorder 1.3.4", + "keccak", + "rand_core 0.5.1", + "zeroize 1.1.0", +] + [[package]] name = "mime" version = "0.2.6" @@ -3034,8 +3090,8 @@ name = "node-primitives" version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ - "sp-core", - "sp-runtime", + "sp-core 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", ] [[package]] @@ -3190,14 +3246,14 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "serde", - "sp-application-crypto", + "sp-application-crypto 2.0.0-alpha.2", "sp-consensus-aura", - "sp-core", - "sp-inherents", - "sp-io", - "sp-runtime", - "sp-std", - "sp-timestamp", + "sp-core 2.0.0-alpha.2", + "sp-inherents 2.0.0-alpha.2", + "sp-io 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", + "sp-timestamp 2.0.0-alpha.2", ] [[package]] @@ -3210,9 +3266,9 @@ dependencies = [ "frame-system", "parity-scale-codec", "serde", - "sp-io", - "sp-runtime", - "sp-std", + "sp-io 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", ] [[package]] @@ -3225,12 +3281,12 @@ dependencies = [ "pallet-session", "parity-scale-codec", "serde", - "sp-core", - "sp-finality-grandpa", - "sp-io", - "sp-runtime", - "sp-state-machine", - "sp-trie", + "sp-core 2.0.0-alpha.2", + "sp-finality-grandpa 2.0.0-alpha.2", + "sp-io 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-state-machine 0.8.0-alpha.2", + "sp-trie 2.0.0-alpha.2", ] [[package]] @@ -3243,9 +3299,9 @@ dependencies = [ "parity-scale-codec", "serde", "sp-bridge-eth-poa", - "sp-io", - "sp-runtime", - "sp-std", + "sp-io 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", ] [[package]] @@ -3258,10 +3314,10 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "serde", - "sp-finality-tracker", - "sp-inherents", - "sp-runtime", - "sp-std", + "sp-finality-tracker 2.0.0-alpha.2", + "sp-inherents 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", ] [[package]] @@ -3275,11 +3331,11 @@ dependencies = [ "pallet-session", "parity-scale-codec", "serde", - "sp-core", - "sp-finality-grandpa", - "sp-runtime", + "sp-core 2.0.0-alpha.2", + "sp-finality-grandpa 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", "sp-staking", - "sp-std", + "sp-std 2.0.0-alpha.2", ] [[package]] @@ -3291,8 +3347,8 @@ dependencies = [ "frame-system", "parity-scale-codec", "safe-mix", - "sp-runtime", - "sp-std", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", ] [[package]] @@ -3306,11 +3362,11 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "serde", - "sp-io", - "sp-runtime", + "sp-io 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", "sp-staking", - "sp-std", - "sp-trie", + "sp-std 2.0.0-alpha.2", + "sp-trie 2.0.0-alpha.2", ] [[package]] @@ -3322,9 +3378,9 @@ dependencies = [ "frame-system", "parity-scale-codec", "serde", - "sp-io", - "sp-runtime", - "sp-std", + "sp-io 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", ] [[package]] @@ -3338,11 +3394,11 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "serde", - "sp-inherents", - "sp-io", - "sp-runtime", - "sp-std", - "sp-timestamp", + "sp-inherents 2.0.0-alpha.2", + "sp-io 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", + "sp-timestamp 2.0.0-alpha.2", ] [[package]] @@ -3354,8 +3410,8 @@ dependencies = [ "frame-system", "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", - "sp-runtime", - "sp-std", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", ] [[package]] @@ -3366,9 +3422,9 @@ dependencies = [ "frame-support", "parity-scale-codec", "serde", - "sp-api", - "sp-runtime", - "sp-std", + "sp-api 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", ] [[package]] @@ -3492,9 +3548,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "1.1.2" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f747c06d9f3b2ad387ac881b9667298c81b1243aa9833f086e05996937c35507" +checksum = "329c8f7f4244ddb5c37c103641027a76c530e65e8e4b8240b29f81ea40508b17" dependencies = [ "arrayvec 0.5.1", "bitvec", @@ -3505,13 +3561,13 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34e513ff3e406f3ede6796dcdc83d0b32ffb86668cea1ccf7363118abeb00476" +checksum = "5a0ec292e92e8ec7c58e576adacc1e3f399c597c8f263c42f18420abe58e7245" dependencies = [ "proc-macro-crate", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -3536,6 +3592,20 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "parity-util-mem" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e42755f26e5ea21a6a819d9e63cbd70713e9867a2b767ec2cc65ca7659532c5" +dependencies = [ + "cfg-if", + "impl-trait-for-tuples", + "parity-util-mem-derive", + "parking_lot 0.10.0", + "primitive-types 0.7.0", + "winapi 0.3.8", +] + [[package]] name = "parity-util-mem-derive" version = "0.1.0" @@ -3621,7 +3691,7 @@ checksum = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5" dependencies = [ "proc-macro-hack", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -3684,7 +3754,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -3764,7 +3834,7 @@ checksum = "e7959c6467d962050d639361f7703b2051c43036d03493c36f01d440fdd3138a" dependencies = [ "proc-macro-error-attr", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", "version_check 0.9.1", ] @@ -3776,7 +3846,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4002d9f55991d5e019fb940a90e1a95eb80c24e77cb2462dd4dc869604d543a" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", "syn-mid", "version_check 0.9.1", @@ -3789,7 +3859,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -3882,7 +3952,7 @@ dependencies = [ "anyhow", "itertools", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -3930,13 +4000,19 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" +checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" dependencies = [ "proc-macro2 1.0.8", ] +[[package]] +name = "radium" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" + [[package]] name = "rand" version = "0.3.23" @@ -4300,7 +4376,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -4364,17 +4440,17 @@ dependencies = [ "futures 0.3.4", "log 0.4.8", "parity-scale-codec", - "sc-block-builder", - "sc-client", - "sc-client-api", - "sc-telemetry", - "sp-api", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-inherents", - "sp-runtime", - "sp-transaction-pool", + "sc-block-builder 0.8.0-alpha.2", + "sc-client 0.8.0-alpha.2", + "sc-client-api 2.0.0-alpha.2", + "sc-telemetry 2.0.0-alpha.2", + "sp-api 2.0.0-alpha.2", + "sp-blockchain 2.0.0-alpha.2", + "sp-consensus 0.8.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-inherents 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-transaction-pool 2.0.0-alpha.2", "tokio-executor 0.2.0-alpha.6", ] @@ -4384,14 +4460,31 @@ version = "0.8.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "parity-scale-codec", - "sc-client-api", - "sp-api", - "sp-block-builder", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-runtime", - "sp-state-machine", + "sc-client-api 2.0.0-alpha.2", + "sp-api 2.0.0-alpha.2", + "sp-block-builder 2.0.0-alpha.2", + "sp-blockchain 2.0.0-alpha.2", + "sp-consensus 0.8.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-state-machine 0.8.0-alpha.2", +] + +[[package]] +name = "sc-block-builder" +version = "0.8.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "288d056ccb51111940a020cc4dda2b3ecd539ac680a20a7614b45b52615e1b62" +dependencies = [ + "parity-scale-codec", + "sc-client-api 2.0.0-alpha.5", + "sp-api 2.0.0-alpha.5", + "sp-block-builder 2.0.0-alpha.5", + "sp-blockchain 2.0.0-alpha.5", + "sp-consensus 0.8.0-alpha.5", + "sp-core 2.0.0-alpha.5", + "sp-runtime 2.0.0-alpha.5", + "sp-state-machine 0.8.0-alpha.5", ] [[package]] @@ -4401,12 +4494,12 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "impl-trait-for-tuples", "sc-chain-spec-derive", - "sc-network", - "sc-telemetry", + "sc-network 0.8.0-alpha.2", + "sc-telemetry 2.0.0-alpha.2", "serde", "serde_json", - "sp-core", - "sp-runtime", + "sp-core 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", ] [[package]] @@ -4416,7 +4509,7 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "proc-macro-crate", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -4437,23 +4530,23 @@ dependencies = [ "lazy_static", "log 0.4.8", "names", - "parity-util-mem", + "parity-util-mem 0.5.1", "prometheus-exporter", "regex", "rpassword", - "sc-client-api", + "sc-client-api 2.0.0-alpha.2", "sc-informant", - "sc-network", + "sc-network 0.8.0-alpha.2", "sc-service", - "sc-telemetry", + "sc-telemetry 2.0.0-alpha.2", "sc-tracing", "serde_json", - "sp-blockchain", - "sp-core", - "sp-keyring", - "sp-panic-handler", - "sp-runtime", - "sp-state-machine", + "sp-blockchain 2.0.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-keyring 2.0.0-alpha.2", + "sp-panic-handler 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-state-machine 0.8.0-alpha.2", "structopt", "time 0.1.42", "tokio 0.2.11", @@ -4469,26 +4562,61 @@ dependencies = [ "futures 0.3.4", "hash-db", "hex-literal", - "kvdb", + "kvdb 0.4.0", + "log 0.4.8", + "parity-scale-codec", + "parking_lot 0.10.0", + "sc-block-builder 0.8.0-alpha.2", + "sc-client-api 2.0.0-alpha.2", + "sc-executor 0.8.0-alpha.2", + "sc-telemetry 2.0.0-alpha.2", + "sp-api 2.0.0-alpha.2", + "sp-blockchain 2.0.0-alpha.2", + "sp-consensus 0.8.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-externalities 0.8.0-alpha.2", + "sp-inherents 2.0.0-alpha.2", + "sp-keyring 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-state-machine 0.8.0-alpha.2", + "sp-std 2.0.0-alpha.2", + "sp-trie 2.0.0-alpha.2", + "sp-version 2.0.0-alpha.2", + "tracing", +] + +[[package]] +name = "sc-client" +version = "0.8.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bc77d90c2647134251ed73494515106da17aeee66dd9f5ae067bfa061bb19c9" +dependencies = [ + "derive_more", + "fnv", + "futures 0.3.4", + "hash-db", + "hex-literal", + "kvdb 0.5.0", "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.0", - "sc-block-builder", - "sc-client-api", - "sc-executor", - "sc-telemetry", - "sp-api", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-externalities", - "sp-inherents", - "sp-keyring", - "sp-runtime", - "sp-state-machine", - "sp-std", - "sp-trie", - "sp-version", + "sc-block-builder 0.8.0-alpha.5", + "sc-client-api 2.0.0-alpha.5", + "sc-executor 0.8.0-alpha.5", + "sc-telemetry 2.0.0-alpha.5", + "sp-api 2.0.0-alpha.5", + "sp-blockchain 2.0.0-alpha.5", + "sp-consensus 0.8.0-alpha.5", + "sp-core 2.0.0-alpha.5", + "sp-externalities 0.8.0-alpha.5", + "sp-inherents 2.0.0-alpha.5", + "sp-keyring 2.0.0-alpha.5", + "sp-runtime 2.0.0-alpha.5", + "sp-state-machine 0.8.0-alpha.5", + "sp-std 2.0.0-alpha.5", + "sp-trie 2.0.0-alpha.5", + "sp-version 2.0.0-alpha.5", + "substrate-prometheus-endpoint", "tracing", ] @@ -4502,25 +4630,58 @@ dependencies = [ "futures 0.3.4", "hash-db", "hex-literal", - "kvdb", + "kvdb 0.4.0", + "log 0.4.8", + "parity-scale-codec", + "parking_lot 0.10.0", + "sc-executor 0.8.0-alpha.2", + "sc-telemetry 2.0.0-alpha.2", + "sp-api 2.0.0-alpha.2", + "sp-blockchain 2.0.0-alpha.2", + "sp-consensus 0.8.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-externalities 0.8.0-alpha.2", + "sp-inherents 2.0.0-alpha.2", + "sp-keyring 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-state-machine 0.8.0-alpha.2", + "sp-std 2.0.0-alpha.2", + "sp-transaction-pool 2.0.0-alpha.2", + "sp-trie 2.0.0-alpha.2", + "sp-version 2.0.0-alpha.2", +] + +[[package]] +name = "sc-client-api" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f17aa33afbc6b4f8c64a17922dff034c7d430919fc0835319f6663c8f4deddc" +dependencies = [ + "derive_more", + "fnv", + "futures 0.3.4", + "hash-db", + "hex-literal", + "kvdb 0.5.0", "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.0", - "sc-executor", - "sc-telemetry", - "sp-api", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-externalities", - "sp-inherents", - "sp-keyring", - "sp-runtime", - "sp-state-machine", - "sp-std", - "sp-transaction-pool", - "sp-trie", - "sp-version", + "sc-executor 0.8.0-alpha.5", + "sc-telemetry 2.0.0-alpha.5", + "sp-api 2.0.0-alpha.5", + "sp-blockchain 2.0.0-alpha.5", + "sp-consensus 0.8.0-alpha.5", + "sp-core 2.0.0-alpha.5", + "sp-externalities 0.8.0-alpha.5", + "sp-inherents 2.0.0-alpha.5", + "sp-keyring 2.0.0-alpha.5", + "sp-runtime 2.0.0-alpha.5", + "sp-state-machine 0.8.0-alpha.5", + "sp-std 2.0.0-alpha.5", + "sp-storage 2.0.0-alpha.5", + "sp-transaction-pool 2.0.0-alpha.5", + "sp-trie 2.0.0-alpha.5", + "sp-version 2.0.0-alpha.5", ] [[package]] @@ -4529,25 +4690,25 @@ version = "0.8.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "hash-db", - "kvdb", + "kvdb 0.4.0", "kvdb-memorydb", "kvdb-rocksdb", "linked-hash-map", "log 0.4.8", "parity-scale-codec", - "parity-util-mem", + "parity-util-mem 0.5.1", "parking_lot 0.10.0", "rand 0.7.3", - "sc-client", - "sc-client-api", - "sc-executor", + "sc-client 0.8.0-alpha.2", + "sc-client-api 2.0.0-alpha.2", + "sc-executor 0.8.0-alpha.2", "sc-state-db", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-runtime", - "sp-state-machine", - "sp-trie", + "sp-blockchain 2.0.0-alpha.2", + "sp-consensus 0.8.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-state-machine 0.8.0-alpha.2", + "sp-trie 2.0.0-alpha.2", ] [[package]] @@ -4561,23 +4722,23 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.0", - "sc-client", - "sc-client-api", + "sc-client 0.8.0-alpha.2", + "sc-client-api 2.0.0-alpha.2", "sc-consensus-slots", - "sc-keystore", - "sc-telemetry", - "sp-api", - "sp-application-crypto", - "sp-block-builder", - "sp-blockchain", - "sp-consensus", + "sc-keystore 2.0.0-alpha.2", + "sc-telemetry 2.0.0-alpha.2", + "sp-api 2.0.0-alpha.2", + "sp-application-crypto 2.0.0-alpha.2", + "sp-block-builder 2.0.0-alpha.2", + "sp-blockchain 2.0.0-alpha.2", + "sp-consensus 0.8.0-alpha.2", "sp-consensus-aura", - "sp-core", - "sp-inherents", - "sp-io", - "sp-runtime", - "sp-timestamp", - "sp-version", + "sp-core 2.0.0-alpha.2", + "sp-inherents 2.0.0-alpha.2", + "sp-io 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-timestamp 2.0.0-alpha.2", + "sp-version 2.0.0-alpha.2", ] [[package]] @@ -4590,15 +4751,15 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.0", - "sc-client-api", - "sc-telemetry", - "sp-api", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-inherents", - "sp-runtime", - "sp-state-machine", + "sc-client-api 2.0.0-alpha.2", + "sc-telemetry 2.0.0-alpha.2", + "sp-api 2.0.0-alpha.2", + "sp-blockchain 2.0.0-alpha.2", + "sp-consensus 0.8.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-inherents 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-state-machine 0.8.0-alpha.2", ] [[package]] @@ -4613,17 +4774,44 @@ dependencies = [ "parity-scale-codec", "parity-wasm", "parking_lot 0.10.0", - "sc-executor-common", - "sc-executor-wasmi", - "sp-core", - "sp-externalities", - "sp-io", - "sp-panic-handler", - "sp-runtime-interface", - "sp-serializer", - "sp-trie", - "sp-version", - "sp-wasm-interface", + "sc-executor-common 0.8.0-alpha.2", + "sc-executor-wasmi 0.8.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-externalities 0.8.0-alpha.2", + "sp-io 2.0.0-alpha.2", + "sp-panic-handler 2.0.0-alpha.2", + "sp-runtime-interface 2.0.0-alpha.2", + "sp-serializer 2.0.0-alpha.2", + "sp-trie 2.0.0-alpha.2", + "sp-version 2.0.0-alpha.2", + "sp-wasm-interface 2.0.0-alpha.2", + "wasmi", +] + +[[package]] +name = "sc-executor" +version = "0.8.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0ab992ed677c0d18c30a5a13f7a03af29a59cc74501c60e2e45eb35dc9467e5" +dependencies = [ + "derive_more", + "lazy_static", + "libsecp256k1", + "log 0.4.8", + "parity-scale-codec", + "parity-wasm", + "parking_lot 0.10.0", + "sc-executor-common 0.8.0-alpha.5", + "sc-executor-wasmi 0.8.0-alpha.5", + "sp-core 2.0.0-alpha.5", + "sp-externalities 0.8.0-alpha.5", + "sp-io 2.0.0-alpha.5", + "sp-panic-handler 2.0.0-alpha.5", + "sp-runtime-interface 2.0.0-alpha.5", + "sp-serializer 2.0.0-alpha.5", + "sp-trie 2.0.0-alpha.5", + "sp-version 2.0.0-alpha.5", + "sp-wasm-interface 2.0.0-alpha.5", "wasmi", ] @@ -4635,11 +4823,28 @@ dependencies = [ "derive_more", "log 0.4.8", "parity-scale-codec", - "sp-allocator", - "sp-core", - "sp-runtime-interface", - "sp-serializer", - "sp-wasm-interface", + "sp-allocator 2.0.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-runtime-interface 2.0.0-alpha.2", + "sp-serializer 2.0.0-alpha.2", + "sp-wasm-interface 2.0.0-alpha.2", + "wasmi", +] + +[[package]] +name = "sc-executor-common" +version = "0.8.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859a874cc47a01fb44bd53b172773629abb2c0d155b4e6505c1ec438103ffe5b" +dependencies = [ + "derive_more", + "log 0.4.8", + "parity-scale-codec", + "sp-allocator 2.0.0-alpha.5", + "sp-core 2.0.0-alpha.5", + "sp-runtime-interface 2.0.0-alpha.5", + "sp-serializer 2.0.0-alpha.5", + "sp-wasm-interface 2.0.0-alpha.5", "wasmi", ] @@ -4651,11 +4856,28 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "parity-wasm", - "sc-executor-common", - "sp-allocator", - "sp-core", - "sp-runtime-interface", - "sp-wasm-interface", + "sc-executor-common 0.8.0-alpha.2", + "sp-allocator 2.0.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-runtime-interface 2.0.0-alpha.2", + "sp-wasm-interface 2.0.0-alpha.2", + "wasmi", +] + +[[package]] +name = "sc-executor-wasmi" +version = "0.8.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4af5cb944a100efd2c117846b1f42da4e303c2a9e48d5231922315861775c558" +dependencies = [ + "log 0.4.8", + "parity-scale-codec", + "parity-wasm", + "sc-executor-common 0.8.0-alpha.5", + "sp-allocator 2.0.0-alpha.5", + "sp-core 2.0.0-alpha.5", + "sp-runtime-interface 2.0.0-alpha.5", + "sp-wasm-interface 2.0.0-alpha.5", "wasmi", ] @@ -4666,7 +4888,40 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "assert_matches", "finality-grandpa", - "fork-tree", + "fork-tree 2.0.0-alpha.2", + "futures 0.3.4", + "futures-timer 3.0.2", + "log 0.4.8", + "parity-scale-codec", + "parking_lot 0.10.0", + "pin-project", + "rand 0.7.3", + "sc-client 0.8.0-alpha.2", + "sc-client-api 2.0.0-alpha.2", + "sc-keystore 2.0.0-alpha.2", + "sc-network 0.8.0-alpha.2", + "sc-network-gossip 0.8.0-alpha.2", + "sc-telemetry 2.0.0-alpha.2", + "serde_json", + "sp-arithmetic 2.0.0-alpha.2", + "sp-blockchain 2.0.0-alpha.2", + "sp-consensus 0.8.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-finality-grandpa 2.0.0-alpha.2", + "sp-finality-tracker 2.0.0-alpha.2", + "sp-inherents 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", +] + +[[package]] +name = "sc-finality-grandpa" +version = "0.8.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aad8a1f0d03e8a7c3b1d8cd74050960365e347f739c131715f84f588dd051a4" +dependencies = [ + "assert_matches", + "finality-grandpa", + "fork-tree 2.0.0-alpha.5", "futures 0.3.4", "futures-timer 3.0.2", "log 0.4.8", @@ -4674,21 +4929,24 @@ dependencies = [ "parking_lot 0.10.0", "pin-project", "rand 0.7.3", - "sc-client", - "sc-client-api", - "sc-keystore", - "sc-network", - "sc-network-gossip", - "sc-telemetry", + "sc-block-builder 0.8.0-alpha.5", + "sc-client 0.8.0-alpha.5", + "sc-client-api 2.0.0-alpha.5", + "sc-keystore 2.0.0-alpha.5", + "sc-network 0.8.0-alpha.5", + "sc-network-gossip 0.8.0-alpha.5", + "sc-telemetry 2.0.0-alpha.5", "serde_json", - "sp-arithmetic", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-finality-grandpa", - "sp-finality-tracker", - "sp-inherents", - "sp-runtime", + "sp-api 2.0.0-alpha.5", + "sp-arithmetic 2.0.0-alpha.5", + "sp-blockchain 2.0.0-alpha.5", + "sp-consensus 0.8.0-alpha.5", + "sp-core 2.0.0-alpha.5", + "sp-finality-grandpa 2.0.0-alpha.5", + "sp-finality-tracker 2.0.0-alpha.5", + "sp-inherents 2.0.0-alpha.5", + "sp-runtime 2.0.0-alpha.5", + "substrate-prometheus-endpoint", ] [[package]] @@ -4699,12 +4957,12 @@ dependencies = [ "ansi_term 0.12.1", "futures 0.3.4", "log 0.4.8", - "parity-util-mem", - "sc-client-api", - "sc-network", + "parity-util-mem 0.5.1", + "sc-client-api 2.0.0-alpha.2", + "sc-network 0.8.0-alpha.2", "sc-service", - "sp-blockchain", - "sp-runtime", + "sp-blockchain 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", "wasm-timer", ] @@ -4718,8 +4976,24 @@ dependencies = [ "parking_lot 0.10.0", "rand 0.7.3", "serde_json", - "sp-application-crypto", - "sp-core", + "sp-application-crypto 2.0.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "subtle 2.2.2", +] + +[[package]] +name = "sc-keystore" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01c17c8aa8cb9fa4aa710379dc4e119b848cd65fa0a4e2209b6c0f97ee7c2c8a" +dependencies = [ + "derive_more", + "hex", + "parking_lot 0.10.0", + "rand 0.7.3", + "serde_json", + "sp-application-crypto 2.0.0-alpha.5", + "sp-core 2.0.0-alpha.5", "subtle 2.2.2", ] @@ -4734,7 +5008,58 @@ dependencies = [ "either", "erased-serde", "fnv", - "fork-tree", + "fork-tree 2.0.0-alpha.2", + "futures 0.3.4", + "futures-timer 3.0.2", + "futures_codec", + "libp2p", + "linked-hash-map", + "linked_hash_set", + "log 0.4.8", + "lru", + "nohash-hasher", + "parity-scale-codec", + "parking_lot 0.10.0", + "pin-project", + "prost", + "prost-build", + "rand 0.7.3", + "rustc-hex", + "sc-block-builder 0.8.0-alpha.2", + "sc-client 0.8.0-alpha.2", + "sc-client-api 2.0.0-alpha.2", + "sc-peerset 2.0.0-alpha.2", + "serde", + "serde_json", + "slog", + "slog_derive", + "smallvec 0.6.13", + "sp-arithmetic 2.0.0-alpha.2", + "sp-blockchain 2.0.0-alpha.2", + "sp-consensus 0.8.0-alpha.2", + "sp-consensus-babe 0.8.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "thiserror", + "unsigned-varint 0.3.1", + "void", + "wasm-timer", + "zeroize 1.1.0", +] + +[[package]] +name = "sc-network" +version = "0.8.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0df01faa65b22aca751910a417f5a6ea28cefd9d3349c17fbc2ad8b7f190d390" +dependencies = [ + "bitflags 1.2.1", + "bytes 0.5.4", + "derive_more", + "either", + "erased-serde", + "fnv", + "fork-tree 2.0.0-alpha.5", "futures 0.3.4", "futures-timer 3.0.2", "futures_codec", @@ -4751,21 +5076,22 @@ dependencies = [ "prost-build", "rand 0.7.3", "rustc-hex", - "sc-block-builder", - "sc-client", - "sc-client-api", - "sc-peerset", + "sc-block-builder 0.8.0-alpha.5", + "sc-client 0.8.0-alpha.5", + "sc-client-api 2.0.0-alpha.5", + "sc-peerset 2.0.0-alpha.5", "serde", "serde_json", "slog", "slog_derive", "smallvec 0.6.13", - "sp-arithmetic", - "sp-blockchain", - "sp-consensus", - "sp-consensus-babe", - "sp-core", - "sp-runtime", + "sp-arithmetic 2.0.0-alpha.5", + "sp-blockchain 2.0.0-alpha.5", + "sp-consensus 0.8.0-alpha.5", + "sp-consensus-babe 0.8.0-alpha.5", + "sp-core 2.0.0-alpha.5", + "sp-runtime 2.0.0-alpha.5", + "substrate-prometheus-endpoint", "thiserror", "unsigned-varint 0.3.1", "void", @@ -4784,8 +5110,24 @@ dependencies = [ "log 0.4.8", "lru", "parking_lot 0.10.0", - "sc-network", - "sp-runtime", + "sc-network 0.8.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "wasm-timer", +] + +[[package]] +name = "sc-network-gossip" +version = "0.8.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1eb8906bfd2d54f84fad8aba2f4303cff30f5596e7d4b90f97008d5477ea9ce4" +dependencies = [ + "futures 0.3.4", + "futures-timer 3.0.2", + "libp2p", + "log 0.4.8", + "lru", + "sc-network 0.8.0-alpha.5", + "sp-runtime 2.0.0-alpha.5", "wasm-timer", ] @@ -4805,13 +5147,13 @@ dependencies = [ "parity-scale-codec", "parking_lot 0.10.0", "rand 0.7.3", - "sc-client-api", - "sc-keystore", - "sc-network", - "sp-api", - "sp-core", + "sc-client-api 2.0.0-alpha.2", + "sc-keystore 2.0.0-alpha.2", + "sc-network 0.8.0-alpha.2", + "sp-api 2.0.0-alpha.2", + "sp-core 2.0.0-alpha.2", "sp-offchain", - "sp-runtime", + "sp-runtime 2.0.0-alpha.2", "threadpool", ] @@ -4827,6 +5169,19 @@ dependencies = [ "wasm-timer", ] +[[package]] +name = "sc-peerset" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a61bec2c8ace0c65c0cbd306b57a81eff12c92686b2988066d0ac49570944095" +dependencies = [ + "futures 0.3.4", + "libp2p", + "log 0.4.8", + "serde_json", + "wasm-timer", +] + [[package]] name = "sc-rpc" version = "2.0.0-alpha.2" @@ -4839,22 +5194,22 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.0", - "sc-client", - "sc-client-api", - "sc-executor", - "sc-keystore", + "sc-client 0.8.0-alpha.2", + "sc-client-api 2.0.0-alpha.2", + "sc-executor 0.8.0-alpha.2", + "sc-keystore 2.0.0-alpha.2", "sc-rpc-api", "serde_json", - "sp-api", - "sp-blockchain", - "sp-core", + "sp-api 2.0.0-alpha.2", + "sp-blockchain 2.0.0-alpha.2", + "sp-core 2.0.0-alpha.2", "sp-offchain", "sp-rpc", - "sp-runtime", + "sp-runtime 2.0.0-alpha.2", "sp-session", - "sp-state-machine", - "sp-transaction-pool", - "sp-version", + "sp-state-machine 0.8.0-alpha.2", + "sp-transaction-pool 2.0.0-alpha.2", + "sp-version 2.0.0-alpha.2", ] [[package]] @@ -4873,11 +5228,11 @@ dependencies = [ "parking_lot 0.10.0", "serde", "serde_json", - "sp-core", + "sp-core 2.0.0-alpha.2", "sp-rpc", - "sp-runtime", - "sp-transaction-pool", - "sp-version", + "sp-runtime 2.0.0-alpha.2", + "sp-transaction-pool 2.0.0-alpha.2", + "sp-version 2.0.0-alpha.2", ] [[package]] @@ -4892,7 +5247,7 @@ dependencies = [ "log 0.4.8", "serde", "serde_json", - "sp-runtime", + "sp-runtime 2.0.0-alpha.2", ] [[package]] @@ -4910,34 +5265,34 @@ dependencies = [ "log 0.4.8", "parity-multiaddr 0.5.0", "parity-scale-codec", - "parity-util-mem", + "parity-util-mem 0.5.1", "parking_lot 0.10.0", "prometheus-exporter", "sc-chain-spec", - "sc-client", - "sc-client-api", + "sc-client 0.8.0-alpha.2", + "sc-client-api 2.0.0-alpha.2", "sc-client-db", - "sc-executor", - "sc-keystore", - "sc-network", + "sc-executor 0.8.0-alpha.2", + "sc-keystore 2.0.0-alpha.2", + "sc-network 0.8.0-alpha.2", "sc-offchain", "sc-rpc", "sc-rpc-server", - "sc-telemetry", + "sc-telemetry 2.0.0-alpha.2", "sc-tracing", "sc-transaction-pool", "serde", "serde_json", "slog", - "sp-api", - "sp-application-crypto", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-io", - "sp-runtime", + "sp-api 2.0.0-alpha.2", + "sp-application-crypto 2.0.0-alpha.2", + "sp-blockchain 2.0.0-alpha.2", + "sp-consensus 0.8.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-io 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", "sp-session", - "sp-transaction-pool", + "sp-transaction-pool 2.0.0-alpha.2", "sysinfo", "target_info", "tracing", @@ -4952,7 +5307,7 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.0", - "sp-core", + "sp-core 2.0.0-alpha.2", ] [[package]] @@ -4977,6 +5332,29 @@ dependencies = [ "wasm-timer", ] +[[package]] +name = "sc-telemetry" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f358814b6fe2f2c726f708870d98d07f10d6ebb7d06dcf7f8f2781a868d24eb2" +dependencies = [ + "bytes 0.5.4", + "futures 0.3.4", + "futures-timer 3.0.2", + "libp2p", + "log 0.4.8", + "parking_lot 0.10.0", + "pin-project", + "rand 0.7.3", + "serde", + "slog", + "slog-json", + "slog-scope", + "take_mut", + "void", + "wasm-timer", +] + [[package]] name = "sc-tracing" version = "2.0.0-alpha.2" @@ -4985,7 +5363,7 @@ dependencies = [ "erased-serde", "log 0.4.8", "parking_lot 0.10.0", - "sc-telemetry", + "sc-telemetry 2.0.0-alpha.2", "serde", "serde_json", "slog", @@ -5001,13 +5379,13 @@ dependencies = [ "futures 0.3.4", "linked-hash-map", "log 0.4.8", - "parity-util-mem", + "parity-util-mem 0.5.1", "parking_lot 0.10.0", "serde", - "sp-blockchain", - "sp-core", - "sp-runtime", - "sp-transaction-pool", + "sp-blockchain 2.0.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-transaction-pool 2.0.0-alpha.2", "wasm-timer", ] @@ -5022,15 +5400,15 @@ dependencies = [ "futures-timer 2.0.2", "log 0.4.8", "parity-scale-codec", - "parity-util-mem", + "parity-util-mem 0.5.1", "parking_lot 0.10.0", - "sc-client-api", + "sc-client-api 2.0.0-alpha.2", "sc-transaction-graph", - "sp-api", - "sp-blockchain", - "sp-core", - "sp-runtime", - "sp-transaction-pool", + "sp-api 2.0.0-alpha.2", + "sp-blockchain 2.0.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-transaction-pool 2.0.0-alpha.2", "wasm-timer", ] @@ -5052,7 +5430,7 @@ checksum = "eacd8381b3c37840c9c9f40472af529e49975bdcbc24f83c31059fd6539023d3" dependencies = [ "curve25519-dalek 1.2.3", "failure", - "merlin", + "merlin 1.3.0", "rand 0.6.5", "rand_core 0.4.2", "rand_os", @@ -5062,13 +5440,31 @@ dependencies = [ ] [[package]] -name = "scoped-tls" -version = "0.1.2" +name = "schnorrkel" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" - -[[package]] -name = "scopeguard" +checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862" +dependencies = [ + "arrayref", + "arrayvec 0.5.1", + "curve25519-dalek 2.0.0", + "getrandom", + "merlin 2.0.0", + "rand 0.7.3", + "rand_core 0.5.1", + "sha2", + "subtle 2.2.2", + "zeroize 1.1.0", +] + +[[package]] +name = "scoped-tls" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" + +[[package]] +name = "scopeguard" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" @@ -5215,7 +5611,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -5351,7 +5747,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a945ec7f7ce853e89ffa36be1e27dce9a43e82ff9093bf3461c30d5da74ed11b" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -5421,9 +5817,22 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "derive_more", "log 0.4.8", - "sp-core", - "sp-std", - "sp-wasm-interface", + "sp-core 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", + "sp-wasm-interface 2.0.0-alpha.2", +] + +[[package]] +name = "sp-allocator" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bb6b190d2b48dcfc0641760ed0164df8ac8807a50afcb7c1da7641c8c13591b" +dependencies = [ + "derive_more", + "log 0.4.8", + "sp-core 2.0.0-alpha.5", + "sp-std 2.0.0-alpha.5", + "sp-wasm-interface 2.0.0-alpha.5", ] [[package]] @@ -5433,12 +5842,28 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "hash-db", "parity-scale-codec", - "sp-api-proc-macro", - "sp-core", - "sp-runtime", - "sp-state-machine", - "sp-std", - "sp-version", + "sp-api-proc-macro 2.0.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-state-machine 0.8.0-alpha.2", + "sp-std 2.0.0-alpha.2", + "sp-version 2.0.0-alpha.2", +] + +[[package]] +name = "sp-api" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4312c5081652e14f9c87fe6f8c765bbe63ac0ae69daeba48c2e5f7e7b7b25b" +dependencies = [ + "hash-db", + "parity-scale-codec", + "sp-api-proc-macro 2.0.0-alpha.5", + "sp-core 2.0.0-alpha.5", + "sp-runtime 2.0.0-alpha.5", + "sp-state-machine 0.8.0-alpha.5", + "sp-std 2.0.0-alpha.5", + "sp-version 2.0.0-alpha.5", ] [[package]] @@ -5449,7 +5874,20 @@ dependencies = [ "blake2-rfc", "proc-macro-crate", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", + "syn 1.0.14", +] + +[[package]] +name = "sp-api-proc-macro" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73a94ac1f228f99fb5279d7983f6bcde83bf1fe5824f9a56e5f7a81cc8a7069c" +dependencies = [ + "blake2-rfc", + "proc-macro-crate", + "proc-macro2 1.0.8", + "quote 1.0.3", "syn 1.0.14", ] @@ -5460,9 +5898,22 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "parity-scale-codec", "serde", - "sp-core", - "sp-io", - "sp-std", + "sp-core 2.0.0-alpha.2", + "sp-io 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", +] + +[[package]] +name = "sp-application-crypto" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed68f0c283a01b5a8c768965b160fb4aa0a637a7e1b5e0d1168cba2f2310b348" +dependencies = [ + "parity-scale-codec", + "serde", + "sp-core 2.0.0-alpha.5", + "sp-io 2.0.0-alpha.5", + "sp-std 2.0.0-alpha.5", ] [[package]] @@ -5474,8 +5925,22 @@ dependencies = [ "num-traits", "parity-scale-codec", "serde", - "sp-debug-derive", - "sp-std", + "sp-debug-derive 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", +] + +[[package]] +name = "sp-arithmetic" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d1e32dfcd4c87069d6e48d7d4a873221a8c27161a0ef5ad6ff683b591e6f97" +dependencies = [ + "integer-sqrt", + "num-traits", + "parity-scale-codec", + "serde", + "sp-debug-derive 2.0.0-alpha.5", + "sp-std 2.0.0-alpha.5", ] [[package]] @@ -5484,10 +5949,23 @@ version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "parity-scale-codec", - "sp-api", - "sp-inherents", - "sp-runtime", - "sp-std", + "sp-api 2.0.0-alpha.2", + "sp-inherents 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", +] + +[[package]] +name = "sp-block-builder" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb168416f8724c89877bfea4fece91087855760b6fc2957d982de5c168575b5" +dependencies = [ + "parity-scale-codec", + "sp-api 2.0.0-alpha.5", + "sp-inherents 2.0.0-alpha.5", + "sp-runtime 2.0.0-alpha.5", + "sp-std 2.0.0-alpha.5", ] [[package]] @@ -5500,10 +5978,27 @@ dependencies = [ "lru", "parity-scale-codec", "parking_lot 0.10.0", - "sp-block-builder", - "sp-consensus", - "sp-runtime", - "sp-state-machine", + "sp-block-builder 2.0.0-alpha.2", + "sp-consensus 0.8.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-state-machine 0.8.0-alpha.2", +] + +[[package]] +name = "sp-blockchain" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "789cf456c266dfb7d26a08f590b6e4d7644121e0d7fc3a2cd01636e1d3cef512" +dependencies = [ + "derive_more", + "log 0.4.8", + "lru", + "parity-scale-codec", + "parking_lot 0.10.0", + "sp-block-builder 2.0.0-alpha.5", + "sp-consensus 0.8.0-alpha.5", + "sp-runtime 2.0.0-alpha.5", + "sp-state-machine 0.8.0-alpha.5", ] [[package]] @@ -5522,10 +6017,10 @@ dependencies = [ "rlp", "serde", "serde-big-array", - "sp-api", - "sp-io", - "sp-runtime", - "sp-std", + "sp-api 2.0.0-alpha.2", + "sp-io 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", "triehash", ] @@ -5543,12 +6038,35 @@ dependencies = [ "parity-scale-codec", "parking_lot 0.10.0", "serde", - "sp-core", - "sp-inherents", - "sp-runtime", - "sp-state-machine", - "sp-std", - "sp-version", + "sp-core 2.0.0-alpha.2", + "sp-inherents 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-state-machine 0.8.0-alpha.2", + "sp-std 2.0.0-alpha.2", + "sp-version 2.0.0-alpha.2", +] + +[[package]] +name = "sp-consensus" +version = "0.8.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ece2291dcf8ee851df66ea0096a5301e18921e8208782ccf484694d4e50aae98" +dependencies = [ + "derive_more", + "futures 0.3.4", + "futures-diagnose", + "futures-timer 3.0.2", + "libp2p", + "log 0.4.8", + "parity-scale-codec", + "parking_lot 0.10.0", + "serde", + "sp-core 2.0.0-alpha.5", + "sp-inherents 2.0.0-alpha.5", + "sp-runtime 2.0.0-alpha.5", + "sp-state-machine 0.8.0-alpha.5", + "sp-std 2.0.0-alpha.5", + "sp-version 2.0.0-alpha.5", ] [[package]] @@ -5557,12 +6075,12 @@ version = "0.8.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "parity-scale-codec", - "sp-api", - "sp-application-crypto", - "sp-inherents", - "sp-runtime", - "sp-std", - "sp-timestamp", + "sp-api 2.0.0-alpha.2", + "sp-application-crypto 2.0.0-alpha.2", + "sp-inherents 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", + "sp-timestamp 2.0.0-alpha.2", ] [[package]] @@ -5571,14 +6089,44 @@ version = "0.8.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "parity-scale-codec", - "schnorrkel", - "sp-api", - "sp-application-crypto", - "sp-consensus", - "sp-inherents", - "sp-runtime", - "sp-std", - "sp-timestamp", + "schnorrkel 0.8.5", + "sp-api 2.0.0-alpha.2", + "sp-application-crypto 2.0.0-alpha.2", + "sp-consensus 0.8.0-alpha.2", + "sp-inherents 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", + "sp-timestamp 2.0.0-alpha.2", +] + +[[package]] +name = "sp-consensus-babe" +version = "0.8.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3341004b1ed8ae1487dc28b5ba9e3ece95c23c318d427fa598bb0084630ea822" +dependencies = [ + "parity-scale-codec", + "sp-api 2.0.0-alpha.5", + "sp-application-crypto 2.0.0-alpha.5", + "sp-consensus 0.8.0-alpha.5", + "sp-consensus-vrf", + "sp-inherents 2.0.0-alpha.5", + "sp-runtime 2.0.0-alpha.5", + "sp-std 2.0.0-alpha.5", + "sp-timestamp 2.0.0-alpha.5", +] + +[[package]] +name = "sp-consensus-vrf" +version = "0.8.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7749e59ef895203554a9fca6a5d24e49f079f44f2dddc9306fe50faae783f5a0" +dependencies = [ + "parity-scale-codec", + "schnorrkel 0.9.1", + "sp-core 2.0.0-alpha.5", + "sp-runtime 2.0.0-alpha.5", + "sp-std 2.0.0-alpha.5", ] [[package]] @@ -5599,21 +6147,63 @@ dependencies = [ "log 0.4.8", "num-traits", "parity-scale-codec", - "parity-util-mem", + "parity-util-mem 0.5.1", "parking_lot 0.10.0", "primitive-types 0.6.2", "rand 0.7.3", "regex", "rustc-hex", - "schnorrkel", + "schnorrkel 0.8.5", + "serde", + "sha2", + "sp-debug-derive 2.0.0-alpha.2", + "sp-externalities 0.8.0-alpha.2", + "sp-runtime-interface 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", + "sp-storage 2.0.0-alpha.2", + "substrate-bip39 0.3.1", + "tiny-bip39", + "tiny-keccak 2.0.1", + "twox-hash", + "wasmi", + "zeroize 1.1.0", +] + +[[package]] +name = "sp-core" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7a2938aefa827fbf6dbf5c3e8eea5cc6dedafe97a28bbfb733258ee99c82c67" +dependencies = [ + "base58", + "blake2-rfc", + "byteorder 1.3.4", + "ed25519-dalek", + "futures 0.3.4", + "hash-db", + "hash256-std-hasher", + "hex", + "impl-serde 0.3.0", + "lazy_static", + "libsecp256k1", + "log 0.4.8", + "num-traits", + "parity-scale-codec", + "parity-util-mem 0.6.0", + "parking_lot 0.10.0", + "primitive-types 0.7.0", + "rand 0.7.3", + "regex", + "rustc-hex", + "schnorrkel 0.9.1", "serde", "sha2", - "sp-debug-derive", - "sp-externalities", - "sp-runtime-interface", - "sp-std", - "sp-storage", - "substrate-bip39", + "sp-debug-derive 2.0.0-alpha.5", + "sp-externalities 0.8.0-alpha.5", + "sp-runtime-interface 2.0.0-alpha.5", + "sp-std 2.0.0-alpha.5", + "sp-storage 2.0.0-alpha.5", + "substrate-bip39 0.4.1", "tiny-bip39", "tiny-keccak 2.0.1", "twox-hash", @@ -5627,7 +6217,18 @@ version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", + "syn 1.0.14", +] + +[[package]] +name = "sp-debug-derive" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "124f3ffa2d897139864715cc624811ca997ca92be8880229143c6dee801b5ab2" +dependencies = [ + "proc-macro2 1.0.8", + "quote 1.0.3", "syn 1.0.14", ] @@ -5637,8 +6238,19 @@ version = "0.8.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "environmental", - "sp-std", - "sp-storage", + "sp-std 2.0.0-alpha.2", + "sp-storage 2.0.0-alpha.2", +] + +[[package]] +name = "sp-externalities" +version = "0.8.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b3aa6665b2a1a9df50a5514597e96a7d08d69e0e7ff90d238380fb266e14622" +dependencies = [ + "environmental", + "sp-std 2.0.0-alpha.5", + "sp-storage 2.0.0-alpha.5", ] [[package]] @@ -5648,10 +6260,24 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "parity-scale-codec", "serde", - "sp-api", - "sp-application-crypto", - "sp-runtime", - "sp-std", + "sp-api 2.0.0-alpha.2", + "sp-application-crypto 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", +] + +[[package]] +name = "sp-finality-grandpa" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9b4d96f0aa94da01d3110a20b54d8c35c419b193df6e9fa9127b2aa912afecb" +dependencies = [ + "parity-scale-codec", + "serde", + "sp-api 2.0.0-alpha.5", + "sp-application-crypto 2.0.0-alpha.5", + "sp-runtime 2.0.0-alpha.5", + "sp-std 2.0.0-alpha.5", ] [[package]] @@ -5660,8 +6286,19 @@ version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "parity-scale-codec", - "sp-inherents", - "sp-std", + "sp-inherents 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", +] + +[[package]] +name = "sp-finality-tracker" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0be49e587e5667f747ca743ef468949535fae5640d26c236ac35e44abe595b15" +dependencies = [ + "parity-scale-codec", + "sp-inherents 2.0.0-alpha.5", + "sp-std 2.0.0-alpha.5", ] [[package]] @@ -5672,8 +6309,21 @@ dependencies = [ "derive_more", "parity-scale-codec", "parking_lot 0.10.0", - "sp-core", - "sp-std", + "sp-core 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", +] + +[[package]] +name = "sp-inherents" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d5ea2312969d929d617f852f9728644b98591b503a641106ee444acea4394fc" +dependencies = [ + "derive_more", + "parity-scale-codec", + "parking_lot 0.10.0", + "sp-core 2.0.0-alpha.5", + "sp-std 2.0.0-alpha.5", ] [[package]] @@ -5685,13 +6335,32 @@ dependencies = [ "libsecp256k1", "log 0.4.8", "parity-scale-codec", - "sp-core", - "sp-externalities", - "sp-runtime-interface", - "sp-state-machine", - "sp-std", - "sp-trie", - "sp-wasm-interface", + "sp-core 2.0.0-alpha.2", + "sp-externalities 0.8.0-alpha.2", + "sp-runtime-interface 2.0.0-alpha.2", + "sp-state-machine 0.8.0-alpha.2", + "sp-std 2.0.0-alpha.2", + "sp-trie 2.0.0-alpha.2", + "sp-wasm-interface 2.0.0-alpha.2", +] + +[[package]] +name = "sp-io" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ed12cd1b0eddf5250703fff43da9e76be6cce32c492b2e2a71b4f6d9a12f49" +dependencies = [ + "hash-db", + "libsecp256k1", + "log 0.4.8", + "parity-scale-codec", + "sp-core 2.0.0-alpha.5", + "sp-externalities 0.8.0-alpha.5", + "sp-runtime-interface 2.0.0-alpha.5", + "sp-state-machine 0.8.0-alpha.5", + "sp-std 2.0.0-alpha.5", + "sp-trie 2.0.0-alpha.5", + "sp-wasm-interface 2.0.0-alpha.5", ] [[package]] @@ -5700,8 +6369,20 @@ version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "lazy_static", - "sp-core", - "sp-runtime", + "sp-core 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "strum", +] + +[[package]] +name = "sp-keyring" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0efcad50ccf03fa69c14f1b4a48b14cbb8f17afbbb53b81c34f4e0b4a3101d82" +dependencies = [ + "lazy_static", + "sp-core 2.0.0-alpha.5", + "sp-runtime 2.0.0-alpha.5", "strum", ] @@ -5710,8 +6391,8 @@ name = "sp-offchain" version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ - "sp-api", - "sp-runtime", + "sp-api 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", ] [[package]] @@ -5723,13 +6404,23 @@ dependencies = [ "log 0.4.8", ] +[[package]] +name = "sp-panic-handler" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643ae9f2dc119551342422394cdfa8bfe0a230d1adc9891fcb08cf15fdf0f703" +dependencies = [ + "backtrace", + "log 0.4.8", +] + [[package]] name = "sp-rpc" version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "serde", - "sp-core", + "sp-core 2.0.0-alpha.2", ] [[package]] @@ -5740,16 +6431,38 @@ dependencies = [ "impl-trait-for-tuples", "log 0.4.8", "parity-scale-codec", - "parity-util-mem", + "parity-util-mem 0.5.1", + "paste", + "rand 0.7.3", + "serde", + "sp-application-crypto 2.0.0-alpha.2", + "sp-arithmetic 2.0.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-inherents 2.0.0-alpha.2", + "sp-io 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", +] + +[[package]] +name = "sp-runtime" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2eb5d07f847c7420070d9dc28d810d405dc6316cd58f58548a41f0aeeca84e8" +dependencies = [ + "hash256-std-hasher", + "impl-trait-for-tuples", + "log 0.4.8", + "parity-scale-codec", + "parity-util-mem 0.6.0", "paste", "rand 0.7.3", "serde", - "sp-application-crypto", - "sp-arithmetic", - "sp-core", - "sp-inherents", - "sp-io", - "sp-std", + "sp-application-crypto 2.0.0-alpha.5", + "sp-arithmetic 2.0.0-alpha.5", + "sp-core 2.0.0-alpha.5", + "sp-inherents 2.0.0-alpha.5", + "sp-io 2.0.0-alpha.5", + "sp-std 2.0.0-alpha.5", ] [[package]] @@ -5759,10 +6472,25 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "parity-scale-codec", "primitive-types 0.6.2", - "sp-externalities", - "sp-runtime-interface-proc-macro", - "sp-std", - "sp-wasm-interface", + "sp-externalities 0.8.0-alpha.2", + "sp-runtime-interface-proc-macro 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", + "sp-wasm-interface 2.0.0-alpha.2", + "static_assertions", +] + +[[package]] +name = "sp-runtime-interface" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d25229ba01740b13368f743e866d8ee155826932c9f2c4390e4ceb7730df214" +dependencies = [ + "parity-scale-codec", + "primitive-types 0.7.0", + "sp-externalities 0.8.0-alpha.5", + "sp-runtime-interface-proc-macro 2.0.0-alpha.5", + "sp-std 2.0.0-alpha.5", + "sp-wasm-interface 2.0.0-alpha.5", "static_assertions", ] @@ -5774,7 +6502,20 @@ dependencies = [ "Inflector", "proc-macro-crate", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", + "syn 1.0.14", +] + +[[package]] +name = "sp-runtime-interface-proc-macro" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f1d9e32fa5db2f3dd89affbd3c97959432272c9e52e4e2610dad32dd4705784" +dependencies = [ + "Inflector", + "proc-macro-crate", + "proc-macro2 1.0.8", + "quote 1.0.3", "syn 1.0.14", ] @@ -5787,15 +6528,25 @@ dependencies = [ "serde_json", ] +[[package]] +name = "sp-serializer" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91abe1611fb9ad68cc2be724580710c5824a256d6aa92d88b181cb0d4819f8d1" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "sp-session" version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ - "sp-api", - "sp-core", - "sp-runtime", - "sp-std", + "sp-api 2.0.0-alpha.2", + "sp-core 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", ] [[package]] @@ -5804,8 +6555,8 @@ version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "parity-scale-codec", - "sp-runtime", - "sp-std", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", ] [[package]] @@ -5819,10 +6570,30 @@ dependencies = [ "parity-scale-codec", "parking_lot 0.10.0", "rand 0.7.3", - "sp-core", - "sp-externalities", - "sp-panic-handler", - "sp-trie", + "sp-core 2.0.0-alpha.2", + "sp-externalities 0.8.0-alpha.2", + "sp-panic-handler 2.0.0-alpha.2", + "sp-trie 2.0.0-alpha.2", + "trie-db", + "trie-root", +] + +[[package]] +name = "sp-state-machine" +version = "0.8.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e52a17e293be8e7a518ac6aebfc7fdafbe531b6c808a83a754e4a8730f139521" +dependencies = [ + "hash-db", + "log 0.4.8", + "num-traits", + "parity-scale-codec", + "parking_lot 0.10.0", + "rand 0.7.3", + "sp-core 2.0.0-alpha.5", + "sp-externalities 0.8.0-alpha.5", + "sp-panic-handler 2.0.0-alpha.5", + "sp-trie 2.0.0-alpha.5", "trie-db", "trie-root", ] @@ -5832,6 +6603,12 @@ name = "sp-std" version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +[[package]] +name = "sp-std" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "752e038359704226bb5737531fb91df2e4ab33214e0be6eb6f32ad688a71b411" + [[package]] name = "sp-storage" version = "2.0.0-alpha.2" @@ -5839,8 +6616,20 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "impl-serde 0.2.3", "serde", - "sp-debug-derive", - "sp-std", + "sp-debug-derive 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", +] + +[[package]] +name = "sp-storage" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c389a75ddd45ba771b20c4caed1011d23004069e436b73eca058d2f894585069" +dependencies = [ + "impl-serde 0.2.3", + "serde", + "sp-debug-derive 2.0.0-alpha.5", + "sp-std 2.0.0-alpha.5", ] [[package]] @@ -5850,10 +6639,25 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", - "sp-api", - "sp-inherents", - "sp-runtime", - "sp-std", + "sp-api 2.0.0-alpha.2", + "sp-inherents 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", + "wasm-timer", +] + +[[package]] +name = "sp-timestamp" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990bc28e4e7fd31a13f5e61fd30ef0aa3ba5747b64ab3560df5285abbd879f6c" +dependencies = [ + "impl-trait-for-tuples", + "parity-scale-codec", + "sp-api 2.0.0-alpha.5", + "sp-inherents 2.0.0-alpha.5", + "sp-runtime 2.0.0-alpha.5", + "sp-std 2.0.0-alpha.5", "wasm-timer", ] @@ -5867,8 +6671,23 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "serde", - "sp-api", - "sp-runtime", + "sp-api 2.0.0-alpha.2", + "sp-runtime 2.0.0-alpha.2", +] + +[[package]] +name = "sp-transaction-pool" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a7e374dd4c0831fa118728656c5d295a3ebd3da9c7ead45451ad4a5801a77e4" +dependencies = [ + "derive_more", + "futures 0.3.4", + "log 0.4.8", + "parity-scale-codec", + "serde", + "sp-api 2.0.0-alpha.5", + "sp-runtime 2.0.0-alpha.5", ] [[package]] @@ -5877,10 +6696,25 @@ version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "hash-db", - "memory-db", + "memory-db 0.19.0", "parity-scale-codec", - "sp-core", - "sp-std", + "sp-core 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", + "trie-db", + "trie-root", +] + +[[package]] +name = "sp-trie" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f417a60d0d1222f92733deef4dffc73b21180b0cf44ec335ac73fc871198721" +dependencies = [ + "hash-db", + "memory-db 0.20.0", + "parity-scale-codec", + "sp-core 2.0.0-alpha.5", + "sp-std 2.0.0-alpha.5", "trie-db", "trie-root", ] @@ -5893,8 +6727,21 @@ dependencies = [ "impl-serde 0.2.3", "parity-scale-codec", "serde", - "sp-runtime", - "sp-std", + "sp-runtime 2.0.0-alpha.2", + "sp-std 2.0.0-alpha.2", +] + +[[package]] +name = "sp-version" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f7ded62b3fd6346dc7e96dcfc55f8137653809e09cfa3f0da8052efd35c875" +dependencies = [ + "impl-serde 0.2.3", + "parity-scale-codec", + "serde", + "sp-runtime 2.0.0-alpha.5", + "sp-std 2.0.0-alpha.5", ] [[package]] @@ -5904,7 +6751,19 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", - "sp-std", + "sp-std 2.0.0-alpha.2", + "wasmi", +] + +[[package]] +name = "sp-wasm-interface" +version = "2.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ab9dec817ad8e5eed83a3579da8638703d7559be5da5342312c8effee6a70aa" +dependencies = [ + "impl-trait-for-tuples", + "parity-scale-codec", + "sp-std 2.0.0-alpha.5", "wasmi", ] @@ -5953,7 +6812,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "serde", "serde_derive", "syn 1.0.14", @@ -5967,7 +6826,7 @@ checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" dependencies = [ "base-x", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "serde", "serde_derive", "serde_json", @@ -6025,7 +6884,7 @@ dependencies = [ "heck", "proc-macro-error", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -6046,7 +6905,7 @@ checksum = "0054a7df764039a6cd8592b9de84be4bec368ff081d203a7d5371cbfa8e65c81" dependencies = [ "heck", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -6058,7 +6917,19 @@ checksum = "3be511be555a3633e71739a79e4ddff6a6aaa6579fa6114182a51d72c3eb93c5" dependencies = [ "hmac", "pbkdf2", - "schnorrkel", + "schnorrkel 0.8.5", + "sha2", +] + +[[package]] +name = "substrate-bip39" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c004e8166d6e0aa3a9d5fa673e5b7098ff25f930de1013a21341988151e681bb" +dependencies = [ + "hmac", + "pbkdf2", + "schnorrkel 0.9.1", "sha2", ] @@ -6076,7 +6947,7 @@ dependencies = [ "log 0.4.8", "node-primitives", "serde_json", - "sp-core", + "sp-core 2.0.0-alpha.2", "sp-rpc", "url 2.1.1", ] @@ -6086,6 +6957,21 @@ name = "substrate-build-script-utils" version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +[[package]] +name = "substrate-prometheus-endpoint" +version = "0.8.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79926ded24e276de08eba7880c173e90eae37dc748f47eabefca9bda2cb296" +dependencies = [ + "async-std", + "derive_more", + "futures-util", + "hyper 0.13.2", + "log 0.4.8", + "prometheus", + "tokio 0.2.11", +] + [[package]] name = "substrate-wasm-builder-runner" version = "1.0.5" @@ -6121,7 +7007,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "unicode-xid 0.2.0", ] @@ -6132,7 +7018,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -6155,7 +7041,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", "unicode-xid 0.2.0", ] @@ -6233,7 +7119,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7b51e1fbc44b5a0840be594fbc0f960be09050f2617e61e6aa43bef97cd3ef4" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -6299,7 +7185,7 @@ checksum = "e987cfe0537f575b5fc99909de6185f6c19c3ad8889e2275e686a873d0869ba1" dependencies = [ "proc-macro-hack", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -6688,7 +7574,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04cfd395def5a60236e187e1ff905cb55668a59f29928dec05e6e1b1fd2ac1f3" dependencies = [ - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", ] @@ -6981,7 +7867,7 @@ dependencies = [ "lazy_static", "log 0.4.8", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", "wasm-bindgen-shared", ] @@ -7004,7 +7890,7 @@ version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "574094772ce6921576fb6f2e3f7497b8a76273b6db092be18fc48a082de09dc3" dependencies = [ - "quote 1.0.2", + "quote 1.0.3", "wasm-bindgen-macro-support", ] @@ -7015,7 +7901,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", "wasm-bindgen-backend", "wasm-bindgen-shared", @@ -7037,7 +7923,7 @@ dependencies = [ "heck", "log 0.4.8", "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", "wasm-bindgen-backend", "weedle", @@ -7340,7 +8226,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" dependencies = [ "proc-macro2 1.0.8", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.14", "synstructure 0.12.3", ] diff --git a/Cargo.toml b/Cargo.toml index fd86663f9f..2519995941 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "bin/node/runtime", "modules/substrate", "modules/ethereum", + "modules/ethereum-contract/builtin", "relays/ethereum", "relays/substrate", ] diff --git a/modules/ethereum-contract/builtin/Cargo.toml b/modules/ethereum-contract/builtin/Cargo.toml new file mode 100644 index 0000000000..73d16532df --- /dev/null +++ b/modules/ethereum-contract/builtin/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "ethereum-contract-builtin" +description = "Small crate that helps Solidity contract to verify finality proof." +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] + +# General dependencies + +codec = { package = "parity-scale-codec", version = "1.0.0" } +sc-finality-grandpa = "0.8.0-alpha.5" + +# Runtime/chain specific dependencies + +bridge-node-runtime = { path = "../../../bin/node/runtime" } diff --git a/modules/ethereum-contract/builtin/src/lib.rs b/modules/ethereum-contract/builtin/src/lib.rs new file mode 100644 index 0000000000..f1db517b09 --- /dev/null +++ b/modules/ethereum-contract/builtin/src/lib.rs @@ -0,0 +1,50 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +use bridge_node_runtime::{BlockNumber, Hash}; +use sc_finality_grandpa::GrandpaJustification; + +/// Builtin errors. +pub enum Error { + /// Failed to decode Substrate header. + HeaderDecode(codec::Error), +} + +/// Substrate header. +pub struct Header { + /// Header number. + pub number: BlockNumber, +} + +/// All types of finality proofs. +pub enum FinalityProof { + /// GRANDPA justification. + Justification(GrandpaJustification), +} + +/// Parse Substrate header. +pub fn parse_substrate_header(raw_header: &[u8]) -> Result { + unimplemented!() +} + +/// +pub fn verify_finalization_data( + best_header_hash: &Hash, + headers: &[Header], + raw_finalization_data: &[u8] +) -> Result<(usize, usize), Error> { + unimplemented!() +} diff --git a/modules/ethereum-contract/contracts/substrate-bridge.sol b/modules/ethereum-contract/contracts/substrate-bridge.sol new file mode 100644 index 0000000000..f5e12bbd43 --- /dev/null +++ b/modules/ethereum-contract/contracts/substrate-bridge.sol @@ -0,0 +1,197 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +pragma solidity ^0.6.4; +pragma experimental ABIEncoderV2; + +/// @title Substrate-to-PoA Bridge Contract. +contract SubstrateBridge { + /// Voter set as it is stored in the storage. + struct VoterSet { + /// Id of the set. + uint64 id; + /// Raw voter set. + bytes rawVoters; + } + + /// Voter set change signals. + struct VoterSetSignal { + /// keccak256(header.number) of the header that enacts this voter set. + bytes32 headerNumber; + /// Raw voter set. + bytes rawVoters; + } + + /// Header as it is stored in the storage. + struct Header { + /// keccak256(rawHeader) of the next header, or bytes32(0) if it is the best header. + bytes32 nextHeaderHash; + /// Raw header data. + bytes rawHeader; + } + + /// Initializes bridge contract. + /// @param rawInitialHeader Raw finalized header that is ancestor of all importing headers. + /// @param initialVoters GRANDPA voter set that must finalize direct children of the initial header. + /// @param voterSetSignals GRANDPA voter set signals (including signal from rawInitialHeader). + constructor( + bytes memory rawInitialHeader, + VoterSet memory initialVoters, + VoterSetSignal[] memory voterSetSignals + ) public { + // save initial header + bytes32 headerHash = saveBestHeader(rawInitialHeader); + oldestHeaderHash = headerHash; + // save best voter set + bestVoterSet.id = initialVoters.id; + bestVoterSet.rawVoters = initialVoters.rawVoters; + // save all signals + for (uint i = 0; i < voterSetSignals.length; ++i) { + saveSignal(voterSetSignals[i]); + } + } + + /// Reject direct payments. + fallback() external { revert(); } + + /// Import range of headers with finalization data. + /// @param rawHeaders Finalized headers to import. + /// @param rawFinalityProof Data required to finalize rawHeaders. + function importHeaders( + bytes[] calldata rawHeaders, + bytes calldata rawFinalityProof + ) external { + // verify finalization data + (uint256 begin, uint256 end) = verifyFinalityProof( + bestHeaderHash, + rawHeaders, + rawFinalityProof + ); + + // save finalized headers + bool enactedNewSet = false; + for (uint256 i = begin; i < end; ++i) { + // parse header + bytes memory rawHeader = rawHeaders[i]; + (bytes32 headerNumber, VoterSetSignal memory voterSetSignal) = parseSubstrateHeader( + rawHeader + ); + + // save header to the storage + saveBestHeader(rawHeader); + // save voters set signal (if signalled by the header) + if (voterSetSignal.rawVoters.length != 0) { + saveSignal(voterSetSignal); + } + // check if header enacts new set + bytes memory newRawVoters = voterSetByEnactNumber[headerNumber]; + if (newRawVoters.length != 0) { + require( + !enactedNewSet, + "Trying to enact several sets using single finality proof" + ); + + enactedNewSet = true; + bestVoterSet.id = bestVoterSet.id + 1; + bestVoterSet.rawVoters = newRawVoters; + } + } + + // prune oldest headers + if (storedHeadersCount > maxHeadersToStore) { + uint256 headersToPrune = storedHeadersCount - maxHeadersToStore; + for (uint256 i = 0; i < headersToPrune; ++i) { + pruneOldestHeader(); + } + } + } + + /// Save best header to the storage. + /// @return keccak256(rawHeader) + function saveBestHeader( + bytes memory rawHeader + ) private returns (bytes32) { + bytes32 headerHash = keccak256(rawHeader); + bytes32 previousHeaderHash = bestHeaderHash; + if (previousHeaderHash != bytes32(0)) { + headerByHash[previousHeaderHash].nextHeaderHash = headerHash; + } + headerByHash[headerHash].rawHeader = rawHeader; + bestHeaderHash = headerHash; + storedHeadersCount = storedHeadersCount + 1; + return headerHash; + } + + /// Prune oldest header. + function pruneOldestHeader() private { + Header storage oldestHeader = headerByHash[oldestHeaderHash]; + oldestHeaderHash = oldestHeader.nextHeaderHash; + delete headerByHash[oldestHeaderHash]; + storedHeadersCount = storedHeadersCount - 1; + } + + /// Save voter set change signal to the storage. + function saveSignal( + VoterSetSignal memory voterSetSignal + ) private { + require( + voterSetByEnactNumber[voterSetSignal.headerNumber].length == 0, + "Duplicate signal for the same block" + ); + voterSetByEnactNumber[voterSetSignal.headerNumber] = voterSetSignal.rawVoters; + } + + /// Parse Substrate header. + /// @return keccak256(header.number) and voter set signal (if signalled by the header). + function parseSubstrateHeader( + bytes memory rawHeader + ) private pure returns (bytes32, VoterSetSignal memory) { + return ( + bytes32(0), + VoterSetSignal({ + headerNumber: bytes32(0), + rawVoters: "" + }) + ); // TODO: replace with builtin call + } + + /// Verify finality proof. + /// @return Range of headers within rawHeaders that are proved to be final. + function verifyFinalityProof( + bytes32 bestHeaderHash, + bytes[] memory rawHeaders, + bytes memory rawFinalityProof + ) private pure returns (uint256, uint256) { + return (0, 0); // TODO: replace with builtin call + } + + /// Maximal number of headers that we store. + uint256 constant maxHeadersToStore = 1024; + + /// Current number of headers that we store. + uint256 storedHeadersCount; + /// keccak32(rawHeader) of the oldest header. + bytes32 oldestHeaderHash; + /// keccak32(rawHeader) of the last finalized block. + bytes32 bestHeaderHash; + /// Raw voter set for the last finalized block. + VoterSet bestVoterSet; + /// Map of keccak256(raw header) => raw header. + mapping (bytes32 => Header) headerByHash; + /// Map of keccak256(header.number) => raw voter set that is enacted when block + /// with given number is finalized. + mapping (bytes32 => bytes) voterSetByEnactNumber; +} \ No newline at end of file From a9d58a04df79c22f7bf670b250a21d266ff19141 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 6 Apr 2020 11:09:16 +0300 Subject: [PATCH 02/92] continue --- modules/ethereum-contract/builtin/src/lib.rs | 65 ++++++++++++++++--- .../contracts/substrate-bridge.sol | 8 ++- 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/modules/ethereum-contract/builtin/src/lib.rs b/modules/ethereum-contract/builtin/src/lib.rs index f1db517b09..618b0e7581 100644 --- a/modules/ethereum-contract/builtin/src/lib.rs +++ b/modules/ethereum-contract/builtin/src/lib.rs @@ -14,13 +14,24 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use bridge_node_runtime::{BlockNumber, Hash}; +use bridge_node_runtime::{BlockNumber, Hash, Header as RuntimeHeader}; +use finality_grandpa::VoterSet; use sc_finality_grandpa::GrandpaJustification; +use sp_blockchain::Error as ClientError; +use sp_finality_grandpa::AuthorityList; /// Builtin errors. pub enum Error { /// Failed to decode Substrate header. HeaderDecode(codec::Error), + /// Failed to decode best voters set. + BestVotersDecode(codec::Error), + /// Failed to decode finality proof. + FinalityProofDecode(codec::Error), + /// Failed to verify justification. + JustificationVerify(ClientError), + /// + NoNewHeaders, } /// Substrate header. @@ -32,19 +43,55 @@ pub struct Header { /// All types of finality proofs. pub enum FinalityProof { /// GRANDPA justification. - Justification(GrandpaJustification), + Justification(Vec), } /// Parse Substrate header. pub fn parse_substrate_header(raw_header: &[u8]) -> Result { - unimplemented!() + RuntimeHeader::decode(&mut &ras_header[..]) + .map(|header| Header { + number: header.number, + }) + .map_err(Error::HeaderDecode) } -/// -pub fn verify_finalization_data( - best_header_hash: &Hash, - headers: &[Header], - raw_finalization_data: &[u8] +/// Verify GRANDPA finality proof. +pub fn verify_substrate_finality_proof( + best_set_id: u64, + raw_best_voters: &[u8], + raw_best_header: &[u8], + raw_headers: &[&[u8]], + raw_finality_proof: &[u8], ) -> Result<(usize, usize), Error> { - unimplemented!() + let best_voters = AuthorityList::decode(&mut &raw_best_voters[..]) + .map_err(Error::BestVotersDecode)?; + let finality_proof = FinalityProof::decode(&mut &raw_finality_proof[..]) + .map_err(Error::FinalityProofDecode)?; + + let best_header = RuntimeHeader::decode(&mut &raw_best_header[..]) + .map_err(Error::HeaderDecode)?; + let headers = raw_headers + .iter() + .map(|raw_header| RuntimeHeader::decode(&mut &raw_header[..]) + .map_err(Error::HeaderDecode) + ) + .collect::, _>>()?; + + let finality_target = match headers.last() { + Some(header) => (header.hash(), header.number()), + None => return Err(Error::NoNewHeaders), + }; + + match finality_proof { + FinalityProof::Justification(raw_justification) => { + GrandpaJustification::decode_and_verify_finalizes( + &raw_justification, + finality_target, + best_set_id, + &VoterSet::new(best_voters) + ).map_err(Error::JustificationVerify)?; + }, + } + + Ok((0, headers.len())) } diff --git a/modules/ethereum-contract/contracts/substrate-bridge.sol b/modules/ethereum-contract/contracts/substrate-bridge.sol index f5e12bbd43..3d16115e02 100644 --- a/modules/ethereum-contract/contracts/substrate-bridge.sol +++ b/modules/ethereum-contract/contracts/substrate-bridge.sol @@ -76,7 +76,9 @@ contract SubstrateBridge { ) external { // verify finalization data (uint256 begin, uint256 end) = verifyFinalityProof( - bestHeaderHash, + bestVoterSet.id, + bestVoterSet.rawVoters, + headerByHash[bestHeaderHash].rawHeader, rawHeaders, rawFinalityProof ); @@ -171,7 +173,9 @@ contract SubstrateBridge { /// Verify finality proof. /// @return Range of headers within rawHeaders that are proved to be final. function verifyFinalityProof( - bytes32 bestHeaderHash, + uint64 currentSetId, + bytes memory rawCurrentVoters, + bytes memory rawBestHeader, bytes[] memory rawHeaders, bytes memory rawFinalityProof ) private pure returns (uint256, uint256) { From 6995aaca395daf05f57cbec44bc689dd0e47c1eb Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 6 Apr 2020 11:12:22 +0300 Subject: [PATCH 03/92] upd --- modules/ethereum-contract/builtin/Cargo.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/ethereum-contract/builtin/Cargo.toml b/modules/ethereum-contract/builtin/Cargo.toml index 73d16532df..bd359661c2 100644 --- a/modules/ethereum-contract/builtin/Cargo.toml +++ b/modules/ethereum-contract/builtin/Cargo.toml @@ -10,7 +10,9 @@ edition = "2018" # General dependencies codec = { package = "parity-scale-codec", version = "1.0.0" } +finality-grandpa = "0.11.2" sc-finality-grandpa = "0.8.0-alpha.5" +sp-finality-grandpa = "2.0.0-alpha.5" # Runtime/chain specific dependencies From 7a55f484e1730dd5da7c4881b0dad80d7bab90e0 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 6 Apr 2020 11:26:07 +0300 Subject: [PATCH 04/92] cargo update --- Cargo.lock | 677 +++++++++++++++++++++++++---------------------------- 1 file changed, 318 insertions(+), 359 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8d64574779..9b42a515d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -81,9 +81,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743ad5a418686aad3b87fd14c43badd828cf26e214a00f92a384291cf22e1811" +checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" dependencies = [ "memchr", ] @@ -108,9 +108,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.26" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" +checksum = "d9a60d744a80c30fcb657dfe2c1b22bcb3e814c1a1e3674f32bf5820b570fbff" [[package]] name = "app_dirs" @@ -126,9 +126,9 @@ dependencies = [ [[package]] name = "arc-swap" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" +checksum = "d663a8e9a99154b5fb793032533f6328da35e23aac63d5c152279aa8ba356825" [[package]] name = "arrayref" @@ -167,7 +167,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d0864d84b8e07b145449be9a8537db86bf9de5ce03b913214694643b4743502" dependencies = [ "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -218,9 +218,9 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25f9db3b38af870bf7e5cc649167533b493928e50744e2c30ae350230b414670" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -270,9 +270,9 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "backtrace" -version = "0.3.43" +version = "0.3.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f80256bc78f67e7df7e36d77366f636ed976895d91fe2ab9efa3973e8fe8c4f" +checksum = "b1e692897359247cc6bb902933361652380af0f1b7651ae5c5013407f30e109e" dependencies = [ "backtrace-sys", "cfg-if", @@ -282,9 +282,9 @@ dependencies = [ [[package]] name = "backtrace-sys" -version = "0.1.32" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" +checksum = "7de8aba10a69c8e8d7622c5710229485ec32e9d55fdad160ea559c086fdcd118" dependencies = [ "cc", "libc", @@ -329,9 +329,9 @@ checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" [[package]] name = "bindgen" -version = "0.53.1" +version = "0.53.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99de13bb6361e01e493b3db7928085dcc474b7ba4f5481818e53a89d76b8393f" +checksum = "6bb26d6a69a335b8cb0e7c7e9775cd5666611dc50a37177c3f2cedcfc040e8c8" dependencies = [ "bitflags 1.2.1", "cexpr", @@ -343,7 +343,7 @@ dependencies = [ "lazycell", "log 0.4.8", "peeking_take_while", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", "regex", "rustc-hash", @@ -531,18 +531,18 @@ checksum = "b170cd256a3f9fa6b9edae3e44a7dfdfc77e8124dbc3e2612d75f9c3e2396dae" [[package]] name = "bstr" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "502ae1441a0a5adb8fbd38a5955a6416b9493e92b465de5e4a9bde6a539c2c48" +checksum = "2889e6d50f394968c8bf4240dc3f2a7eb4680844d27308f798229ac9d4725f41" dependencies = [ "memchr", ] [[package]] name = "bumpalo" -version = "3.2.0" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f359dc14ff8911330a51ef78022d376f25ed00248912803b58f00cb1c27f742" +checksum = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187" [[package]] name = "byte-slice-cast" @@ -585,15 +585,6 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" -[[package]] -name = "c2-chacha" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" -dependencies = [ - "ppv-lite86", -] - [[package]] name = "c_linked_list" version = "1.1.1" @@ -611,9 +602,9 @@ dependencies = [ [[package]] name = "cexpr" -version = "0.3.6" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fce5b5fb86b0c57c20c834c1b412fd09c77c8a59b9473f86272709e78874cd1d" +checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" dependencies = [ "nom", ] @@ -635,9 +626,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" +checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" dependencies = [ "num-integer", "num-traits", @@ -646,9 +637,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "0.28.1" +version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853" +checksum = "fe6837df1d5cba2397b835c8530f51723267e16abbf83892e9e5af4f0e5dd10a" dependencies = [ "glob", "libc", @@ -758,33 +749,36 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c" +checksum = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061" dependencies = [ "crossbeam-utils", + "maybe-uninit", ] [[package]] name = "crossbeam-deque" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca" +checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" dependencies = [ "crossbeam-epoch", "crossbeam-utils", + "maybe-uninit", ] [[package]] name = "crossbeam-epoch" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" +checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" dependencies = [ - "autocfg 0.1.7", + "autocfg 1.0.0", "cfg-if", "crossbeam-utils", "lazy_static", + "maybe-uninit", "memoffset", "scopeguard", ] @@ -801,11 +795,11 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" dependencies = [ - "autocfg 0.1.7", + "autocfg 1.0.0", "cfg-if", "lazy_static", ] @@ -903,9 +897,9 @@ version = "0.99.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2323f3f47db9a0e77ce7a300605d8d2098597fc451ed1a97bb1f6411bb550a7" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -935,9 +929,9 @@ dependencies = [ [[package]] name = "doc-comment" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "ed25519-dalek" @@ -978,9 +972,9 @@ checksum = "516aa8d7a71cb00a1c4146f0798549b93d083d4f189b3ced8f3de6b8f11ee6c4" [[package]] name = "erased-serde" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7d80305c9bd8cd78e3c753eb9fb110f83621e5211f1a3afffcc812b104daf9" +checksum = "d88b6d1705e16a4d62e05ea61cc0496c2bd190f4fa8e5c1f11ce747be6bcf3d1" dependencies = [ "serde", ] @@ -1032,7 +1026,7 @@ dependencies = [ "fixed-hash 0.6.0", "impl-rlp", "impl-serde 0.3.0", - "tiny-keccak 2.0.1", + "tiny-keccak 2.0.2", ] [[package]] @@ -1040,8 +1034,10 @@ name = "ethereum-contract-builtin" version = "0.1.0" dependencies = [ "bridge-node-runtime", + "finality-grandpa", "parity-scale-codec", "sc-finality-grandpa 0.8.0-alpha.5", + "sp-finality-grandpa 2.0.0-alpha.5", ] [[package]] @@ -1125,7 +1121,7 @@ dependencies = [ "parity-crypto 0.4.2", "rand 0.7.3", "rustc-hex", - "secp256k1 0.15.3", + "secp256k1 0.15.5", "serde", "zeroize 1.1.0", ] @@ -1141,9 +1137,9 @@ dependencies = [ [[package]] name = "failure" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" +checksum = "b8529c2421efa3066a5cbd8063d2244603824daccb6936b079010bb2aa89464b" dependencies = [ "backtrace", "failure_derive", @@ -1151,13 +1147,13 @@ dependencies = [ [[package]] name = "failure_derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" +checksum = "030a733c8287d6213886dd487564ff5c8f6aae10278b3588ed177f9d18f8d231" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", "synstructure 0.12.3", ] @@ -1169,9 +1165,9 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] name = "fdlimit" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9084c55bb76efb1496328976db88320fe7d9ee86e649e83c4ecce3ba7a9a35d1" +checksum = "0da54a593b34c71b889ee45f5b5bb900c74148c5f7f8c6a9479ee7899f69603c" dependencies = [ "libc", ] @@ -1223,9 +1219,9 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" [[package]] name = "flate2" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" +checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42" dependencies = [ "cfg-if", "crc32fast", @@ -1339,9 +1335,9 @@ version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "frame-support-procedural-tools", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -1351,9 +1347,9 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -1361,9 +1357,9 @@ name = "frame-support-procedural-tools-derive" version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -1519,9 +1515,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -1649,9 +1645,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "globset" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2" +checksum = "7ad1da430bd7281dde2576f44c84cc3f0f7b475e7202cd503042dff01a8c8120" dependencies = [ "aho-corasick", "bstr", @@ -1680,20 +1676,20 @@ dependencies = [ [[package]] name = "h2" -version = "0.2.1" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9433d71e471c1736fd5a61b671fc0b148d7a2992f666c958d03cd8feb3b88d1" +checksum = "377038bf3c89d18d6ca1431e7a5027194fbd724ca10592b9487ede5e8e144f42" dependencies = [ "bytes 0.5.4", "fnv", "futures-core", "futures-sink", "futures-util", - "http 0.2.0", + "http 0.2.1", "indexmap", "log 0.4.8", "slab 0.4.2", - "tokio 0.2.11", + "tokio 0.2.16", "tokio-util", ] @@ -1724,9 +1720,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728e7d31e63d53c436094370f1e6fa249f60a4bb318cc5dfbbbe0aa2bc5a29d7" +checksum = "479e9d9a1a3f8c489868a935b557ab5710e3e223836da2ecd52901d88935cb56" dependencies = [ "ahash 0.3.2", "autocfg 1.0.0", @@ -1743,18 +1739,18 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.6" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" +checksum = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e" dependencies = [ "libc", ] [[package]] name = "hex" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76cdda6bf525062a0c9e8f14ee2b37935c86b8efb6c8b69b3c83dfb518a914af" +checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" [[package]] name = "hex-literal" @@ -1809,9 +1805,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b" +checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9" dependencies = [ "bytes 0.5.4", "fnv", @@ -1837,7 +1833,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" dependencies = [ "bytes 0.5.4", - "http 0.2.0", + "http 0.2.1", ] [[package]] @@ -1906,16 +1902,16 @@ dependencies = [ [[package]] name = "hyper" -version = "0.13.2" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa1c527bbc634be72aa7ba31e4e4def9bbb020f5416916279b7c705cd838893e" +checksum = "ed6081100e960d9d74734659ffc9cc91daf1c0fc7aceb8eaa94ee1a3f5046f2e" dependencies = [ "bytes 0.5.4", "futures-channel", "futures-core", "futures-util", - "h2 0.2.1", - "http 0.2.0", + "h2 0.2.4", + "http 0.2.1", "http-body 0.3.1", "httparse", "itoa", @@ -1923,7 +1919,7 @@ dependencies = [ "net2", "pin-project", "time 0.1.42", - "tokio 0.2.11", + "tokio 0.2.16", "tower-service", "want 0.3.0", ] @@ -1937,10 +1933,10 @@ dependencies = [ "bytes 0.5.4", "ct-logs", "futures-util", - "hyper 0.13.2", + "hyper 0.13.4", "rustls", "rustls-native-certs", - "tokio 0.2.11", + "tokio 0.2.16", "tokio-rustls", "webpki", ] @@ -2032,9 +2028,9 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -2069,9 +2065,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a859057dc563d1388c1e816f98a1892629075fc046ed06e845b883bb8b2916fb" +checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" [[package]] name = "itertools" @@ -2090,9 +2086,9 @@ checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" [[package]] name = "js-sys" -version = "0.3.35" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7889c7c36282151f6bf465be4700359318aef36baa951462382eae49e9577cf9" +checksum = "6a27d435371a2fa5b6d2b028a74bbdb1234f308da363226a2854ca3ff8ba7055" dependencies = [ "wasm-bindgen", ] @@ -2142,9 +2138,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8609af8f63b626e8e211f52441fcdb6ec54f1a446606b10d5c89ae9bf8a20058" dependencies = [ "proc-macro-crate", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -2207,7 +2203,7 @@ dependencies = [ [[package]] name = "jsonrpsee" version = "1.0.0" -source = "git+https://github.com/paritytech/jsonrpsee#a0bea41c4f37125fa742ec48b12e11cf55c592b5" +source = "git+https://github.com/paritytech/jsonrpsee.git#62da58d12321355aac76975bfedfbc3ab0fe08e3" dependencies = [ "async-std", "async-tls", @@ -2217,8 +2213,8 @@ dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", "globset", - "hashbrown 0.7.0", - "hyper 0.13.2", + "hashbrown 0.7.1", + "hyper 0.13.4", "jsonrpsee-proc-macros", "lazy_static", "log 0.4.8", @@ -2230,7 +2226,7 @@ dependencies = [ "smallvec 1.2.0", "soketto", "thiserror", - "tokio 0.2.11", + "tokio 0.2.16", "unicase 2.6.0", "url 2.1.1", "webpki", @@ -2239,12 +2235,12 @@ dependencies = [ [[package]] name = "jsonrpsee-proc-macros" version = "1.0.0" -source = "git+https://github.com/paritytech/jsonrpsee#a0bea41c4f37125fa742ec48b12e11cf55c592b5" +source = "git+https://github.com/paritytech/jsonrpsee.git#62da58d12321355aac76975bfedfbc3ab0fe08e3" dependencies = [ "Inflector", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -2279,7 +2275,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03080afe6f42cd996da9f568d6add5d7fb5ee2ea7fb7802d2d2cbd836958fd87" dependencies = [ "parity-bytes", - "parity-util-mem 0.5.1", + "parity-util-mem 0.5.2", "smallvec 1.2.0", ] @@ -2300,7 +2296,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9355274e5a9e0a7e8ef43916950eae3949024de2a8dffe4d5a6c13974a37c8e" dependencies = [ "kvdb 0.4.0", - "parity-util-mem 0.5.1", + "parity-util-mem 0.5.2", "parking_lot 0.10.0", ] @@ -2316,7 +2312,7 @@ dependencies = [ "log 0.4.8", "num_cpus", "owning_ref", - "parity-util-mem 0.5.1", + "parity-util-mem 0.5.2", "parking_lot 0.10.0", "regex", "rocksdb", @@ -2343,9 +2339,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" [[package]] name = "libc" -version = "0.2.66" +version = "0.2.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" +checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" [[package]] name = "libloading" @@ -2423,7 +2419,7 @@ dependencies = [ "sha2", "smallvec 1.2.0", "thiserror", - "unsigned-varint 0.3.1", + "unsigned-varint 0.3.2", "void", "zeroize 1.1.0", ] @@ -2435,7 +2431,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d472e9d522f588805c77801de10b957be84e10f019ca5f869fa1825b15ea9b" dependencies = [ "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -2498,7 +2494,7 @@ dependencies = [ "rand 0.7.3", "sha2", "smallvec 1.2.0", - "unsigned-varint 0.3.1", + "unsigned-varint 0.3.2", "wasm-timer", ] @@ -2540,7 +2536,7 @@ dependencies = [ "sha2", "smallvec 1.2.0", "uint", - "unsigned-varint 0.3.1", + "unsigned-varint 0.3.2", "void", "wasm-timer", ] @@ -2580,7 +2576,7 @@ dependencies = [ "libp2p-core", "log 0.4.8", "parking_lot 0.10.0", - "unsigned-varint 0.3.1", + "unsigned-varint 0.3.2", ] [[package]] @@ -2633,7 +2629,7 @@ dependencies = [ "prost", "prost-build", "rw-stream-sink", - "unsigned-varint 0.3.1", + "unsigned-varint 0.3.2", "void", ] @@ -2875,17 +2871,17 @@ checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" [[package]] name = "memchr" -version = "2.3.0" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3197e20c7edb283f87c071ddfc7a2cca8f8e0b888c242959846a6fce03c72223" +checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" [[package]] name = "memoffset" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" +checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" dependencies = [ - "rustc_version", + "autocfg 1.0.0", ] [[package]] @@ -2897,7 +2893,7 @@ dependencies = [ "ahash 0.2.18", "hash-db", "hashbrown 0.6.3", - "parity-util-mem 0.5.1", + "parity-util-mem 0.5.2", ] [[package]] @@ -3016,9 +3012,9 @@ dependencies = [ [[package]] name = "multimap" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97fbd5d00e0e37bfb10f433af8f5aaf631e739368dc9fc28286ca81ca4948dc" +checksum = "d8883adfde9756c1d30b0f519c9b8c502a94b41ac62f696453c37c7fc0a958ce" [[package]] name = "multistream-select" @@ -3031,7 +3027,7 @@ dependencies = [ "log 0.4.8", "smallvec 1.2.0", "tokio-io", - "unsigned-varint 0.3.1", + "unsigned-varint 0.3.2", ] [[package]] @@ -3056,8 +3052,8 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "security-framework 0.4.1", - "security-framework-sys 0.4.1", + "security-framework 0.4.2", + "security-framework-sys 0.4.2", "tempfile", ] @@ -3108,12 +3104,12 @@ checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" [[package]] name = "nom" -version = "4.2.3" +version = "5.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" +checksum = "0b471253da97532da4b61552249c521e01e736071f71c1a4f7ebbfbf0a06aad6" dependencies = [ "memchr", - "version_check 0.1.5", + "version_check 0.9.1", ] [[package]] @@ -3139,9 +3135,9 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da4dc79f9e6c81bef96148c8f6b8e72ad4541caa4a24373e900a36da07de03a3" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" dependencies = [ "autocfg 1.0.0", "num-bigint", @@ -3429,9 +3425,9 @@ dependencies = [ [[package]] name = "parity-bytes" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c276d76c5333b8c2579e02d49a06733a55b8282d2d9b13e8d53b6406bd7e30a" +checksum = "16b56e3a2420138bdb970f84dfb9c774aea80fa0e7371549eedec0d80c209c67" [[package]] name = "parity-crypto" @@ -3476,7 +3472,7 @@ dependencies = [ "secp256k1 0.17.2", "sha2", "subtle 2.2.2", - "tiny-keccak 2.0.1", + "tiny-keccak 2.0.2", "zeroize 1.1.0", ] @@ -3512,7 +3508,7 @@ dependencies = [ "percent-encoding 2.1.0", "serde", "static_assertions", - "unsigned-varint 0.3.1", + "unsigned-varint 0.3.2", "url 2.1.1", ] @@ -3543,7 +3539,7 @@ dependencies = [ "sha-1", "sha2", "sha3", - "unsigned-varint 0.3.1", + "unsigned-varint 0.3.2", ] [[package]] @@ -3566,9 +3562,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a0ec292e92e8ec7c58e576adacc1e3f399c597c8f263c42f18420abe58e7245" dependencies = [ "proc-macro-crate", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -3579,9 +3575,9 @@ checksum = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" [[package]] name = "parity-util-mem" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef1476e40bf8f5c6776e9600983435821ca86eb9819d74a6207cca69d091406a" +checksum = "9344bc978467339b9ae688f9dcf279d1aaa0ccfc88e9a780c729b765a82d57d5" dependencies = [ "cfg-if", "impl-trait-for-tuples", @@ -3612,8 +3608,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" dependencies = [ - "proc-macro2 1.0.8", - "syn 1.0.14", + "proc-macro2 1.0.10", + "syn 1.0.17", "synstructure 0.12.3", ] @@ -3675,9 +3671,9 @@ dependencies = [ [[package]] name = "paste" -version = "0.1.6" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "423a519e1c6e828f1e73b720f9d9ed2fa643dce8a7737fb43235ce0b41eeaa49" +checksum = "ab4fb1930692d1b6a9cfabdde3d06ea0a7d186518e2f4d67660d8970e2fa647a" dependencies = [ "paste-impl", "proc-macro-hack", @@ -3685,14 +3681,14 @@ dependencies = [ [[package]] name = "paste-impl" -version = "0.1.6" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5" +checksum = "a62486e111e571b1e93b710b61e8f493c0013be39629b714cb166bdb06aa5a8a" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -3753,9 +3749,9 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -3778,9 +3774,9 @@ checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" [[package]] name = "plain_hasher" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1c24f5061a6a53aaa21b0aaaa2e1beb5271a9ecc8c5bd7ae9ac92969070a2a" +checksum = "1e19e6491bdde87c2c43d70f4c194bc8a758f2eb732df00f61e43f7362e3b4cc" dependencies = [ "crunchy", ] @@ -3828,46 +3824,41 @@ dependencies = [ [[package]] name = "proc-macro-error" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7959c6467d962050d639361f7703b2051c43036d03493c36f01d440fdd3138a" +checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", "version_check 0.9.1", ] [[package]] name = "proc-macro-error-attr" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4002d9f55991d5e019fb940a90e1a95eb80c24e77cb2462dd4dc869604d543a" +checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", "syn-mid", "version_check 0.9.1", ] [[package]] name = "proc-macro-hack" -version = "0.5.11" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" -dependencies = [ - "proc-macro2 1.0.8", - "quote 1.0.3", - "syn 1.0.14", -] +checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63" [[package]] name = "proc-macro-nested" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" +checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694" [[package]] name = "proc-macro2" @@ -3880,9 +3871,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" +checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" dependencies = [ "unicode-xid 0.2.0", ] @@ -3909,10 +3900,10 @@ dependencies = [ "async-std", "derive_more", "futures-util", - "hyper 0.13.2", + "hyper 0.13.4", "log 0.4.8", "prometheus", - "tokio 0.2.11", + "tokio 0.2.16", ] [[package]] @@ -3951,9 +3942,9 @@ checksum = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72" dependencies = [ "anyhow", "itertools", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -3968,9 +3959,9 @@ dependencies = [ [[package]] name = "protobuf" -version = "2.10.2" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a5325d019a4d837d3abde0a836920f959e33d350f77b5f1e289e061e774942" +checksum = "71964f34fd51cf04882d7ae3325fa0794d4cad66a03d0003f38d8ae4f63ba126" [[package]] name = "quick-error" @@ -4004,7 +3995,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", ] [[package]] @@ -4076,7 +4067,7 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ "getrandom", "libc", - "rand_chacha 0.2.1", + "rand_chacha 0.2.2", "rand_core 0.5.1", "rand_hc 0.2.0", ] @@ -4093,11 +4084,11 @@ dependencies = [ [[package]] name = "rand_chacha" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ - "c2-chacha", + "ppv-lite86", "rand_core 0.5.1", ] @@ -4237,9 +4228,9 @@ checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" [[package]] name = "regex" -version = "1.3.4" +version = "1.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" +checksum = "7f6946991529684867e47d86474e3a6d0c0ab9b82d5821e314b1ede31fa3a4b3" dependencies = [ "aho-corasick", "memchr", @@ -4249,9 +4240,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.14" +version = "0.6.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06" +checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae" [[package]] name = "remove_dir_all" @@ -4264,9 +4255,9 @@ dependencies = [ [[package]] name = "ring" -version = "0.16.11" +version = "0.16.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "741ba1704ae21999c00942f9f5944f801e977f54302af346b596287599ad1862" +checksum = "1ba5a8ec64ee89a76c98c549af81ff14813df09c3e6dc4766c3856da48597a0c" dependencies = [ "cc", "lazy_static", @@ -4290,9 +4281,9 @@ dependencies = [ [[package]] name = "rlp" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a44d5ae8afcb238af8b75640907edc6c931efcfab2c854e81ed35fa080f84cd" +checksum = "4a7d3f9bed94764eac15b8f14af59fac420c236adaff743b7bcc88e265cb4345" dependencies = [ "rustc-hex", ] @@ -4375,9 +4366,9 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -4393,9 +4384,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" +checksum = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76" [[package]] name = "safe-mix" @@ -4508,9 +4499,9 @@ version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "proc-macro-crate", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -4530,7 +4521,7 @@ dependencies = [ "lazy_static", "log 0.4.8", "names", - "parity-util-mem 0.5.1", + "parity-util-mem 0.5.2", "prometheus-exporter", "regex", "rpassword", @@ -4549,7 +4540,7 @@ dependencies = [ "sp-state-machine 0.8.0-alpha.2", "structopt", "time 0.1.42", - "tokio 0.2.11", + "tokio 0.2.16", ] [[package]] @@ -4696,7 +4687,7 @@ dependencies = [ "linked-hash-map", "log 0.4.8", "parity-scale-codec", - "parity-util-mem 0.5.1", + "parity-util-mem 0.5.2", "parking_lot 0.10.0", "rand 0.7.3", "sc-client 0.8.0-alpha.2", @@ -4957,7 +4948,7 @@ dependencies = [ "ansi_term 0.12.1", "futures 0.3.4", "log 0.4.8", - "parity-util-mem 0.5.1", + "parity-util-mem 0.5.2", "sc-client-api 2.0.0-alpha.2", "sc-network 0.8.0-alpha.2", "sc-service", @@ -5041,7 +5032,7 @@ dependencies = [ "sp-core 2.0.0-alpha.2", "sp-runtime 2.0.0-alpha.2", "thiserror", - "unsigned-varint 0.3.1", + "unsigned-varint 0.3.2", "void", "wasm-timer", "zeroize 1.1.0", @@ -5093,7 +5084,7 @@ dependencies = [ "sp-runtime 2.0.0-alpha.5", "substrate-prometheus-endpoint", "thiserror", - "unsigned-varint 0.3.1", + "unsigned-varint 0.3.2", "void", "wasm-timer", "zeroize 1.1.0", @@ -5140,7 +5131,7 @@ dependencies = [ "fnv", "futures 0.3.4", "futures-timer 3.0.2", - "hyper 0.13.2", + "hyper 0.13.4", "hyper-rustls", "log 0.4.8", "num_cpus", @@ -5265,7 +5256,7 @@ dependencies = [ "log 0.4.8", "parity-multiaddr 0.5.0", "parity-scale-codec", - "parity-util-mem 0.5.1", + "parity-util-mem 0.5.2", "parking_lot 0.10.0", "prometheus-exporter", "sc-chain-spec", @@ -5379,7 +5370,7 @@ dependencies = [ "futures 0.3.4", "linked-hash-map", "log 0.4.8", - "parity-util-mem 0.5.1", + "parity-util-mem 0.5.2", "parking_lot 0.10.0", "serde", "sp-blockchain 2.0.0-alpha.2", @@ -5400,7 +5391,7 @@ dependencies = [ "futures-timer 2.0.2", "log 0.4.8", "parity-scale-codec", - "parity-util-mem 0.5.1", + "parity-util-mem 0.5.2", "parking_lot 0.10.0", "sc-client-api 2.0.0-alpha.2", "sc-transaction-graph", @@ -5414,9 +5405,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507a9e6e8ffe0a4e0ebb9a10293e62fdf7657c06f1b8bb07a8fcf697d2abf295" +checksum = "039c25b130bd8c1321ee2d7de7fde2659fa9c2744e4bb29711cfc852ea53cd19" dependencies = [ "lazy_static", "winapi 0.3.8", @@ -5465,9 +5456,9 @@ checksum = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" [[package]] name = "scopeguard" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "scrypt" @@ -5494,9 +5485,9 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.15.3" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5618cd39d19d7a3964dde3bd1cc940c58097538ca42b6c3ea1cd66634d39652" +checksum = "4d311229f403d64002e9eed9964dfa5a0a0c1ac443344f7546bf48e916c6053a" dependencies = [ "cc", "rand 0.6.5", @@ -5535,14 +5526,15 @@ dependencies = [ [[package]] name = "security-framework" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97bbedbe81904398b6ebb054b3e912f99d55807125790f3198ac990d98def5b0" +checksum = "572dfa3a0785509e7a44b5b4bebcf94d41ba34e9ed9eb9df722545c3b3c4144a" dependencies = [ "bitflags 1.2.1", "core-foundation 0.7.0", "core-foundation-sys 0.7.0", - "security-framework-sys 0.4.1", + "libc", + "security-framework-sys 0.4.2", ] [[package]] @@ -5556,9 +5548,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06fd2f23e31ef68dd2328cc383bd493142e46107a3a0e24f7d734e3f3b80fe4c" +checksum = "8ddb15a5fec93b7021b8a9e96009c5d8d51c15673569f7c0f6b7204e5b7b404f" dependencies = [ "core-foundation-sys 0.7.0", "libc", @@ -5587,9 +5579,9 @@ checksum = "a0eddf2e8f50ced781f288c19f18621fa72a3779e3cb58dbf23b07469b0abeb4" [[package]] name = "serde" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e707fbbf255b8fc8c3b99abb91e7257a622caeb20a9818cbadbeeede4e0932ff" +checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399" dependencies = [ "serde_derive", ] @@ -5606,20 +5598,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8" +checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] name = "serde_json" -version = "1.0.50" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78a7a12c167809363ec3bd7329fc0a3369056996de43c4b37ef3cd54a6ce4867" +checksum = "da07b57ee2623368351e9a0488bb0b261322a15a6e0ae53e243cbdc0f4208da9" dependencies = [ "itoa", "ryu", @@ -5746,9 +5738,9 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a945ec7f7ce853e89ffa36be1e27dce9a43e82ff9093bf3461c30d5da74ed11b" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -5794,7 +5786,7 @@ dependencies = [ "bytes 0.5.4", "flate2", "futures 0.3.4", - "http 0.2.0", + "http 0.2.1", "httparse", "log 0.4.8", "rand 0.7.3", @@ -5804,12 +5796,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "sourcefile" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" - [[package]] name = "sp-allocator" version = "2.0.0-alpha.2" @@ -5873,9 +5859,9 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "blake2-rfc", "proc-macro-crate", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -5886,9 +5872,9 @@ checksum = "73a94ac1f228f99fb5279d7983f6bcde83bf1fe5824f9a56e5f7a81cc8a7069c" dependencies = [ "blake2-rfc", "proc-macro-crate", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -6147,7 +6133,7 @@ dependencies = [ "log 0.4.8", "num-traits", "parity-scale-codec", - "parity-util-mem 0.5.1", + "parity-util-mem 0.5.2", "parking_lot 0.10.0", "primitive-types 0.6.2", "rand 0.7.3", @@ -6163,7 +6149,7 @@ dependencies = [ "sp-storage 2.0.0-alpha.2", "substrate-bip39 0.3.1", "tiny-bip39", - "tiny-keccak 2.0.1", + "tiny-keccak 2.0.2", "twox-hash", "wasmi", "zeroize 1.1.0", @@ -6205,7 +6191,7 @@ dependencies = [ "sp-storage 2.0.0-alpha.5", "substrate-bip39 0.4.1", "tiny-bip39", - "tiny-keccak 2.0.1", + "tiny-keccak 2.0.2", "twox-hash", "wasmi", "zeroize 1.1.0", @@ -6216,9 +6202,9 @@ name = "sp-debug-derive" version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -6227,9 +6213,9 @@ version = "2.0.0-alpha.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "124f3ffa2d897139864715cc624811ca997ca92be8880229143c6dee801b5ab2" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -6431,7 +6417,7 @@ dependencies = [ "impl-trait-for-tuples", "log 0.4.8", "parity-scale-codec", - "parity-util-mem 0.5.1", + "parity-util-mem 0.5.2", "paste", "rand 0.7.3", "serde", @@ -6501,9 +6487,9 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "Inflector", "proc-macro-crate", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -6514,9 +6500,9 @@ checksum = "5f1d9e32fa5db2f3dd89affbd3c97959432272c9e52e4e2610dad32dd4705784" dependencies = [ "Inflector", "proc-macro-crate", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -6781,9 +6767,9 @@ checksum = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" [[package]] name = "standback" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4edf667ea8f60afc06d6aeec079d20d5800351109addec1faea678a8663da4e1" +checksum = "ee531c64ad0f80d289504bd32fb047f42a9e957cda584276ab96eb587e9abac3" [[package]] name = "static_assertions" @@ -6811,11 +6797,11 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", "serde", "serde_derive", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -6825,13 +6811,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" dependencies = [ "base-x", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", "serde", "serde_derive", "serde_json", "sha1", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -6883,9 +6869,9 @@ checksum = "3f88b8e18c69496aad6f9ddf4630dd7d585bcaf765786cb415b9aec2fe5a0430" dependencies = [ "heck", "proc-macro-error", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -6904,9 +6890,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0054a7df764039a6cd8592b9de84be4bec368ff081d203a7d5371cbfa8e65c81" dependencies = [ "heck", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -6966,10 +6952,10 @@ dependencies = [ "async-std", "derive_more", "futures-util", - "hyper 0.13.2", + "hyper 0.13.4", "log 0.4.8", "prometheus", - "tokio 0.2.11", + "tokio 0.2.16", ] [[package]] @@ -7002,11 +6988,11 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" +checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", "unicode-xid 0.2.0", ] @@ -7017,9 +7003,9 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -7040,9 +7026,9 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", "unicode-xid 0.2.0", ] @@ -7105,22 +7091,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee14bf8e6767ab4c687c9e8bc003879e042a96fd67a3ba5934eadb6536bef4db" +checksum = "f0570dc61221295909abdb95c739f2e74325e14293b2026b0a7e195091ec54ae" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7b51e1fbc44b5a0840be594fbc0f960be09050f2617e61e6aa43bef97cd3ef4" +checksum = "227362df41d566be41a28f64401e07a043157c21c14b9785a0d8e256f940a8fd" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] @@ -7184,16 +7170,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e987cfe0537f575b5fc99909de6185f6c19c3ad8889e2275e686a873d0869ba1" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] name = "tiny-bip39" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6848cd8f566953ce1e8faeba12ee23cbdbb0437754792cd857d44628b5685e3" +checksum = "b0165e045cc2ae1660270ca65e1676dbaab60feb0f91b10f7d0665e9b47e31f2" dependencies = [ "failure", "hmac", @@ -7216,9 +7202,9 @@ dependencies = [ [[package]] name = "tiny-keccak" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2953ca5148619bc99695c1274cb54c5275bbb913c6adad87e72eaf8db9787f69" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" dependencies = [ "crunchy", ] @@ -7249,12 +7235,13 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.11" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fdd17989496f49cdc57978c96f0c9fe5e4a58a8bddc6813c449a4624f6a030b" +checksum = "ee5a0dd887e37d37390c13ff8ac830f992307fe30a1fff0ab8427af67211ba28" dependencies = [ "bytes 0.5.4", "fnv", + "futures-core", "iovec", "lazy_static", "libc", @@ -7389,7 +7376,7 @@ checksum = "141afec0978abae6573065a48882c6bae44c5cc61db9b511ac4abf6a09bfd9cc" dependencies = [ "futures-core", "rustls", - "tokio 0.2.11", + "tokio 0.2.16", "webpki", ] @@ -7530,16 +7517,16 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" +checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" dependencies = [ "bytes 0.5.4", "futures-core", "futures-sink", "log 0.4.8", "pin-project-lite", - "tokio 0.2.11", + "tokio 0.2.16", ] [[package]] @@ -7559,9 +7546,9 @@ checksum = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" [[package]] name = "tracing" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e213bd24252abeb86a0b7060e02df677d367ce6cb772cef17e9214b8390a8d3" +checksum = "1721cc8cf7d770cc4257872507180f35a4797272f5962f24c806af9e7faf52ab" dependencies = [ "cfg-if", "tracing-attributes", @@ -7570,19 +7557,19 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cfd395def5a60236e187e1ff905cb55668a59f29928dec05e6e1b1fd2ac1f3" +checksum = "7fbad39da2f9af1cae3016339ad7f2c7a9e870f12e8fd04c4fd7ef35b30c0d2b" dependencies = [ "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", ] [[package]] name = "tracing-core" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13a46f11e372b8bd4b4398ea54353412fdd7fd42a8370c7e543e218cf7661978" +checksum = "0aa83a9a47081cd522c09c81b31aec2c9273424976f922ad61c053b58350b715" dependencies = [ "lazy_static", ] @@ -7617,9 +7604,9 @@ dependencies = [ [[package]] name = "triehash" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a518c10ed2591fd67bbafd7d5daf725767d07b129d8c99b3b3831eeabd639ed9" +checksum = "f490aa7aa4e4d07edeba442c007e42e3e7f43aafb5112c5b047fff0b1aa5449c" dependencies = [ "hash-db", "rlp", @@ -7743,12 +7730,13 @@ checksum = "a7f0023a96687fe169081e8adce3f65e3874426b7886e9234d490af2dc077959" [[package]] name = "unsigned-varint" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b7ffb36714206d2f5f05d61a2bc350415c642f2c54433f0ebf829afbe41d570" +checksum = "f38e01ad4b98f042e166c1bf9a13f9873a99d79eaa171ce7ca81e6dd0f895d8a" dependencies = [ "bytes 0.5.4", - "futures 0.3.4", + "futures-io", + "futures-util", "futures_codec", ] @@ -7849,9 +7837,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasm-bindgen" -version = "0.2.58" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c" +checksum = "2cc57ce05287f8376e998cbddfb4c8cb43b84a7ec55cf4551d7c00eef317a47f" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -7859,24 +7847,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.58" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11cdb95816290b525b32587d76419facd99662a07e59d3cdb560488a819d9a45" +checksum = "d967d37bf6c16cca2973ca3af071d0a2523392e4a594548155d89a678f4237cd" dependencies = [ "bumpalo", "lazy_static", "log 0.4.8", - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.8" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bbdd49e3e28b40dec6a9ba8d17798245ce32b019513a845369c641b275135d9" +checksum = "7add542ea1ac7fdaa9dc25e031a6af33b7d63376292bd24140c637d00d1c312a" dependencies = [ "cfg-if", "js-sys", @@ -7886,9 +7874,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.58" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "574094772ce6921576fb6f2e3f7497b8a76273b6db092be18fc48a082de09dc3" +checksum = "8bd151b63e1ea881bb742cd20e1d6127cef28399558f3b5d415289bc41eee3a4" dependencies = [ "quote 1.0.3", "wasm-bindgen-macro-support", @@ -7896,38 +7884,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.58" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" +checksum = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.58" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e7e61fc929f4c0dddb748b102ebf9f632e2b8d739f2016542b4de2965a9601" - -[[package]] -name = "wasm-bindgen-webidl" -version = "0.2.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef012a0d93fc0432df126a8eaf547b2dce25a8ce9212e1d3cbeef5c11157975d" -dependencies = [ - "anyhow", - "heck", - "log 0.4.8", - "proc-macro2 1.0.8", - "quote 1.0.3", - "syn 1.0.14", - "wasm-bindgen-backend", - "weedle", -] +checksum = "daf76fe7d25ac79748a37538b7daeed1c7a6867c92d3245c12c6222e4a20d639" [[package]] name = "wasm-timer" @@ -7970,15 +7942,12 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.35" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf97caf6aa8c2b1dac90faf0db529d9d63c93846cca4911856f78a83cebf53b" +checksum = "2d6f51648d8c56c366144378a33290049eafdd784071077f6fe37dae64c1c4cb" dependencies = [ - "anyhow", "js-sys", - "sourcefile", "wasm-bindgen", - "wasm-bindgen-webidl", ] [[package]] @@ -8062,20 +8031,11 @@ dependencies = [ "url 1.7.2", ] -[[package]] -name = "weedle" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" -dependencies = [ - "nom", -] - [[package]] name = "which" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5475d47078209a02e60614f7ba5e645ef3ed60f771920ac1906d7c1cc65024c8" +checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" dependencies = [ "libc", ] @@ -8110,9 +8070,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" +checksum = "fa515c5163a99cc82bab70fd3bfdd36d827be85de63737b40fcef2ce084a436e" dependencies = [ "winapi 0.3.8", ] @@ -8176,17 +8136,16 @@ checksum = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" [[package]] name = "yamux" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03098897b734bd943ab23f6aa9f98aafd72a88516deedd66f9d564c57bf2f19" +checksum = "84300bb493cc878f3638b981c62b4632ec1a5c52daaa3036651e8c106d3b55ea" dependencies = [ - "bytes 0.5.4", "futures 0.3.4", "log 0.4.8", "nohash-hasher", "parking_lot 0.10.0", "rand 0.7.3", - "thiserror", + "static_assertions", ] [[package]] @@ -8225,8 +8184,8 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.10", "quote 1.0.3", - "syn 1.0.14", + "syn 1.0.17", "synstructure 0.12.3", ] From f7e976888d1363acbc0490e864074ffaf8f73c7a Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 6 Apr 2020 12:03:05 +0300 Subject: [PATCH 05/92] fixes --- Cargo.lock | 629 +++---------------- modules/ethereum-contract/builtin/Cargo.toml | 5 +- modules/ethereum-contract/builtin/src/lib.rs | 171 ++++- 3 files changed, 260 insertions(+), 545 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9b42a515d2..18db8f3571 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -450,11 +450,11 @@ dependencies = [ "log 0.4.8", "sc-basic-authorship", "sc-cli", - "sc-client 0.8.0-alpha.2", + "sc-client", "sc-consensus-aura", - "sc-executor 0.8.0-alpha.2", - "sc-finality-grandpa 0.8.0-alpha.2", - "sc-network 0.8.0-alpha.2", + "sc-executor", + "sc-finality-grandpa", + "sc-network", "sc-service", "sc-transaction-pool", "sp-bridge-eth-poa", @@ -464,7 +464,7 @@ dependencies = [ "sp-finality-grandpa 2.0.0-alpha.2", "sp-inherents 2.0.0-alpha.2", "sp-runtime 2.0.0-alpha.2", - "sp-transaction-pool 2.0.0-alpha.2", + "sp-transaction-pool", "structopt", "substrate-build-script-utils", "vergen", @@ -498,7 +498,7 @@ dependencies = [ "sp-runtime 2.0.0-alpha.2", "sp-session", "sp-std 2.0.0-alpha.2", - "sp-transaction-pool 2.0.0-alpha.2", + "sp-transaction-pool", "sp-version 2.0.0-alpha.2", "substrate-wasm-builder-runner", ] @@ -1036,8 +1036,9 @@ dependencies = [ "bridge-node-runtime", "finality-grandpa", "parity-scale-codec", - "sc-finality-grandpa 0.8.0-alpha.5", + "sp-blockchain 2.0.0-alpha.5", "sp-finality-grandpa 2.0.0-alpha.5", + "sp-runtime 2.0.0-alpha.5", ] [[package]] @@ -1064,7 +1065,7 @@ dependencies = [ "serde_json", "sp-bridge-eth-poa", "sp-core 2.0.0-alpha.2", - "sp-keyring 2.0.0-alpha.2", + "sp-keyring", "sp-runtime 2.0.0-alpha.2", "time 0.2.9", "web3", @@ -1259,15 +1260,6 @@ dependencies = [ "parity-scale-codec", ] -[[package]] -name = "fork-tree" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b2b3ac9016db4aa757dcab0a52c6911e6c98820d29bc75092176b98e73582bb" -dependencies = [ - "parity-scale-codec", -] - [[package]] name = "frame-benchmarking" version = "2.0.0-alpha.2" @@ -2279,23 +2271,13 @@ dependencies = [ "smallvec 1.2.0", ] -[[package]] -name = "kvdb" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cad096c6849b2ef027fabe35c4aed356d0e3d3f586d0a8361e5e17f1e50a7ce5" -dependencies = [ - "parity-util-mem 0.6.0", - "smallvec 1.2.0", -] - [[package]] name = "kvdb-memorydb" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9355274e5a9e0a7e8ef43916950eae3949024de2a8dffe4d5a6c13974a37c8e" dependencies = [ - "kvdb 0.4.0", + "kvdb", "parity-util-mem 0.5.2", "parking_lot 0.10.0", ] @@ -2308,7 +2290,7 @@ checksum = "af36fd66ccd99f3f771ae39b75aaba28b952372b6debfb971134bf1f03466ab2" dependencies = [ "fs-swap", "interleaved-ordered", - "kvdb 0.4.0", + "kvdb", "log 0.4.8", "num_cpus", "owning_ref", @@ -3249,7 +3231,7 @@ dependencies = [ "sp-io 2.0.0-alpha.2", "sp-runtime 2.0.0-alpha.2", "sp-std 2.0.0-alpha.2", - "sp-timestamp 2.0.0-alpha.2", + "sp-timestamp", ] [[package]] @@ -3310,7 +3292,7 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "serde", - "sp-finality-tracker 2.0.0-alpha.2", + "sp-finality-tracker", "sp-inherents 2.0.0-alpha.2", "sp-runtime 2.0.0-alpha.2", "sp-std 2.0.0-alpha.2", @@ -3394,7 +3376,7 @@ dependencies = [ "sp-io 2.0.0-alpha.2", "sp-runtime 2.0.0-alpha.2", "sp-std 2.0.0-alpha.2", - "sp-timestamp 2.0.0-alpha.2", + "sp-timestamp", ] [[package]] @@ -4431,17 +4413,17 @@ dependencies = [ "futures 0.3.4", "log 0.4.8", "parity-scale-codec", - "sc-block-builder 0.8.0-alpha.2", - "sc-client 0.8.0-alpha.2", - "sc-client-api 2.0.0-alpha.2", - "sc-telemetry 2.0.0-alpha.2", + "sc-block-builder", + "sc-client", + "sc-client-api", + "sc-telemetry", "sp-api 2.0.0-alpha.2", "sp-blockchain 2.0.0-alpha.2", "sp-consensus 0.8.0-alpha.2", "sp-core 2.0.0-alpha.2", "sp-inherents 2.0.0-alpha.2", "sp-runtime 2.0.0-alpha.2", - "sp-transaction-pool 2.0.0-alpha.2", + "sp-transaction-pool", "tokio-executor 0.2.0-alpha.6", ] @@ -4451,7 +4433,7 @@ version = "0.8.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "parity-scale-codec", - "sc-client-api 2.0.0-alpha.2", + "sc-client-api", "sp-api 2.0.0-alpha.2", "sp-block-builder 2.0.0-alpha.2", "sp-blockchain 2.0.0-alpha.2", @@ -4461,23 +4443,6 @@ dependencies = [ "sp-state-machine 0.8.0-alpha.2", ] -[[package]] -name = "sc-block-builder" -version = "0.8.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "288d056ccb51111940a020cc4dda2b3ecd539ac680a20a7614b45b52615e1b62" -dependencies = [ - "parity-scale-codec", - "sc-client-api 2.0.0-alpha.5", - "sp-api 2.0.0-alpha.5", - "sp-block-builder 2.0.0-alpha.5", - "sp-blockchain 2.0.0-alpha.5", - "sp-consensus 0.8.0-alpha.5", - "sp-core 2.0.0-alpha.5", - "sp-runtime 2.0.0-alpha.5", - "sp-state-machine 0.8.0-alpha.5", -] - [[package]] name = "sc-chain-spec" version = "2.0.0-alpha.2" @@ -4485,8 +4450,8 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "impl-trait-for-tuples", "sc-chain-spec-derive", - "sc-network 0.8.0-alpha.2", - "sc-telemetry 2.0.0-alpha.2", + "sc-network", + "sc-telemetry", "serde", "serde_json", "sp-core 2.0.0-alpha.2", @@ -4525,16 +4490,16 @@ dependencies = [ "prometheus-exporter", "regex", "rpassword", - "sc-client-api 2.0.0-alpha.2", + "sc-client-api", "sc-informant", - "sc-network 0.8.0-alpha.2", + "sc-network", "sc-service", - "sc-telemetry 2.0.0-alpha.2", + "sc-telemetry", "sc-tracing", "serde_json", "sp-blockchain 2.0.0-alpha.2", "sp-core 2.0.0-alpha.2", - "sp-keyring 2.0.0-alpha.2", + "sp-keyring", "sp-panic-handler 2.0.0-alpha.2", "sp-runtime 2.0.0-alpha.2", "sp-state-machine 0.8.0-alpha.2", @@ -4553,21 +4518,21 @@ dependencies = [ "futures 0.3.4", "hash-db", "hex-literal", - "kvdb 0.4.0", + "kvdb", "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.0", - "sc-block-builder 0.8.0-alpha.2", - "sc-client-api 2.0.0-alpha.2", - "sc-executor 0.8.0-alpha.2", - "sc-telemetry 2.0.0-alpha.2", + "sc-block-builder", + "sc-client-api", + "sc-executor", + "sc-telemetry", "sp-api 2.0.0-alpha.2", "sp-blockchain 2.0.0-alpha.2", "sp-consensus 0.8.0-alpha.2", "sp-core 2.0.0-alpha.2", "sp-externalities 0.8.0-alpha.2", "sp-inherents 2.0.0-alpha.2", - "sp-keyring 2.0.0-alpha.2", + "sp-keyring", "sp-runtime 2.0.0-alpha.2", "sp-state-machine 0.8.0-alpha.2", "sp-std 2.0.0-alpha.2", @@ -4576,41 +4541,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "sc-client" -version = "0.8.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bc77d90c2647134251ed73494515106da17aeee66dd9f5ae067bfa061bb19c9" -dependencies = [ - "derive_more", - "fnv", - "futures 0.3.4", - "hash-db", - "hex-literal", - "kvdb 0.5.0", - "log 0.4.8", - "parity-scale-codec", - "parking_lot 0.10.0", - "sc-block-builder 0.8.0-alpha.5", - "sc-client-api 2.0.0-alpha.5", - "sc-executor 0.8.0-alpha.5", - "sc-telemetry 2.0.0-alpha.5", - "sp-api 2.0.0-alpha.5", - "sp-blockchain 2.0.0-alpha.5", - "sp-consensus 0.8.0-alpha.5", - "sp-core 2.0.0-alpha.5", - "sp-externalities 0.8.0-alpha.5", - "sp-inherents 2.0.0-alpha.5", - "sp-keyring 2.0.0-alpha.5", - "sp-runtime 2.0.0-alpha.5", - "sp-state-machine 0.8.0-alpha.5", - "sp-std 2.0.0-alpha.5", - "sp-trie 2.0.0-alpha.5", - "sp-version 2.0.0-alpha.5", - "substrate-prometheus-endpoint", - "tracing", -] - [[package]] name = "sc-client-api" version = "2.0.0-alpha.2" @@ -4621,67 +4551,34 @@ dependencies = [ "futures 0.3.4", "hash-db", "hex-literal", - "kvdb 0.4.0", + "kvdb", "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.0", - "sc-executor 0.8.0-alpha.2", - "sc-telemetry 2.0.0-alpha.2", + "sc-executor", + "sc-telemetry", "sp-api 2.0.0-alpha.2", "sp-blockchain 2.0.0-alpha.2", "sp-consensus 0.8.0-alpha.2", "sp-core 2.0.0-alpha.2", "sp-externalities 0.8.0-alpha.2", "sp-inherents 2.0.0-alpha.2", - "sp-keyring 2.0.0-alpha.2", + "sp-keyring", "sp-runtime 2.0.0-alpha.2", "sp-state-machine 0.8.0-alpha.2", "sp-std 2.0.0-alpha.2", - "sp-transaction-pool 2.0.0-alpha.2", + "sp-transaction-pool", "sp-trie 2.0.0-alpha.2", "sp-version 2.0.0-alpha.2", ] -[[package]] -name = "sc-client-api" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f17aa33afbc6b4f8c64a17922dff034c7d430919fc0835319f6663c8f4deddc" -dependencies = [ - "derive_more", - "fnv", - "futures 0.3.4", - "hash-db", - "hex-literal", - "kvdb 0.5.0", - "log 0.4.8", - "parity-scale-codec", - "parking_lot 0.10.0", - "sc-executor 0.8.0-alpha.5", - "sc-telemetry 2.0.0-alpha.5", - "sp-api 2.0.0-alpha.5", - "sp-blockchain 2.0.0-alpha.5", - "sp-consensus 0.8.0-alpha.5", - "sp-core 2.0.0-alpha.5", - "sp-externalities 0.8.0-alpha.5", - "sp-inherents 2.0.0-alpha.5", - "sp-keyring 2.0.0-alpha.5", - "sp-runtime 2.0.0-alpha.5", - "sp-state-machine 0.8.0-alpha.5", - "sp-std 2.0.0-alpha.5", - "sp-storage 2.0.0-alpha.5", - "sp-transaction-pool 2.0.0-alpha.5", - "sp-trie 2.0.0-alpha.5", - "sp-version 2.0.0-alpha.5", -] - [[package]] name = "sc-client-db" version = "0.8.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "hash-db", - "kvdb 0.4.0", + "kvdb", "kvdb-memorydb", "kvdb-rocksdb", "linked-hash-map", @@ -4690,9 +4587,9 @@ dependencies = [ "parity-util-mem 0.5.2", "parking_lot 0.10.0", "rand 0.7.3", - "sc-client 0.8.0-alpha.2", - "sc-client-api 2.0.0-alpha.2", - "sc-executor 0.8.0-alpha.2", + "sc-client", + "sc-client-api", + "sc-executor", "sc-state-db", "sp-blockchain 2.0.0-alpha.2", "sp-consensus 0.8.0-alpha.2", @@ -4713,11 +4610,11 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.0", - "sc-client 0.8.0-alpha.2", - "sc-client-api 2.0.0-alpha.2", + "sc-client", + "sc-client-api", "sc-consensus-slots", - "sc-keystore 2.0.0-alpha.2", - "sc-telemetry 2.0.0-alpha.2", + "sc-keystore", + "sc-telemetry", "sp-api 2.0.0-alpha.2", "sp-application-crypto 2.0.0-alpha.2", "sp-block-builder 2.0.0-alpha.2", @@ -4728,7 +4625,7 @@ dependencies = [ "sp-inherents 2.0.0-alpha.2", "sp-io 2.0.0-alpha.2", "sp-runtime 2.0.0-alpha.2", - "sp-timestamp 2.0.0-alpha.2", + "sp-timestamp", "sp-version 2.0.0-alpha.2", ] @@ -4742,8 +4639,8 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.0", - "sc-client-api 2.0.0-alpha.2", - "sc-telemetry 2.0.0-alpha.2", + "sc-client-api", + "sc-telemetry", "sp-api 2.0.0-alpha.2", "sp-blockchain 2.0.0-alpha.2", "sp-consensus 0.8.0-alpha.2", @@ -4765,47 +4662,20 @@ dependencies = [ "parity-scale-codec", "parity-wasm", "parking_lot 0.10.0", - "sc-executor-common 0.8.0-alpha.2", - "sc-executor-wasmi 0.8.0-alpha.2", + "sc-executor-common", + "sc-executor-wasmi", "sp-core 2.0.0-alpha.2", "sp-externalities 0.8.0-alpha.2", "sp-io 2.0.0-alpha.2", "sp-panic-handler 2.0.0-alpha.2", "sp-runtime-interface 2.0.0-alpha.2", - "sp-serializer 2.0.0-alpha.2", + "sp-serializer", "sp-trie 2.0.0-alpha.2", "sp-version 2.0.0-alpha.2", "sp-wasm-interface 2.0.0-alpha.2", "wasmi", ] -[[package]] -name = "sc-executor" -version = "0.8.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0ab992ed677c0d18c30a5a13f7a03af29a59cc74501c60e2e45eb35dc9467e5" -dependencies = [ - "derive_more", - "lazy_static", - "libsecp256k1", - "log 0.4.8", - "parity-scale-codec", - "parity-wasm", - "parking_lot 0.10.0", - "sc-executor-common 0.8.0-alpha.5", - "sc-executor-wasmi 0.8.0-alpha.5", - "sp-core 2.0.0-alpha.5", - "sp-externalities 0.8.0-alpha.5", - "sp-io 2.0.0-alpha.5", - "sp-panic-handler 2.0.0-alpha.5", - "sp-runtime-interface 2.0.0-alpha.5", - "sp-serializer 2.0.0-alpha.5", - "sp-trie 2.0.0-alpha.5", - "sp-version 2.0.0-alpha.5", - "sp-wasm-interface 2.0.0-alpha.5", - "wasmi", -] - [[package]] name = "sc-executor-common" version = "0.8.0-alpha.2" @@ -4814,31 +4684,14 @@ dependencies = [ "derive_more", "log 0.4.8", "parity-scale-codec", - "sp-allocator 2.0.0-alpha.2", + "sp-allocator", "sp-core 2.0.0-alpha.2", "sp-runtime-interface 2.0.0-alpha.2", - "sp-serializer 2.0.0-alpha.2", + "sp-serializer", "sp-wasm-interface 2.0.0-alpha.2", "wasmi", ] -[[package]] -name = "sc-executor-common" -version = "0.8.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859a874cc47a01fb44bd53b172773629abb2c0d155b4e6505c1ec438103ffe5b" -dependencies = [ - "derive_more", - "log 0.4.8", - "parity-scale-codec", - "sp-allocator 2.0.0-alpha.5", - "sp-core 2.0.0-alpha.5", - "sp-runtime-interface 2.0.0-alpha.5", - "sp-serializer 2.0.0-alpha.5", - "sp-wasm-interface 2.0.0-alpha.5", - "wasmi", -] - [[package]] name = "sc-executor-wasmi" version = "0.8.0-alpha.2" @@ -4847,31 +4700,14 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "parity-wasm", - "sc-executor-common 0.8.0-alpha.2", - "sp-allocator 2.0.0-alpha.2", + "sc-executor-common", + "sp-allocator", "sp-core 2.0.0-alpha.2", "sp-runtime-interface 2.0.0-alpha.2", "sp-wasm-interface 2.0.0-alpha.2", "wasmi", ] -[[package]] -name = "sc-executor-wasmi" -version = "0.8.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4af5cb944a100efd2c117846b1f42da4e303c2a9e48d5231922315861775c558" -dependencies = [ - "log 0.4.8", - "parity-scale-codec", - "parity-wasm", - "sc-executor-common 0.8.0-alpha.5", - "sp-allocator 2.0.0-alpha.5", - "sp-core 2.0.0-alpha.5", - "sp-runtime-interface 2.0.0-alpha.5", - "sp-wasm-interface 2.0.0-alpha.5", - "wasmi", -] - [[package]] name = "sc-finality-grandpa" version = "0.8.0-alpha.2" @@ -4879,7 +4715,7 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "assert_matches", "finality-grandpa", - "fork-tree 2.0.0-alpha.2", + "fork-tree", "futures 0.3.4", "futures-timer 3.0.2", "log 0.4.8", @@ -4887,59 +4723,23 @@ dependencies = [ "parking_lot 0.10.0", "pin-project", "rand 0.7.3", - "sc-client 0.8.0-alpha.2", - "sc-client-api 2.0.0-alpha.2", - "sc-keystore 2.0.0-alpha.2", - "sc-network 0.8.0-alpha.2", - "sc-network-gossip 0.8.0-alpha.2", - "sc-telemetry 2.0.0-alpha.2", + "sc-client", + "sc-client-api", + "sc-keystore", + "sc-network", + "sc-network-gossip", + "sc-telemetry", "serde_json", "sp-arithmetic 2.0.0-alpha.2", "sp-blockchain 2.0.0-alpha.2", "sp-consensus 0.8.0-alpha.2", "sp-core 2.0.0-alpha.2", "sp-finality-grandpa 2.0.0-alpha.2", - "sp-finality-tracker 2.0.0-alpha.2", + "sp-finality-tracker", "sp-inherents 2.0.0-alpha.2", "sp-runtime 2.0.0-alpha.2", ] -[[package]] -name = "sc-finality-grandpa" -version = "0.8.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aad8a1f0d03e8a7c3b1d8cd74050960365e347f739c131715f84f588dd051a4" -dependencies = [ - "assert_matches", - "finality-grandpa", - "fork-tree 2.0.0-alpha.5", - "futures 0.3.4", - "futures-timer 3.0.2", - "log 0.4.8", - "parity-scale-codec", - "parking_lot 0.10.0", - "pin-project", - "rand 0.7.3", - "sc-block-builder 0.8.0-alpha.5", - "sc-client 0.8.0-alpha.5", - "sc-client-api 2.0.0-alpha.5", - "sc-keystore 2.0.0-alpha.5", - "sc-network 0.8.0-alpha.5", - "sc-network-gossip 0.8.0-alpha.5", - "sc-telemetry 2.0.0-alpha.5", - "serde_json", - "sp-api 2.0.0-alpha.5", - "sp-arithmetic 2.0.0-alpha.5", - "sp-blockchain 2.0.0-alpha.5", - "sp-consensus 0.8.0-alpha.5", - "sp-core 2.0.0-alpha.5", - "sp-finality-grandpa 2.0.0-alpha.5", - "sp-finality-tracker 2.0.0-alpha.5", - "sp-inherents 2.0.0-alpha.5", - "sp-runtime 2.0.0-alpha.5", - "substrate-prometheus-endpoint", -] - [[package]] name = "sc-informant" version = "0.8.0-alpha.2" @@ -4949,8 +4749,8 @@ dependencies = [ "futures 0.3.4", "log 0.4.8", "parity-util-mem 0.5.2", - "sc-client-api 2.0.0-alpha.2", - "sc-network 0.8.0-alpha.2", + "sc-client-api", + "sc-network", "sc-service", "sp-blockchain 2.0.0-alpha.2", "sp-runtime 2.0.0-alpha.2", @@ -4972,22 +4772,6 @@ dependencies = [ "subtle 2.2.2", ] -[[package]] -name = "sc-keystore" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c17c8aa8cb9fa4aa710379dc4e119b848cd65fa0a4e2209b6c0f97ee7c2c8a" -dependencies = [ - "derive_more", - "hex", - "parking_lot 0.10.0", - "rand 0.7.3", - "serde_json", - "sp-application-crypto 2.0.0-alpha.5", - "sp-core 2.0.0-alpha.5", - "subtle 2.2.2", -] - [[package]] name = "sc-network" version = "0.8.0-alpha.2" @@ -4999,7 +4783,7 @@ dependencies = [ "either", "erased-serde", "fnv", - "fork-tree 2.0.0-alpha.2", + "fork-tree", "futures 0.3.4", "futures-timer 3.0.2", "futures_codec", @@ -5016,10 +4800,10 @@ dependencies = [ "prost-build", "rand 0.7.3", "rustc-hex", - "sc-block-builder 0.8.0-alpha.2", - "sc-client 0.8.0-alpha.2", - "sc-client-api 2.0.0-alpha.2", - "sc-peerset 2.0.0-alpha.2", + "sc-block-builder", + "sc-client", + "sc-client-api", + "sc-peerset", "serde", "serde_json", "slog", @@ -5028,7 +4812,7 @@ dependencies = [ "sp-arithmetic 2.0.0-alpha.2", "sp-blockchain 2.0.0-alpha.2", "sp-consensus 0.8.0-alpha.2", - "sp-consensus-babe 0.8.0-alpha.2", + "sp-consensus-babe", "sp-core 2.0.0-alpha.2", "sp-runtime 2.0.0-alpha.2", "thiserror", @@ -5038,58 +4822,6 @@ dependencies = [ "zeroize 1.1.0", ] -[[package]] -name = "sc-network" -version = "0.8.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0df01faa65b22aca751910a417f5a6ea28cefd9d3349c17fbc2ad8b7f190d390" -dependencies = [ - "bitflags 1.2.1", - "bytes 0.5.4", - "derive_more", - "either", - "erased-serde", - "fnv", - "fork-tree 2.0.0-alpha.5", - "futures 0.3.4", - "futures-timer 3.0.2", - "futures_codec", - "libp2p", - "linked-hash-map", - "linked_hash_set", - "log 0.4.8", - "lru", - "nohash-hasher", - "parity-scale-codec", - "parking_lot 0.10.0", - "pin-project", - "prost", - "prost-build", - "rand 0.7.3", - "rustc-hex", - "sc-block-builder 0.8.0-alpha.5", - "sc-client 0.8.0-alpha.5", - "sc-client-api 2.0.0-alpha.5", - "sc-peerset 2.0.0-alpha.5", - "serde", - "serde_json", - "slog", - "slog_derive", - "smallvec 0.6.13", - "sp-arithmetic 2.0.0-alpha.5", - "sp-blockchain 2.0.0-alpha.5", - "sp-consensus 0.8.0-alpha.5", - "sp-consensus-babe 0.8.0-alpha.5", - "sp-core 2.0.0-alpha.5", - "sp-runtime 2.0.0-alpha.5", - "substrate-prometheus-endpoint", - "thiserror", - "unsigned-varint 0.3.2", - "void", - "wasm-timer", - "zeroize 1.1.0", -] - [[package]] name = "sc-network-gossip" version = "0.8.0-alpha.2" @@ -5101,27 +4833,11 @@ dependencies = [ "log 0.4.8", "lru", "parking_lot 0.10.0", - "sc-network 0.8.0-alpha.2", + "sc-network", "sp-runtime 2.0.0-alpha.2", "wasm-timer", ] -[[package]] -name = "sc-network-gossip" -version = "0.8.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1eb8906bfd2d54f84fad8aba2f4303cff30f5596e7d4b90f97008d5477ea9ce4" -dependencies = [ - "futures 0.3.4", - "futures-timer 3.0.2", - "libp2p", - "log 0.4.8", - "lru", - "sc-network 0.8.0-alpha.5", - "sp-runtime 2.0.0-alpha.5", - "wasm-timer", -] - [[package]] name = "sc-offchain" version = "2.0.0-alpha.2" @@ -5138,9 +4854,9 @@ dependencies = [ "parity-scale-codec", "parking_lot 0.10.0", "rand 0.7.3", - "sc-client-api 2.0.0-alpha.2", - "sc-keystore 2.0.0-alpha.2", - "sc-network 0.8.0-alpha.2", + "sc-client-api", + "sc-keystore", + "sc-network", "sp-api 2.0.0-alpha.2", "sp-core 2.0.0-alpha.2", "sp-offchain", @@ -5160,19 +4876,6 @@ dependencies = [ "wasm-timer", ] -[[package]] -name = "sc-peerset" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a61bec2c8ace0c65c0cbd306b57a81eff12c92686b2988066d0ac49570944095" -dependencies = [ - "futures 0.3.4", - "libp2p", - "log 0.4.8", - "serde_json", - "wasm-timer", -] - [[package]] name = "sc-rpc" version = "2.0.0-alpha.2" @@ -5185,10 +4888,10 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.0", - "sc-client 0.8.0-alpha.2", - "sc-client-api 2.0.0-alpha.2", - "sc-executor 0.8.0-alpha.2", - "sc-keystore 2.0.0-alpha.2", + "sc-client", + "sc-client-api", + "sc-executor", + "sc-keystore", "sc-rpc-api", "serde_json", "sp-api 2.0.0-alpha.2", @@ -5199,7 +4902,7 @@ dependencies = [ "sp-runtime 2.0.0-alpha.2", "sp-session", "sp-state-machine 0.8.0-alpha.2", - "sp-transaction-pool 2.0.0-alpha.2", + "sp-transaction-pool", "sp-version 2.0.0-alpha.2", ] @@ -5222,7 +4925,7 @@ dependencies = [ "sp-core 2.0.0-alpha.2", "sp-rpc", "sp-runtime 2.0.0-alpha.2", - "sp-transaction-pool 2.0.0-alpha.2", + "sp-transaction-pool", "sp-version 2.0.0-alpha.2", ] @@ -5260,16 +4963,16 @@ dependencies = [ "parking_lot 0.10.0", "prometheus-exporter", "sc-chain-spec", - "sc-client 0.8.0-alpha.2", - "sc-client-api 2.0.0-alpha.2", + "sc-client", + "sc-client-api", "sc-client-db", - "sc-executor 0.8.0-alpha.2", - "sc-keystore 2.0.0-alpha.2", - "sc-network 0.8.0-alpha.2", + "sc-executor", + "sc-keystore", + "sc-network", "sc-offchain", "sc-rpc", "sc-rpc-server", - "sc-telemetry 2.0.0-alpha.2", + "sc-telemetry", "sc-tracing", "sc-transaction-pool", "serde", @@ -5283,7 +4986,7 @@ dependencies = [ "sp-io 2.0.0-alpha.2", "sp-runtime 2.0.0-alpha.2", "sp-session", - "sp-transaction-pool 2.0.0-alpha.2", + "sp-transaction-pool", "sysinfo", "target_info", "tracing", @@ -5323,29 +5026,6 @@ dependencies = [ "wasm-timer", ] -[[package]] -name = "sc-telemetry" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f358814b6fe2f2c726f708870d98d07f10d6ebb7d06dcf7f8f2781a868d24eb2" -dependencies = [ - "bytes 0.5.4", - "futures 0.3.4", - "futures-timer 3.0.2", - "libp2p", - "log 0.4.8", - "parking_lot 0.10.0", - "pin-project", - "rand 0.7.3", - "serde", - "slog", - "slog-json", - "slog-scope", - "take_mut", - "void", - "wasm-timer", -] - [[package]] name = "sc-tracing" version = "2.0.0-alpha.2" @@ -5354,7 +5034,7 @@ dependencies = [ "erased-serde", "log 0.4.8", "parking_lot 0.10.0", - "sc-telemetry 2.0.0-alpha.2", + "sc-telemetry", "serde", "serde_json", "slog", @@ -5376,7 +5056,7 @@ dependencies = [ "sp-blockchain 2.0.0-alpha.2", "sp-core 2.0.0-alpha.2", "sp-runtime 2.0.0-alpha.2", - "sp-transaction-pool 2.0.0-alpha.2", + "sp-transaction-pool", "wasm-timer", ] @@ -5393,13 +5073,13 @@ dependencies = [ "parity-scale-codec", "parity-util-mem 0.5.2", "parking_lot 0.10.0", - "sc-client-api 2.0.0-alpha.2", + "sc-client-api", "sc-transaction-graph", "sp-api 2.0.0-alpha.2", "sp-blockchain 2.0.0-alpha.2", "sp-core 2.0.0-alpha.2", "sp-runtime 2.0.0-alpha.2", - "sp-transaction-pool 2.0.0-alpha.2", + "sp-transaction-pool", "wasm-timer", ] @@ -5808,19 +5488,6 @@ dependencies = [ "sp-wasm-interface 2.0.0-alpha.2", ] -[[package]] -name = "sp-allocator" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bb6b190d2b48dcfc0641760ed0164df8ac8807a50afcb7c1da7641c8c13591b" -dependencies = [ - "derive_more", - "log 0.4.8", - "sp-core 2.0.0-alpha.5", - "sp-std 2.0.0-alpha.5", - "sp-wasm-interface 2.0.0-alpha.5", -] - [[package]] name = "sp-api" version = "2.0.0-alpha.2" @@ -6066,7 +5733,7 @@ dependencies = [ "sp-inherents 2.0.0-alpha.2", "sp-runtime 2.0.0-alpha.2", "sp-std 2.0.0-alpha.2", - "sp-timestamp 2.0.0-alpha.2", + "sp-timestamp", ] [[package]] @@ -6082,37 +5749,7 @@ dependencies = [ "sp-inherents 2.0.0-alpha.2", "sp-runtime 2.0.0-alpha.2", "sp-std 2.0.0-alpha.2", - "sp-timestamp 2.0.0-alpha.2", -] - -[[package]] -name = "sp-consensus-babe" -version = "0.8.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3341004b1ed8ae1487dc28b5ba9e3ece95c23c318d427fa598bb0084630ea822" -dependencies = [ - "parity-scale-codec", - "sp-api 2.0.0-alpha.5", - "sp-application-crypto 2.0.0-alpha.5", - "sp-consensus 0.8.0-alpha.5", - "sp-consensus-vrf", - "sp-inherents 2.0.0-alpha.5", - "sp-runtime 2.0.0-alpha.5", - "sp-std 2.0.0-alpha.5", - "sp-timestamp 2.0.0-alpha.5", -] - -[[package]] -name = "sp-consensus-vrf" -version = "0.8.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7749e59ef895203554a9fca6a5d24e49f079f44f2dddc9306fe50faae783f5a0" -dependencies = [ - "parity-scale-codec", - "schnorrkel 0.9.1", - "sp-core 2.0.0-alpha.5", - "sp-runtime 2.0.0-alpha.5", - "sp-std 2.0.0-alpha.5", + "sp-timestamp", ] [[package]] @@ -6276,17 +5913,6 @@ dependencies = [ "sp-std 2.0.0-alpha.2", ] -[[package]] -name = "sp-finality-tracker" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0be49e587e5667f747ca743ef468949535fae5640d26c236ac35e44abe595b15" -dependencies = [ - "parity-scale-codec", - "sp-inherents 2.0.0-alpha.5", - "sp-std 2.0.0-alpha.5", -] - [[package]] name = "sp-inherents" version = "2.0.0-alpha.2" @@ -6360,18 +5986,6 @@ dependencies = [ "strum", ] -[[package]] -name = "sp-keyring" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0efcad50ccf03fa69c14f1b4a48b14cbb8f17afbbb53b81c34f4e0b4a3101d82" -dependencies = [ - "lazy_static", - "sp-core 2.0.0-alpha.5", - "sp-runtime 2.0.0-alpha.5", - "strum", -] - [[package]] name = "sp-offchain" version = "2.0.0-alpha.2" @@ -6514,16 +6128,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "sp-serializer" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91abe1611fb9ad68cc2be724580710c5824a256d6aa92d88b181cb0d4819f8d1" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "sp-session" version = "2.0.0-alpha.2" @@ -6632,21 +6236,6 @@ dependencies = [ "wasm-timer", ] -[[package]] -name = "sp-timestamp" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990bc28e4e7fd31a13f5e61fd30ef0aa3ba5747b64ab3560df5285abbd879f6c" -dependencies = [ - "impl-trait-for-tuples", - "parity-scale-codec", - "sp-api 2.0.0-alpha.5", - "sp-inherents 2.0.0-alpha.5", - "sp-runtime 2.0.0-alpha.5", - "sp-std 2.0.0-alpha.5", - "wasm-timer", -] - [[package]] name = "sp-transaction-pool" version = "2.0.0-alpha.2" @@ -6661,21 +6250,6 @@ dependencies = [ "sp-runtime 2.0.0-alpha.2", ] -[[package]] -name = "sp-transaction-pool" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a7e374dd4c0831fa118728656c5d295a3ebd3da9c7ead45451ad4a5801a77e4" -dependencies = [ - "derive_more", - "futures 0.3.4", - "log 0.4.8", - "parity-scale-codec", - "serde", - "sp-api 2.0.0-alpha.5", - "sp-runtime 2.0.0-alpha.5", -] - [[package]] name = "sp-trie" version = "2.0.0-alpha.2" @@ -6943,21 +6517,6 @@ name = "substrate-build-script-utils" version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" -[[package]] -name = "substrate-prometheus-endpoint" -version = "0.8.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79926ded24e276de08eba7880c173e90eae37dc748f47eabefca9bda2cb296" -dependencies = [ - "async-std", - "derive_more", - "futures-util", - "hyper 0.13.4", - "log 0.4.8", - "prometheus", - "tokio 0.2.16", -] - [[package]] name = "substrate-wasm-builder-runner" version = "1.0.5" diff --git a/modules/ethereum-contract/builtin/Cargo.toml b/modules/ethereum-contract/builtin/Cargo.toml index bd359661c2..be2b1c7f68 100644 --- a/modules/ethereum-contract/builtin/Cargo.toml +++ b/modules/ethereum-contract/builtin/Cargo.toml @@ -10,9 +10,10 @@ edition = "2018" # General dependencies codec = { package = "parity-scale-codec", version = "1.0.0" } -finality-grandpa = "0.11.2" -sc-finality-grandpa = "0.8.0-alpha.5" +finality-grandpa = { version = "0.11.2", features = ["derive-codec"] } +sp-blockchain = "2.0.0-alpha.5" sp-finality-grandpa = "2.0.0-alpha.5" +sp-runtime = "2.0.0-alpha.5" # Runtime/chain specific dependencies diff --git a/modules/ethereum-contract/builtin/src/lib.rs b/modules/ethereum-contract/builtin/src/lib.rs index 618b0e7581..6d3f33dc86 100644 --- a/modules/ethereum-contract/builtin/src/lib.rs +++ b/modules/ethereum-contract/builtin/src/lib.rs @@ -14,9 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use bridge_node_runtime::{BlockNumber, Hash, Header as RuntimeHeader}; -use finality_grandpa::VoterSet; -use sc_finality_grandpa::GrandpaJustification; +use codec::{Encode, Decode}; +use bridge_node_runtime::{BlockNumber, Header as RuntimeHeader}; use sp_blockchain::Error as ClientError; use sp_finality_grandpa::AuthorityList; @@ -41,6 +40,7 @@ pub struct Header { } /// All types of finality proofs. +#[derive(Decode, Encode)] pub enum FinalityProof { /// GRANDPA justification. Justification(Vec), @@ -48,7 +48,7 @@ pub enum FinalityProof { /// Parse Substrate header. pub fn parse_substrate_header(raw_header: &[u8]) -> Result { - RuntimeHeader::decode(&mut &ras_header[..]) + RuntimeHeader::decode(&mut &raw_header[..]) .map(|header| Header { number: header.number, }) @@ -68,7 +68,7 @@ pub fn verify_substrate_finality_proof( let finality_proof = FinalityProof::decode(&mut &raw_finality_proof[..]) .map_err(Error::FinalityProofDecode)?; - let best_header = RuntimeHeader::decode(&mut &raw_best_header[..]) + let _best_header = RuntimeHeader::decode(&mut &raw_best_header[..]) .map_err(Error::HeaderDecode)?; let headers = raw_headers .iter() @@ -78,20 +78,175 @@ pub fn verify_substrate_finality_proof( .collect::, _>>()?; let finality_target = match headers.last() { - Some(header) => (header.hash(), header.number()), + Some(header) => (header.hash(), header.number), None => return Err(Error::NoNewHeaders), }; match finality_proof { FinalityProof::Justification(raw_justification) => { - GrandpaJustification::decode_and_verify_finalizes( + substrate::GrandpaJustification::decode_and_verify_finalizes( &raw_justification, finality_target, best_set_id, - &VoterSet::new(best_voters) + &best_voters.into_iter().collect(), ).map_err(Error::JustificationVerify)?; }, } Ok((0, headers.len())) } + +// =================================================================================================== +// =================================================================================================== +// =================================================================================================== + + +mod substrate { + use std::collections::HashMap; + use codec::{Encode, Decode}; + use bridge_node_runtime::{BlockNumber, Hash, Header as RuntimeHeader}; + use finality_grandpa::{voter_set::VoterSet}; + use sp_blockchain::Error as ClientError; + use sp_finality_grandpa::{AuthorityId, AuthoritySignature}; + + /// A commit message for this chain's block type. + pub type Commit = finality_grandpa::Commit; + + /// GRANDPA justification. + #[derive(Encode, Decode)] + pub struct GrandpaJustification { + pub round: u64, + pub commit: Commit, + pub votes_ancestries: Vec, + } + + impl GrandpaJustification { + /// Decode a GRANDPA justification and validate the commit and the votes' + /// ancestry proofs finalize the given block. + pub(crate) fn decode_and_verify_finalizes( + encoded: &[u8], + finalized_target: (Hash, BlockNumber), + set_id: u64, + voters: &VoterSet, + ) -> Result { + + let justification = GrandpaJustification::decode(&mut &*encoded) + .map_err(|_| ClientError::JustificationDecode)?; + + if (justification.commit.target_hash, justification.commit.target_number) != finalized_target { + let msg = "invalid commit target in grandpa justification".to_string(); + Err(ClientError::BadJustification(msg)) + } else { + justification.verify(set_id, voters).map(|_| justification) + } + } + + /// Validate the commit and the votes' ancestry proofs. + pub(crate) fn verify(&self, _set_id: u64, voters: &VoterSet) -> Result<(), ClientError> { +// use finality_grandpa::Chain; + + let ancestry_chain = AncestryChain::new(&self.votes_ancestries); + + match finality_grandpa::validate_commit( + &self.commit, + voters, + &ancestry_chain, + ) { + Ok(ref result) if result.ghost().is_some() => {}, + _ => { + let msg = "invalid commit in grandpa justification".to_string(); + return Err(ClientError::BadJustification(msg)); + } + } +/* TODO + let mut buf = Vec::new(); + let mut visited_hashes = HashSet::new(); + for signed in self.commit.precommits.iter() { + if let Err(_) = communication::check_message_sig_with_buffer::( + &finality_grandpa::Message::Precommit(signed.precommit.clone()), + &signed.id, + &signed.signature, + self.round, + set_id, + &mut buf, + ) { + return Err(ClientError::BadJustification( + "invalid signature for precommit in grandpa justification".to_string()).into()); + } + + if self.commit.target_hash == signed.precommit.target_hash { + continue; + } + + match ancestry_chain.ancestry(self.commit.target_hash, signed.precommit.target_hash) { + Ok(route) => { + // ancestry starts from parent hash but the precommit target hash has been visited + visited_hashes.insert(signed.precommit.target_hash); + for hash in route { + visited_hashes.insert(hash); + } + }, + _ => { + return Err(ClientError::BadJustification( + "invalid precommit ancestry proof in grandpa justification".to_string()).into()); + }, + } + } + + let ancestry_hashes = self.votes_ancestries + .iter() + .map(|h: &Block::Header| h.hash()) + .collect(); + + if visited_hashes != ancestry_hashes { + return Err(ClientError::BadJustification( + "invalid precommit ancestries in grandpa justification with unused headers".to_string()).into()); + } +*/ + Ok(()) + } + } + + /// A utility trait implementing `finality_grandpa::Chain` using a given set of headers. + /// This is useful when validating commits, using the given set of headers to + /// verify a valid ancestry route to the target commit block. + struct AncestryChain { + ancestry: HashMap, + } + + impl AncestryChain { + fn new(ancestry: &[RuntimeHeader]) -> AncestryChain { + let ancestry: HashMap<_, _> = ancestry + .iter() + .cloned() + .map(|h: RuntimeHeader| (h.hash(), h)) + .collect(); + + AncestryChain { ancestry } + } + } + + impl finality_grandpa::Chain for AncestryChain { + fn ancestry(&self, base: Hash, block: Hash) -> Result, finality_grandpa::Error> { + let mut route = Vec::new(); + let mut current_hash = block; + loop { + if current_hash == base { break; } + match self.ancestry.get(¤t_hash) { + Some(current_header) => { + current_hash = current_header.parent_hash; + route.push(current_hash); + }, + _ => return Err(finality_grandpa::Error::NotDescendent), + } + } + route.pop(); // remove the base + + Ok(route) + } + + fn best_chain_containing(&self, _block: Hash) -> Option<(Hash, BlockNumber)> { + None + } + } +} From 3a13d1f92b307f90a51e5c4b6046c392a742bb69 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 6 Apr 2020 13:16:11 +0300 Subject: [PATCH 06/92] ehtereum_headers -> headers --- relays/ethereum/src/ethereum_sync.rs | 4 ++-- relays/ethereum/src/{ethereum_headers.rs => headers.rs} | 0 relays/ethereum/src/main.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename relays/ethereum/src/{ethereum_headers.rs => headers.rs} (100%) diff --git a/relays/ethereum/src/ethereum_sync.rs b/relays/ethereum/src/ethereum_sync.rs index df5698f7e0..bc69eb9a7c 100644 --- a/relays/ethereum/src/ethereum_sync.rs +++ b/relays/ethereum/src/ethereum_sync.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::ethereum_headers::QueuedHeaders; +use crate::headers::QueuedHeaders; use crate::ethereum_sync_loop::EthereumSyncParams; use crate::ethereum_types::{HeaderId, HeaderStatus, QueuedHeader}; use crate::substrate_types::{into_substrate_ethereum_header, into_substrate_ethereum_receipts}; @@ -167,7 +167,7 @@ impl HeadersSync { #[cfg(test)] mod tests { use super::*; - use crate::ethereum_headers::tests::{header, id}; + use crate::headers::tests::{header, id}; use crate::ethereum_types::{HeaderStatus, H256}; fn side_hash(number: u64) -> H256 { diff --git a/relays/ethereum/src/ethereum_headers.rs b/relays/ethereum/src/headers.rs similarity index 100% rename from relays/ethereum/src/ethereum_headers.rs rename to relays/ethereum/src/headers.rs diff --git a/relays/ethereum/src/main.rs b/relays/ethereum/src/main.rs index 9feb34462b..9483524293 100644 --- a/relays/ethereum/src/main.rs +++ b/relays/ethereum/src/main.rs @@ -17,10 +17,10 @@ #![recursion_limit = "1024"] mod ethereum_client; -mod ethereum_headers; mod ethereum_sync; mod ethereum_sync_loop; mod ethereum_types; +mod headers; mod substrate_client; mod substrate_types; From 39555d0028c1ec60774ec8f4d0b696648a164875 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 6 Apr 2020 13:49:57 +0300 Subject: [PATCH 07/92] extracted some common stuff --- Cargo.lock | 1 + relays/ethereum/Cargo.toml | 1 + relays/ethereum/src/cli.yml | 88 ++++++++++++------- relays/ethereum/src/ethereum_sync_loop.rs | 81 ++---------------- relays/ethereum/src/main.rs | 64 +++++++++++--- relays/ethereum/src/substrate_client.rs | 10 +-- relays/ethereum/src/substrate_sync_loop.rs | 98 ++++++++++++++++++++++ relays/ethereum/src/utils.rs | 92 ++++++++++++++++++++ 8 files changed, 314 insertions(+), 121 deletions(-) create mode 100644 relays/ethereum/src/substrate_sync_loop.rs create mode 100644 relays/ethereum/src/utils.rs diff --git a/Cargo.lock b/Cargo.lock index 18db8f3571..ae9cfd7034 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1058,6 +1058,7 @@ dependencies = [ "log 0.4.8", "node-primitives", "pallet-transaction-payment", + "parity-crypto 0.6.0", "parity-scale-codec", "parking_lot 0.10.0", "rustc-hex", diff --git a/relays/ethereum/Cargo.toml b/relays/ethereum/Cargo.toml index 8fb7226699..9528fd6cfb 100644 --- a/relays/ethereum/Cargo.toml +++ b/relays/ethereum/Cargo.toml @@ -15,6 +15,7 @@ futures = "0.3.1" jsonrpsee = { git = "https://github.com/paritytech/jsonrpsee.git", default-features = false, features = ["http"] } linked-hash-map = "0.5.2" log = "0.4.8" +parity-crypto = { version = "0.6", features = ["publickey"] } parking_lot = "0.10.0" rustc-hex = "2.0.1" serde = { version = "1.0.105", features = ["derive"] } diff --git a/relays/ethereum/src/cli.yml b/relays/ethereum/src/cli.yml index 7a3dcbe2b7..f31f6bad10 100644 --- a/relays/ethereum/src/cli.yml +++ b/relays/ethereum/src/cli.yml @@ -2,32 +2,62 @@ name: ethsub-bridge version: "0.1.0" author: Parity Technologies about: Parity Ethereum (PoA) <-> Substrate bridge -args: - - eth-host: - long: eth-host - value_name: ETH_HOST - help: Connect to Ethereum node at given host. - takes_value: true - - eth-port: - long: eth-port - value_name: ETH_PORT - help: Connect to Ethereum node at given port. - takes_value: true - - sub-host: - long: sub-host - value_name: SUB_HOST - help: Connect to Substrate node at given host. - takes_value: true - - sub-port: - long: sub-port - value_name: SUB_PORT - help: Connect to Substrate node at given port. - takes_value: true - - sub-signer: - long: sub-signer - value_name: SUB_SIGNER - help: The SURI of secret key to use when transactions are submitted to the Substrate node. - - sub-signer-password: - long: sub-signer-password - value_name: SUB_SIGNER_PASSWORD - help: The password for the SURI of secret key to use when transactions are submitted to the Substrate node. \ No newline at end of file +subcommands: + - eth-to-sub: + about: Synchronize headers from Ethereum node to Substrate node. + args: + - eth-host: + long: eth-host + value_name: ETH_HOST + help: Connect to Ethereum node at given host. + takes_value: true + - eth-port: + long: eth-port + value_name: ETH_PORT + help: Connect to Ethereum node at given port. + takes_value: true + - sub-host: + long: sub-host + value_name: SUB_HOST + help: Connect to Substrate node at given host. + takes_value: true + - sub-port: + long: sub-port + value_name: SUB_PORT + help: Connect to Substrate node at given port. + takes_value: true + - sub-signer: + long: sub-signer + value_name: SUB_SIGNER + help: The SURI of secret key to use when transactions are submitted to the Substrate node. + - sub-signer-password: + long: sub-signer-password + value_name: SUB_SIGNER_PASSWORD + help: The password for the SURI of secret key to use when transactions are submitted to the Substrate node. + - sub-to-eth: + about: Synchronize headers from Substrate node to Ethereum node. + args: + - eth-host: + long: eth-host + value_name: ETH_HOST + help: Connect to Ethereum node at given host. + takes_value: true + - eth-port: + long: eth-port + value_name: ETH_PORT + help: Connect to Ethereum node at given port. + takes_value: true + - eth-signer: + long: eth-signer + value_name: ETH_SIGNER + help: Hex-encoded secret to use when transactions are submitted to the Ethereum node. + - sub-host: + long: sub-host + value_name: SUB_HOST + help: Connect to Substrate node at given host. + takes_value: true + - sub-port: + long: sub-port + value_name: SUB_PORT + help: Connect to Substrate node at given port. + takes_value: true \ No newline at end of file diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index 5c91b27510..a75134cba0 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -41,12 +41,6 @@ const STALL_SYNC_TIMEOUT_MS: u64 = 30_000; /// reconnection again. const CONNECTION_ERROR_DELAY_MS: u64 = 10_000; -/// Error type that can signal connection errors. -pub trait MaybeConnectionError { - /// Returns true if error (maybe) represents connection error. - fn is_connection_error(&self) -> bool; -} - /// Ethereum synchronization parameters. pub struct EthereumSyncParams { /// Ethereum RPC host. @@ -133,7 +127,7 @@ pub fn run(params: EthereumSyncParams) { let mut sub_maybe_client = None; let mut sub_best_block_required = false; let sub_best_block_future = - substrate_client::best_ethereum_block(substrate_client::client(&sub_uri, sub_signer)).fuse(); + substrate_client::best_ethereum_block(substrate_client::client(&sub_uri)).fuse(); let sub_receipts_check_future = futures::future::Fuse::terminated(); let sub_existence_status_future = futures::future::Fuse::terminated(); let sub_submit_header_future = futures::future::Fuse::terminated(); @@ -301,7 +295,7 @@ pub fn run(params: EthereumSyncParams) { } // print progress - progress_context = print_progress(progress_context, ð_sync); + progress_context = print_sync_progress(progress_context, ð_sync); // if client is available: wait, or call Substrate RPC methods if let Some(sub_client) = sub_maybe_client.take() { @@ -350,7 +344,9 @@ pub fn run(params: EthereumSyncParams) { ); let headers = headers.into_iter().cloned().collect(); - sub_submit_header_future.set(substrate_client::submit_ethereum_headers(sub_client, headers).fuse()); + sub_submit_header_future.set( + substrate_client::submit_ethereum_headers(sub_client, sub_signer.clone(), headers).fuse() + ); // remember that we have submitted some headers if stall_countdown.is_none() { @@ -409,70 +405,3 @@ pub fn run(params: EthereumSyncParams) { } }); } - -fn print_progress( - progress_context: (std::time::Instant, Option, Option), - eth_sync: &crate::ethereum_sync::HeadersSync, -) -> (std::time::Instant, Option, Option) { - let (prev_time, prev_best_header, prev_target_header) = progress_context; - let now_time = std::time::Instant::now(); - let (now_best_header, now_target_header) = eth_sync.status(); - - let need_update = now_time - prev_time > std::time::Duration::from_secs(10) - || match (prev_best_header, now_best_header) { - (Some(prev_best_header), Some(now_best_header)) => now_best_header.0.saturating_sub(prev_best_header) > 10, - _ => false, - }; - if !need_update { - return (prev_time, prev_best_header, prev_target_header); - } - - log::info!( - target: "bridge", - "Synced {:?} of {:?} headers", - now_best_header.map(|id| id.0), - now_target_header, - ); - (now_time, now_best_header.clone().map(|id| id.0), *now_target_header) -} - -async fn delay(timeout_ms: u64, retval: T) -> T { - async_std::task::sleep(std::time::Duration::from_millis(timeout_ms)).await; - retval -} - -fn interval(timeout_ms: u64) -> impl futures::Stream { - futures::stream::unfold((), move |_| async move { - delay(timeout_ms, ()).await; - Some(((), ())) - }) -} - -fn process_future_result( - maybe_client: &mut Option, - client: TClient, - result: Result, - on_success: impl FnOnce(TResult), - go_offline_future: &mut std::pin::Pin<&mut futures::future::Fuse>, - go_offline: impl FnOnce(TClient) -> TGoOfflineFuture, - error_pattern: &'static str, -) where - TError: std::fmt::Debug + MaybeConnectionError, - TGoOfflineFuture: FutureExt, -{ - match result { - Ok(result) => { - *maybe_client = Some(client); - on_success(result); - } - Err(error) => { - if error.is_connection_error() { - go_offline_future.set(go_offline(client).fuse()); - } else { - *maybe_client = Some(client); - } - - log::error!(target: "bridge", "{}: {:?}", error_pattern, error); - } - } -} diff --git a/relays/ethereum/src/main.rs b/relays/ethereum/src/main.rs index 9483524293..fcec82a383 100644 --- a/relays/ethereum/src/main.rs +++ b/relays/ethereum/src/main.rs @@ -22,21 +22,45 @@ mod ethereum_sync_loop; mod ethereum_types; mod headers; mod substrate_client; +mod substrate_sync; +mod substrate_sync_loop; mod substrate_types; +mod utils; +use parity_crypto::publickey::KeyPair; use sp_core::crypto::Pair; use std::io::Write; fn main() { initialize(); - ethereum_sync_loop::run(match ethereum_sync_params() { - Ok(ethereum_sync_params) => ethereum_sync_params, - Err(err) => { - log::error!(target: "bridge", "Error parsing parameters: {}", err); + let yaml = clap::load_yaml!("cli.yml"); + let matches = clap::App::from_yaml(yaml).get_matches(); + match matches.subcommand() { + ("eth-to-sub", Some(eth_to_sub_matches)) => { + ethereum_sync_loop::run(match ethereum_sync_params(ð_to_sub_matches) { + Ok(ethereum_sync_params) => ethereum_sync_params, + Err(err) => { + log::error!(target: "bridge", "Error parsing parameters: {}", err); + return; + } + }); + }, + ("sub-to-eth", Some(sub_to_eth_matches)) => { + substrate_sync_loop::run(match substrate_sync_params(&sub_to_eth_matches) { + Ok(substrate_sync_params) => substrate_sync_params, + Err(err) => { + log::error!(target: "bridge", "Error parsing parameters: {}", err); + return; + } + }); + }, + ("", _) => { + log::error!(target: "bridge", "No subcommand specified"); return; - } - }); + }, + _ => unreachable!(), + } } fn initialize() { @@ -76,10 +100,7 @@ fn initialize() { builder.init(); } -fn ethereum_sync_params() -> Result { - let yaml = clap::load_yaml!("cli.yml"); - let matches = clap::App::from_yaml(yaml).get_matches(); - +fn ethereum_sync_params(matches: &clap::ArgMatches) -> Result { let mut eth_sync_params = ethereum_sync_loop::EthereumSyncParams::default(); if let Some(eth_host) = matches.value_of("eth-host") { eth_sync_params.eth_host = eth_host.into(); @@ -101,3 +122,26 @@ fn ethereum_sync_params() -> Result Result { + let mut sub_sync_params = substrate_sync_loop::SubstrateSyncParams::default(); + if let Some(eth_host) = matches.value_of("eth-host") { + sub_sync_params.eth_host = eth_host.into(); + } + if let Some(eth_port) = matches.value_of("eth-port") { + sub_sync_params.eth_port = eth_port.parse().map_err(|e| format!("{}", e))?; + } + if let Some(eth_signer) = matches.value_of("eth-signer") { + sub_sync_params.eth_signer = KeyPair::from_secret( + eth_signer.parse().map_err(|e| format!("{}", e))? + ).map_err(|e| format!("{}", e))?; + } + if let Some(sub_host) = matches.value_of("sub-host") { + sub_sync_params.sub_host = sub_host.into(); + } + if let Some(sub_port) = matches.value_of("sub-port") { + sub_sync_params.sub_port = sub_port.parse().map_err(|e| format!("{}", e))?; + } + + Ok(sub_sync_params) +} diff --git a/relays/ethereum/src/substrate_client.rs b/relays/ethereum/src/substrate_client.rs index 799bf6151e..f52690f3c5 100644 --- a/relays/ethereum/src/substrate_client.rs +++ b/relays/ethereum/src/substrate_client.rs @@ -29,8 +29,6 @@ use sp_runtime::traits::IdentifyAccount; pub struct Client { /// Substrate RPC client. rpc_client: RawClient, - /// Transactions signer. - signer: sp_core::sr25519::Pair, /// Genesis block hash. genesis_hash: Option, } @@ -58,11 +56,10 @@ impl MaybeConnectionError for Error { } /// Returns client that is able to call RPCs on Substrate node. -pub fn client(uri: &str, signer: sp_core::sr25519::Pair) -> Client { +pub fn client(uri: &str) -> Client { let transport = HttpTransportClient::new(uri); Client { rpc_client: RawClient::new(transport), - signer, genesis_hash: None, } } @@ -131,6 +128,7 @@ pub async fn ethereum_header_known( /// Submits Ethereum header to Substrate runtime. pub async fn submit_ethereum_headers( client: Client, + signer: sp_core::sr25519::Pair, headers: Vec, ) -> (Client, Result<(TransactionHash, Vec), Error>) { let ids = headers.iter().map(|header| header.id()).collect(); @@ -146,13 +144,13 @@ pub async fn submit_ethereum_headers( (client, genesis_hash) } }; - let account_id = client.signer.public().as_array_ref().clone().into(); + let account_id = signer.public().as_array_ref().clone().into(); let (client, nonce) = next_account_index(client, account_id).await; let nonce = match nonce { Ok(nonce) => nonce, Err(err) => return (client, Err(err)), }; - let transaction = create_submit_transaction(headers, &client.signer, nonce, genesis_hash); + let transaction = create_submit_transaction(headers, &signer, nonce, genesis_hash); let encoded_transaction = transaction.encode(); let (client, transaction_hash) = call_rpc( client, diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs new file mode 100644 index 0000000000..012e3262ae --- /dev/null +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -0,0 +1,98 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +use crate::ethereum_client; +use crate::substrate_client; +use futures::{future::FutureExt, stream::StreamExt}; +use parity_crypto::publickey::KeyPair; + +/// Substrate synchronization parameters. +pub struct SubstrateSyncParams { + /// Ethereum RPC host. + pub eth_host: String, + /// Ethereum RPC port. + pub eth_port: u16, + /// Ethereum transactions signer. + pub eth_signer: KeyPair, + /// Substrate RPC host. + pub sub_host: String, + /// Substrate RPC port. + pub sub_port: u16, + /// Maximal number of ethereum headers to pre-download. + pub max_future_headers_to_download: usize, + /// Maximal number of active (we believe) submit header transactions. + pub max_headers_in_submitted_status: usize, + /// Maximal number of headers in single submit request. + pub max_headers_in_single_submit: usize, + /// Maximal total headers size in single submit request. + pub max_headers_size_in_single_submit: usize, + /// We only may store and accept (from Ethereum node) headers that have + /// number >= than best_substrate_header.number - prune_depth. + pub prune_depth: u64, +} + +impl Default for SubstrateSyncParams { + fn default() -> Self { + SubstrateSyncParams { + eth_host: "localhost".into(), + eth_port: 8545, + // that the account that has a lot of ether when we run instant seal engine + // address: 0x00a329c0648769a73afac7f9381e08fb43dbea72 + // secret: 0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7 + eth_signer: KeyPair::from_secret_slice( + &[0x4d, 0x5d, 0xb4, 0x10, 0x7d, 0x23, 0x7d, 0xf6, 0xa3, 0xd5, 0x8e, 0xe5, 0xf7, 0x0a, + 0xe6, 0x3d, 0x73, 0xd7, 0x65, 0x8d, 0x40, 0x26, 0xf2, 0xee, 0xfd, 0x2f, 0x20, 0x4c, + 0x81, 0x68, 0x2c, 0xb7] + ).expect("secret is hardcoded, thus valid; qed"), + sub_host: "localhost".into(), + sub_port: 9933, + max_future_headers_to_download: 128, + max_headers_in_submitted_status: 128, + max_headers_in_single_submit: 32, + max_headers_size_in_single_submit: 131_072, + prune_depth: 4096, + } + } +} + +/// Run Substrate headers synchronization. +pub fn run(params: SubstrateSyncParams) { + let mut local_pool = futures::executor::LocalPool::new(); +// let mut progress_context = (std::time::Instant::now(), None, None); + + local_pool.run_until(async move { + let eth_uri = format!("http://{}:{}", params.eth_host, params.eth_port); + let sub_uri = format!("http://{}:{}", params.sub_host, params.sub_port); + + let mut eth_maybe_client = None; + let mut eth_best_block_number_required = false; + let eth_best_block_number_future = ethereum_client::best_block_number(ethereum_client::client(ð_uri)).fuse(); + + let mut sub_maybe_client = None; + let mut sub_best_block_required = false; + let sub_best_block_future = + substrate_client::best_ethereum_block(substrate_client::client(&sub_uri)).fuse(); + + loop { + futures::select! { + (eth_client, eth_best_block_number) = eth_best_block_number_future => { + eth_best_block_number_required = false; + } + } + } + }); +} + diff --git a/relays/ethereum/src/utils.rs b/relays/ethereum/src/utils.rs new file mode 100644 index 0000000000..9c82a93291 --- /dev/null +++ b/relays/ethereum/src/utils.rs @@ -0,0 +1,92 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +/// Error type that can signal connection errors. +pub trait MaybeConnectionError { + /// Returns true if error (maybe) represents connection error. + fn is_connection_error(&self) -> bool; +} + +/// Future that resolves into given value after given timeout. +pub async fn delay(timeout_ms: u64, retval: T) -> T { + async_std::task::sleep(std::time::Duration::from_millis(timeout_ms)).await; + retval +} + +/// Stream that emits item every `timeout_ms` milliseconds. +pub fn interval(timeout_ms: u64) -> impl futures::Stream { + futures::stream::unfold((), move |_| async move { + delay(timeout_ms, ()).await; + Some(((), ())) + }) +} + +/// Process result of the future that may have been caused by connection failure. +pub fn process_future_result( + maybe_client: &mut Option, + client: TClient, + result: Result, + on_success: impl FnOnce(TResult), + go_offline_future: &mut std::pin::Pin<&mut futures::future::Fuse>, + go_offline: impl FnOnce(TClient) -> TGoOfflineFuture, + error_pattern: &'static str, +) where + TError: std::fmt::Debug + MaybeConnectionError, + TGoOfflineFuture: FutureExt, +{ + match result { + Ok(result) => { + *maybe_client = Some(client); + on_success(result); + } + Err(error) => { + if error.is_connection_error() { + go_offline_future.set(go_offline(client).fuse()); + } else { + *maybe_client = Some(client); + } + + log::error!(target: "bridge", "{}: {:?}", error_pattern, error); + } + } +} + +/// Print synchronization progress. +pub fn print_sync_progress( + progress_context: (std::time::Instant, Option, Option), + eth_sync: &crate::ethereum_sync::HeadersSync, +) -> (std::time::Instant, Option, Option) { + let (prev_time, prev_best_header, prev_target_header) = progress_context; + let now_time = std::time::Instant::now(); + let (now_best_header, now_target_header) = eth_sync.status(); + + let need_update = now_time - prev_time > std::time::Duration::from_secs(10) + || match (prev_best_header, now_best_header) { + (Some(prev_best_header), Some(now_best_header)) => now_best_header.0.saturating_sub(prev_best_header) > 10, + _ => false, + }; + if !need_update { + return (prev_time, prev_best_header, prev_target_header); + } + + log::info!( + target: "bridge", + "Synced {:?} of {:?} headers", + now_best_header.map(|id| id.0), + now_target_header, + ); + (now_time, now_best_header.clone().map(|id| id.0), *now_target_header) +} From 5831990b62da3d7edcc409de63a949e6290148f6 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 6 Apr 2020 13:52:01 +0300 Subject: [PATCH 08/92] ethereum_sync.rs -> sync.rs --- relays/ethereum/src/{ethereum_sync.rs => sync.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename relays/ethereum/src/{ethereum_sync.rs => sync.rs} (100%) diff --git a/relays/ethereum/src/ethereum_sync.rs b/relays/ethereum/src/sync.rs similarity index 100% rename from relays/ethereum/src/ethereum_sync.rs rename to relays/ethereum/src/sync.rs From 4dfffd8c04ec8847412350ec02dc541780d51892 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 7 Apr 2020 09:56:10 +0300 Subject: [PATCH 09/92] make sync generic --- Cargo.lock | 1 + relays/ethereum/Cargo.toml | 1 + relays/ethereum/src/ethereum_client.rs | 8 +- relays/ethereum/src/ethereum_sync_loop.rs | 46 +- relays/ethereum/src/ethereum_types.rs | 103 ++--- relays/ethereum/src/headers.rs | 492 ++++++++++++--------- relays/ethereum/src/main.rs | 4 +- relays/ethereum/src/substrate_client.rs | 7 +- relays/ethereum/src/substrate_sync_loop.rs | 16 +- relays/ethereum/src/sync.rs | 190 ++++---- relays/ethereum/src/sync_types.rs | 127 ++++++ relays/ethereum/src/utils.rs | 15 +- 12 files changed, 610 insertions(+), 400 deletions(-) create mode 100644 relays/ethereum/src/sync_types.rs diff --git a/Cargo.lock b/Cargo.lock index ae9cfd7034..c230eb2cdf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1057,6 +1057,7 @@ dependencies = [ "linked-hash-map", "log 0.4.8", "node-primitives", + "num-traits", "pallet-transaction-payment", "parity-crypto 0.6.0", "parity-scale-codec", diff --git a/relays/ethereum/Cargo.toml b/relays/ethereum/Cargo.toml index 9528fd6cfb..b21a6892f4 100644 --- a/relays/ethereum/Cargo.toml +++ b/relays/ethereum/Cargo.toml @@ -15,6 +15,7 @@ futures = "0.3.1" jsonrpsee = { git = "https://github.com/paritytech/jsonrpsee.git", default-features = false, features = ["http"] } linked-hash-map = "0.5.2" log = "0.4.8" +num-traits = "0.2" parity-crypto = { version = "0.6", features = ["publickey"] } parking_lot = "0.10.0" rustc-hex = "2.0.1" diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index 30a6bfb28a..3904515163 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::ethereum_sync_loop::MaybeConnectionError; -use crate::ethereum_types::{Header, HeaderId, Receipt, H256, U64}; +use crate::ethereum_types::{EthereumHeaderId, Header, Receipt, H256, U64}; +use crate::utils::MaybeConnectionError; use jsonrpsee::common::Params; use jsonrpsee::raw::{RawClient, RawClientError}; use jsonrpsee::transport::http::{HttpTransportClient, RequestError}; @@ -117,9 +117,9 @@ pub async fn header_by_hash(client: Client, hash: H256) -> (Client, Result, -) -> (Client, Result<(HeaderId, Vec), Error>) { +) -> (Client, Result<(EthereumHeaderId, Vec), Error>) { let mut transactions_receipts = Vec::with_capacity(transacactions.len()); for transacaction in transacactions { let (next_client, transaction_receipt) = transaction_receipt(client, transacaction).await; diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index a75134cba0..e160ac74ca 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -15,8 +15,10 @@ // along with Parity Bridges Common. If not, see . use crate::ethereum_client; -use crate::ethereum_types::HeaderStatus as EthereumHeaderStatus; use crate::substrate_client; +use crate::sync::HeadersSyncParams; +use crate::sync_types::HeaderStatus as EthereumHeaderStatus; +use crate::utils::{delay, interval, print_sync_progress, process_future_result}; use futures::{future::FutureExt, stream::StreamExt}; // TODO: when SharedClient will be available, switch to Substrate headers subscription @@ -53,17 +55,8 @@ pub struct EthereumSyncParams { pub sub_port: u16, /// Substrate transactions signer. pub sub_signer: sp_core::sr25519::Pair, - /// Maximal number of ethereum headers to pre-download. - pub max_future_headers_to_download: usize, - /// Maximal number of active (we believe) submit header transactions. - pub max_headers_in_submitted_status: usize, - /// Maximal number of headers in single submit request. - pub max_headers_in_single_submit: usize, - /// Maximal total headers size in single submit request. - pub max_headers_size_in_single_submit: usize, - /// We only may store and accept (from Ethereum node) headers that have - /// number >= than best_substrate_header.number - prune_depth. - pub prune_depth: u64, + /// Synchronization parameters. + pub sync_params: HeadersSyncParams, } impl std::fmt::Debug for EthereumSyncParams { @@ -73,14 +66,7 @@ impl std::fmt::Debug for EthereumSyncParams { .field("eth_port", &self.eth_port) .field("sub_host", &self.sub_port) .field("sub_port", &self.sub_port) - .field("max_future_headers_to_download", &self.max_future_headers_to_download) - .field("max_headers_in_submitted_status", &self.max_headers_in_submitted_status) - .field("max_headers_in_single_submit", &self.max_headers_in_single_submit) - .field( - "max_headers_size_in_single_submit", - &self.max_headers_size_in_single_submit, - ) - .field("prune_depth", &self.prune_depth) + .field("sync_params", &self.sync_params) .finish() } } @@ -93,11 +79,7 @@ impl Default for EthereumSyncParams { sub_host: "localhost".into(), sub_port: 9933, sub_signer: sp_keyring::AccountKeyring::Alice.pair(), - max_future_headers_to_download: 128, - max_headers_in_submitted_status: 128, - max_headers_in_single_submit: 32, - max_headers_size_in_single_submit: 131_072, - prune_depth: 4096, + sync_params: Default::default(), } } } @@ -112,7 +94,7 @@ pub fn run(params: EthereumSyncParams) { let sub_uri = format!("http://{}:{}", params.sub_host, params.sub_port); let sub_signer = params.sub_signer.clone(); - let mut eth_sync = crate::ethereum_sync::HeadersSync::new(params); + let mut eth_sync = crate::sync::HeadersSync::new(params.sync_params); let mut stall_countdown = None; let mut eth_maybe_client = None; @@ -158,7 +140,7 @@ pub fn run(params: EthereumSyncParams) { &mut eth_maybe_client, eth_client, eth_best_block_number, - |eth_best_block_number| eth_sync.ethereum_best_header_number_response(eth_best_block_number), + |eth_best_block_number| eth_sync.source_best_header_number_response(eth_best_block_number), &mut eth_go_offline_future, |eth_client| delay(CONNECTION_ERROR_DELAY_MS, eth_client), "Error retrieving best header number from Ethereum number", @@ -191,7 +173,7 @@ pub fn run(params: EthereumSyncParams) { &mut eth_maybe_client, eth_client, eth_receipts, - |(header, receipts)| eth_sync.headers_mut().receipts_response(&header, receipts), + |(header, receipts)| eth_sync.headers_mut().extra_response(&header, receipts), &mut eth_go_offline_future, |eth_client| delay(CONNECTION_ERROR_DELAY_MS, eth_client), "Error retrieving transactions receipts from Ethereum node", @@ -213,7 +195,7 @@ pub fn run(params: EthereumSyncParams) { sub_client, sub_best_block, |sub_best_block| { - let head_updated = eth_sync.substrate_best_header_response(sub_best_block); + let head_updated = eth_sync.target_best_header_response(sub_best_block); match head_updated { // IF head is updated AND there are still our transactions: // => restart stall countdown timer @@ -280,7 +262,7 @@ pub fn run(params: EthereumSyncParams) { sub_receipts_check_result, |(header, receipts_check_result)| eth_sync .headers_mut() - .maybe_receipts_response(&header, receipts_check_result), + .maybe_extra_response(&header, receipts_check_result), &mut sub_go_offline_future, |sub_client| delay(CONNECTION_ERROR_DELAY_MS, sub_client), "Error retrieving receipts requirement from Substrate node", @@ -308,7 +290,7 @@ pub fn run(params: EthereumSyncParams) { if sub_best_block_required { log::debug!(target: "bridge", "Asking Substrate about best block"); sub_best_block_future.set(substrate_client::best_ethereum_block(sub_client).fuse()); - } else if let Some(header) = eth_sync.headers().header(EthereumHeaderStatus::MaybeReceipts) { + } else if let Some(header) = eth_sync.headers().header(EthereumHeaderStatus::MaybeExtra) { log::debug!( target: "bridge", "Checking if header submission requires receipts: {:?}", @@ -368,7 +350,7 @@ pub fn run(params: EthereumSyncParams) { if eth_best_block_number_required { log::debug!(target: "bridge", "Asking Ethereum node about best block number"); eth_best_block_number_future.set(ethereum_client::best_block_number(eth_client).fuse()); - } else if let Some(header) = eth_sync.headers().header(EthereumHeaderStatus::Receipts) { + } else if let Some(header) = eth_sync.headers().header(EthereumHeaderStatus::Extra) { let id = header.id(); log::debug!( target: "bridge", diff --git a/relays/ethereum/src/ethereum_types.rs b/relays/ethereum/src/ethereum_types.rs index beb6c100fb..2e61df9f09 100644 --- a/relays/ethereum/src/ethereum_types.rs +++ b/relays/ethereum/src/ethereum_types.rs @@ -14,6 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +use crate::sync_types::{HeaderId, HeadersSyncPipeline, SourceHeader, QueuedHeader}; +use crate::substrate_types::{into_substrate_ethereum_header, into_substrate_ethereum_receipts}; +use codec::Encode; + pub use web3::types::{Bytes, H256, U128, U64}; /// When header is just received from the Ethereum node, we check that it has @@ -30,84 +34,51 @@ pub type Header = web3::types::Block; /// Ethereum transaction receipt type. pub type Receipt = web3::types::TransactionReceipt; -/// Ethereum header Id. -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct HeaderId(pub u64, pub H256); +/// Ethereum header ID. +pub type EthereumHeaderId = HeaderId; -impl From<&Header> for HeaderId { - fn from(header: &Header) -> HeaderId { - HeaderId( - header.number.expect(HEADER_ID_PROOF).as_u64(), - header.hash.expect(HEADER_ID_PROOF), - ) - } -} +/// Queued ethereum header ID. +pub type QueuedEthereumHeader = QueuedHeader; -/// Ethereum header synchronization status. -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum HeaderStatus { - /// Header is unknown. - Unknown, - /// Header is in MaybeOrphan queue. - MaybeOrphan, - /// Header is in Orphan queue. - Orphan, - /// Header is in MaybeReceipts queue. - MaybeReceipts, - /// Header is in Receipts queue. - Receipts, - /// Header is in Ready queue. - Ready, - /// Header has been recently submitted to the Substrate runtime. - Submitted, - /// Header is known to the Substrate runtime. - Synced, -} - -#[derive(Clone, Debug, Default)] +/// Ethereum synchronization pipeline. +#[derive(Clone, Copy, Debug)] #[cfg_attr(test, derive(PartialEq))] -pub struct QueuedHeader { - header: Header, - receipts: Option>, -} - -impl QueuedHeader { - /// Creates new queued header. - pub fn new(header: Header) -> Self { - QueuedHeader { header, receipts: None } - } +pub struct EthereumHeadersSyncPipeline; - /// Returns ID of header. - pub fn id(&self) -> HeaderId { - (&self.header).into() - } +impl HeadersSyncPipeline for EthereumHeadersSyncPipeline { + type Hash = H256; + type Number = u64; + type Header = Header; + type Extra = Vec; - /// Returns ID of parent header. - pub fn parent_id(&self) -> HeaderId { - HeaderId( - self.header.number.expect(HEADER_ID_PROOF).as_u64() - 1, - self.header.parent_hash, - ) + fn source_name() -> &'static str { + "Ethereum" } - /// Returns reference to header. - pub fn header(&self) -> &Header { - &self.header + fn target_name() -> &'static str { + "Substrate" } - /// Returns reference to transactions receipts. - pub fn receipts(&self) -> &Option> { - &self.receipts + fn estimate_size(source: &QueuedHeader) -> usize { + into_substrate_ethereum_header(source.header()).encode().len() + + into_substrate_ethereum_receipts(source.extra()) + .map(|extra| extra.encode().len()) + .unwrap_or(0) } +} - /// Extract header and receipts from self. - pub fn extract(self) -> (Header, Option>) { - (self.header, self.receipts) +impl SourceHeader for Header { + fn id(&self) -> EthereumHeaderId { + HeaderId( + self.number.expect(HEADER_ID_PROOF).as_u64(), + self.hash.expect(HEADER_ID_PROOF), + ) } - /// Set associated transaction receipts. - pub fn set_receipts(mut self, receipts: Vec) -> Self { - self.receipts = Some(receipts); - self + fn parent_id(&self) -> EthereumHeaderId { + HeaderId( + self.number.expect(HEADER_ID_PROOF).as_u64() - 1, + self.parent_hash, + ) } } diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index 881bc15fee..dd772bcc13 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -14,46 +14,73 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::ethereum_types::{Header, HeaderId, HeaderStatus, QueuedHeader, Receipt, H256}; +use crate::sync_types::{HeaderId, HeaderStatus, HeadersSyncPipeline, QueuedHeader, SourceHeader}; +use num_traits::{One, Zero}; use std::collections::{ btree_map::Entry as BTreeMapEntry, hash_map::Entry as HashMapEntry, BTreeMap, HashMap, HashSet, }; -type HeadersQueue = BTreeMap>; -type KnownHeaders = BTreeMap>; +type HeadersQueue

= BTreeMap< +

::Number, + HashMap< +

::Hash, + QueuedHeader

, + >, +>; +type KnownHeaders

= BTreeMap< +

::Number, + HashMap< +

::Hash, + HeaderStatus, + >, +>; /// Ethereum headers queue. -#[derive(Debug, Default)] -pub struct QueuedHeaders { - /// Headers that are received from Ethereum node, but we (native ethereum sync code) have +#[derive(Debug)] +pub struct QueuedHeaders { + /// Headers that are received from source node, but we (native sync code) have /// never seen their parents. So we need to check if we can/should submit this header. - maybe_orphan: HeadersQueue, - /// Headers that are received from Ethreum node, and we (native ethereum sync code) have + maybe_orphan: HeadersQueue

, + /// Headers that are received from source node, and we (native sync code) have /// checked that Substrate runtime doesn't know their parents. So we need to submit parents /// first. - orphan: HeadersQueue, - /// Headers that are ready to be submitted to Substrate runtime, but we need to check - /// whether submission requires transactions receipts to be provided. - maybe_receipts: HeadersQueue, - /// Headers that are ready to be submitted to Substrate runtime, but we need to retrieve - /// transactions receipts first. - receipts: HeadersQueue, - /// Headers that are ready to be submitted to Substrate runtime. - ready: HeadersQueue, - /// Headers that are (we believe) are currently submitted to Substrate runtime by our, + orphan: HeadersQueue

, + /// Headers that are ready to be submitted to target node, but we need to check + /// whether submission requires extra data to be provided. + maybe_extra: HeadersQueue

, + /// Headers that are ready to be submitted to target node, but we need to retrieve + /// extra data first. + extra: HeadersQueue

, + /// Headers that are ready to be submitted to target node. + ready: HeadersQueue

, + /// Headers that are (we believe) currently submitted to target node by our, /// not-yet mined transactions. - submitted: HeadersQueue, + submitted: HeadersQueue

, /// Pointers to all headers that we ever seen and we believe we can touch in the future. - known_headers: KnownHeaders, + known_headers: KnownHeaders

, /// Pruned blocks border. We do not store or accept any blocks with number less than /// this number. - prune_border: u64, + prune_border: P::Number, } -impl QueuedHeaders { +impl QueuedHeaders

{ + /// Returns new QueuedHeaders. + pub fn new() -> Self { + QueuedHeaders { + maybe_orphan: HeadersQueue::new(), + orphan: HeadersQueue::new(), + maybe_extra: HeadersQueue::new(), + extra: HeadersQueue::new(), + ready: HeadersQueue::new(), + submitted: HeadersQueue::new(), + known_headers: KnownHeaders::

::new(), + prune_border: Zero::zero(), + } + } + /// Returns prune border. #[cfg(test)] - pub fn prune_border(&self) -> u64 { + pub fn prune_border(&self) -> P::Number { self.prune_border } @@ -66,11 +93,11 @@ impl QueuedHeaders { .values() .fold(0, |total, headers| total + headers.len()), HeaderStatus::Orphan => self.orphan.values().fold(0, |total, headers| total + headers.len()), - HeaderStatus::MaybeReceipts => self - .maybe_receipts + HeaderStatus::MaybeExtra => self + .maybe_extra .values() .fold(0, |total, headers| total + headers.len()), - HeaderStatus::Receipts => self.receipts.values().fold(0, |total, headers| total + headers.len()), + HeaderStatus::Extra => self.extra.values().fold(0, |total, headers| total + headers.len()), HeaderStatus::Ready => self.ready.values().fold(0, |total, headers| total + headers.len()), HeaderStatus::Submitted => self.submitted.values().fold(0, |total, headers| total + headers.len()), } @@ -83,24 +110,24 @@ impl QueuedHeaders { .fold(0, |total, headers| total + headers.len()) + self.orphan.values().fold(0, |total, headers| total + headers.len()) + self - .maybe_receipts + .maybe_extra .values() .fold(0, |total, headers| total + headers.len()) - + self.receipts.values().fold(0, |total, headers| total + headers.len()) + + self.extra.values().fold(0, |total, headers| total + headers.len()) + self.ready.values().fold(0, |total, headers| total + headers.len()) } /// Returns number of best block in the queue. - pub fn best_queued_number(&self) -> u64 { + pub fn best_queued_number(&self) -> P::Number { std::cmp::max( - self.maybe_orphan.keys().next_back().cloned().unwrap_or(0), + self.maybe_orphan.keys().next_back().cloned().unwrap_or_else(Zero::zero), std::cmp::max( - self.orphan.keys().next_back().cloned().unwrap_or(0), + self.orphan.keys().next_back().cloned().unwrap_or_else(Zero::zero), std::cmp::max( - self.maybe_receipts.keys().next_back().cloned().unwrap_or(0), + self.maybe_extra.keys().next_back().cloned().unwrap_or_else(Zero::zero), std::cmp::max( - self.receipts.keys().next_back().cloned().unwrap_or(0), - self.ready.keys().next_back().cloned().unwrap_or(0), + self.extra.keys().next_back().cloned().unwrap_or_else(Zero::zero), + self.ready.keys().next_back().cloned().unwrap_or_else(Zero::zero), ), ), ), @@ -108,7 +135,7 @@ impl QueuedHeaders { } /// Returns synchronization status of the header. - pub fn status(&self, id: &HeaderId) -> HeaderStatus { + pub fn status(&self, id: &HeaderId) -> HeaderStatus { self.known_headers .get(&id.0) .and_then(|x| x.get(&id.1)) @@ -117,46 +144,61 @@ impl QueuedHeaders { } /// Get oldest header from given queue. - pub fn header(&self, status: HeaderStatus) -> Option<&QueuedHeader> { + pub fn header(&self, status: HeaderStatus) -> Option<&QueuedHeader

> { match status { HeaderStatus::Unknown | HeaderStatus::Synced => return None, HeaderStatus::MaybeOrphan => oldest_header(&self.maybe_orphan), HeaderStatus::Orphan => oldest_header(&self.orphan), - HeaderStatus::MaybeReceipts => oldest_header(&self.maybe_receipts), - HeaderStatus::Receipts => oldest_header(&self.receipts), + HeaderStatus::MaybeExtra => oldest_header(&self.maybe_extra), + HeaderStatus::Extra => oldest_header(&self.extra), HeaderStatus::Ready => oldest_header(&self.ready), HeaderStatus::Submitted => oldest_header(&self.submitted), } } /// Get oldest headers from given queue until functor will return false. - pub fn headers(&self, status: HeaderStatus, f: impl FnMut(&QueuedHeader) -> bool) -> Option> { + pub fn headers( + &self, + status: HeaderStatus, + f: impl FnMut(&QueuedHeader

) -> bool, + ) -> Option>> { match status { HeaderStatus::Unknown | HeaderStatus::Synced => return None, HeaderStatus::MaybeOrphan => oldest_headers(&self.maybe_orphan, f), HeaderStatus::Orphan => oldest_headers(&self.orphan, f), - HeaderStatus::MaybeReceipts => oldest_headers(&self.maybe_receipts, f), - HeaderStatus::Receipts => oldest_headers(&self.receipts, f), + HeaderStatus::MaybeExtra => oldest_headers(&self.maybe_extra, f), + HeaderStatus::Extra => oldest_headers(&self.extra, f), HeaderStatus::Ready => oldest_headers(&self.ready, f), HeaderStatus::Submitted => oldest_headers(&self.submitted, f), } } - /// Appends new header to the queue. - pub fn header_response(&mut self, header: Header) { - let id = (&header).into(); + /// Appends new header, received from the source node, to the queue. + pub fn header_response(&mut self, header: P::Header) { + let id = header.id(); let status = self.status(&id); if status != HeaderStatus::Unknown { - log::debug!(target: "bridge", "Ignoring new Ethereum header: {:?}. Status is {:?}.", id, status); + log::debug!( + target: "bridge", + "Ignoring new {} header: {:?}. Status is {:?}.", + P::source_name(), + id, + status, + ); return; } if id.0 < self.prune_border { - log::debug!(target: "bridge", "Ignoring ancient new Ethereum header: {:?}.", id); + log::debug!( + target: "bridge", + "Ignoring ancient new {} header: {:?}.", + P::source_name(), + id, + ); return; } - let parent_id = HeaderId(id.0 - 1, header.parent_hash); + let parent_id = header.parent_id(); let parent_status = self.status(&parent_id); let header = QueuedHeader::new(header); @@ -169,22 +211,28 @@ impl QueuedHeaders { insert_header(&mut self.orphan, id, header); HeaderStatus::Orphan } - HeaderStatus::MaybeReceipts - | HeaderStatus::Receipts + HeaderStatus::MaybeExtra + | HeaderStatus::Extra | HeaderStatus::Ready | HeaderStatus::Submitted | HeaderStatus::Synced => { - insert_header(&mut self.maybe_receipts, id, header); - HeaderStatus::MaybeReceipts + insert_header(&mut self.maybe_extra, id, header); + HeaderStatus::MaybeExtra } }; self.known_headers.entry(id.0).or_default().insert(id.1, status); - log::debug!(target: "bridge", "Queueing new Ethereum header: {:?}. Queue: {:?}.", id, status); + log::debug!( + target: "bridge", + "Queueing new {} header: {:?}. Queue: {:?}.", + P::source_name(), + id, + status, + ); } - /// Receive Substrate best header. - pub fn substrate_best_header_response(&mut self, id: &HeaderId) { + /// Receive best header from the target node. + pub fn target_best_header_response(&mut self, id: &HeaderId) { // all ancestors of this header are now synced => let's remove them from // queues let mut current = *id; @@ -193,15 +241,21 @@ impl QueuedHeaders { HeaderStatus::Unknown => break, HeaderStatus::MaybeOrphan => remove_header(&mut self.maybe_orphan, ¤t), HeaderStatus::Orphan => remove_header(&mut self.orphan, ¤t), - HeaderStatus::MaybeReceipts => remove_header(&mut self.maybe_receipts, ¤t), - HeaderStatus::Receipts => remove_header(&mut self.receipts, ¤t), + HeaderStatus::MaybeExtra => remove_header(&mut self.maybe_extra, ¤t), + HeaderStatus::Extra => remove_header(&mut self.extra, ¤t), HeaderStatus::Ready => remove_header(&mut self.ready, ¤t), HeaderStatus::Submitted => remove_header(&mut self.submitted, ¤t), HeaderStatus::Synced => break, } .expect("header has a given status; given queue has the header; qed"); - log::debug!(target: "bridge", "Ethereum header {:?} is now {:?}", current, HeaderStatus::Synced); + log::debug!( + target: "bridge", + "{} header {:?} is now {:?}", + P::source_name(), + current, + HeaderStatus::Synced, + ); *self .known_headers .entry(current.0) @@ -212,7 +266,13 @@ impl QueuedHeaders { } // remember that the header is synced - log::debug!(target: "bridge", "Ethereum header {:?} is now {:?}", id, HeaderStatus::Synced); + log::debug!( + target: "bridge", + "{} header {:?} is now {:?}", + P::source_name(), + id, + HeaderStatus::Synced, + ); *self .known_headers .entry(id.0) @@ -221,20 +281,20 @@ impl QueuedHeaders { .or_insert(HeaderStatus::Synced) = HeaderStatus::Synced; // now let's move all descendants from maybe_orphan && orphan queues to - // maybe_receipts queue - move_header_descendants( + // maybe_extra queue + move_header_descendants::

( &mut [&mut self.maybe_orphan, &mut self.orphan], - &mut self.maybe_receipts, + &mut self.maybe_extra, &mut self.known_headers, - HeaderStatus::MaybeReceipts, + HeaderStatus::MaybeExtra, id, ); } - /// Receive Substrate response for MaybeOrphan request. - pub fn maybe_orphan_response(&mut self, id: &HeaderId, response: bool) { + /// Receive target node response for MaybeOrphan request. + pub fn maybe_orphan_response(&mut self, id: &HeaderId, response: bool) { if !response { - move_header_descendants( + move_header_descendants::

( &mut [&mut self.maybe_orphan], &mut self.orphan, &mut self.known_headers, @@ -244,25 +304,25 @@ impl QueuedHeaders { return; } - move_header_descendants( + move_header_descendants::

( &mut [&mut self.maybe_orphan, &mut self.orphan], - &mut self.maybe_receipts, + &mut self.maybe_extra, &mut self.known_headers, - HeaderStatus::MaybeReceipts, + HeaderStatus::MaybeExtra, &id, ); } - /// Receive Substrate response for MaybeReceipts request. - pub fn maybe_receipts_response(&mut self, id: &HeaderId, response: bool) { + /// Receive target node response for MaybeExtra request. + pub fn maybe_extra_response(&mut self, id: &HeaderId, response: bool) { let (destination_status, destination_queue) = if response { - (HeaderStatus::Receipts, &mut self.receipts) + (HeaderStatus::Extra, &mut self.extra) } else { (HeaderStatus::Ready, &mut self.ready) }; move_header( - &mut self.maybe_receipts, + &mut self.maybe_extra, destination_queue, &mut self.known_headers, destination_status, @@ -271,20 +331,20 @@ impl QueuedHeaders { ); } - /// Receive transactions receipts from Ethereum node. - pub fn receipts_response(&mut self, id: &HeaderId, receipts: Vec) { + /// Receive extra from source node. + pub fn extra_response(&mut self, id: &HeaderId, extra: P::Extra) { move_header( - &mut self.receipts, + &mut self.extra, &mut self.ready, &mut self.known_headers, HeaderStatus::Ready, id, - |header| header.set_receipts(receipts), + |header| header.set_extra(extra), ); } - /// When header is submitted to Substrate node. - pub fn headers_submitted(&mut self, ids: Vec) { + /// When header is submitted to target node. + pub fn headers_submitted(&mut self, ids: Vec>) { for id in ids { move_header( &mut self.ready, @@ -298,18 +358,18 @@ impl QueuedHeaders { } /// Prune and never accep headers before this block. - pub fn prune(&mut self, prune_border: u64) { + pub fn prune(&mut self, prune_border: P::Number) { if prune_border <= self.prune_border { return; } prune_queue(&mut self.maybe_orphan, prune_border); prune_queue(&mut self.orphan, prune_border); - prune_queue(&mut self.maybe_receipts, prune_border); - prune_queue(&mut self.receipts, prune_border); + prune_queue(&mut self.maybe_extra, prune_border); + prune_queue(&mut self.extra, prune_border); prune_queue(&mut self.ready, prune_border); prune_queue(&mut self.submitted, prune_border); - prune_known_headers(&mut self.known_headers, prune_border); + prune_known_headers::

(&mut self.known_headers, prune_border); self.prune_border = prune_border; } @@ -317,22 +377,29 @@ impl QueuedHeaders { pub fn clear(&mut self) { self.maybe_orphan.clear(); self.orphan.clear(); - self.maybe_receipts.clear(); - self.receipts.clear(); + self.maybe_extra.clear(); + self.extra.clear(); self.ready.clear(); self.submitted.clear(); self.known_headers.clear(); - self.prune_border = 0; + self.prune_border = Zero::zero(); } } /// Insert header to the queue. -fn insert_header(queue: &mut HeadersQueue, id: HeaderId, header: QueuedHeader) { +fn insert_header( + queue: &mut HeadersQueue

, + id: HeaderId, + header: QueuedHeader

, +) { queue.entry(id.0).or_default().insert(id.1, header); } /// Remove header from the queue. -fn remove_header(queue: &mut HeadersQueue, id: &HeaderId) -> Option { +fn remove_header( + queue: &mut HeadersQueue

, + id: &HeaderId, +) -> Option> { let mut headers_at = match queue.entry(id.0) { BTreeMapEntry::Occupied(headers_at) => headers_at, BTreeMapEntry::Vacant(_) => return None, @@ -346,13 +413,13 @@ fn remove_header(queue: &mut HeadersQueue, id: &HeaderId) -> Option( + source_queue: &mut HeadersQueue

, + destination_queue: &mut HeadersQueue

, + known_headers: &mut KnownHeaders

, destination_status: HeaderStatus, - id: &HeaderId, - prepare: impl FnOnce(QueuedHeader) -> QueuedHeader, + id: &HeaderId, + prepare: impl FnOnce(QueuedHeader

) -> QueuedHeader

, ) { let header = match remove_header(source_queue, id) { Some(header) => prepare(header), @@ -364,21 +431,22 @@ fn move_header( log::debug!( target: "bridge", - "Ethereum header {:?} is now {:?}", + "{} header {:?} is now {:?}", + P::source_name(), id, destination_status, ); } /// Move all descendant headers from the source to destination queue. -fn move_header_descendants( - source_queues: &mut [&mut HeadersQueue], - destination_queue: &mut HeadersQueue, - known_headers: &mut KnownHeaders, +fn move_header_descendants( + source_queues: &mut [&mut HeadersQueue

], + destination_queue: &mut HeadersQueue

, + known_headers: &mut KnownHeaders

, destination_status: HeaderStatus, - id: &HeaderId, + id: &HeaderId, ) { - let mut current_number = id.0 + 1; + let mut current_number = id.0 + One::one(); let mut current_parents = HashSet::new(); current_parents.insert(id.1); @@ -398,7 +466,7 @@ fn move_header_descendants( HashMapEntry::Vacant(_) => unreachable!("iterating existing keys; qed"), }; - if current_parents.contains(&entry.get().header().parent_hash) { + if current_parents.contains(&entry.get().header().parent_id().1) { let header_to_move = entry.remove(); let header_to_move_id = header_to_move.id(); known_headers @@ -409,7 +477,8 @@ fn move_header_descendants( log::debug!( target: "bridge", - "Ethereum header {:?} is now {:?}", + "{} header {:?} is now {:?}", + P::source_name(), header_to_move_id, destination_status, ); @@ -428,18 +497,21 @@ fn move_header_descendants( .extend(headers_to_move.into_iter().map(|(id, h)| (id.1, h))) } - current_number = current_number + 1; + current_number = current_number + One::one(); std::mem::swap(&mut current_parents, &mut next_parents); } } /// Return oldest header from the queue. -fn oldest_header(queue: &HeadersQueue) -> Option<&QueuedHeader> { +fn oldest_header(queue: &HeadersQueue

) -> Option<&QueuedHeader

> { queue.values().flat_map(|h| h.values()).next() } /// Return oldest headers from the queue until functor will return false. -fn oldest_headers(queue: &HeadersQueue, mut f: impl FnMut(&QueuedHeader) -> bool) -> Option> { +fn oldest_headers( + queue: &HeadersQueue

, + mut f: impl FnMut(&QueuedHeader

) -> bool, +) -> Option>> { let result = queue .values() .flat_map(|h| h.values()) @@ -453,12 +525,18 @@ fn oldest_headers(queue: &HeadersQueue, mut f: impl FnMut(&QueuedHeader) -> bool } /// Forget all headers with number less than given. -fn prune_queue(queue: &mut HeadersQueue, prune_border: u64) { +fn prune_queue( + queue: &mut HeadersQueue

, + prune_border: P::Number, +) { *queue = queue.split_off(&prune_border); } /// Forget all known headers with number less than given. -fn prune_known_headers(known_headers: &mut KnownHeaders, prune_border: u64) { +fn prune_known_headers( + known_headers: &mut KnownHeaders

, + prune_border: P::Number, +) { let new_known_headers = known_headers.split_off(&prune_border); for (pruned_number, pruned_headers) in &*known_headers { for pruned_hash in pruned_headers.keys() { @@ -471,8 +549,10 @@ fn prune_known_headers(known_headers: &mut KnownHeaders, prune_border: u64) { #[cfg(test)] pub(crate) mod tests { use super::*; + use crate::ethereum_types::{EthereumHeaderId, EthereumHeadersSyncPipeline, H256, Header}; + use crate::sync_types::{HeaderId, QueuedHeader}; - pub(crate) fn header(number: u64) -> QueuedHeader { + pub(crate) fn header(number: u64) -> QueuedHeader { QueuedHeader::new(Header { number: Some(number.into()), hash: Some(hash(number)), @@ -485,85 +565,101 @@ pub(crate) mod tests { H256::from_low_u64_le(number) } - pub(crate) fn id(number: u64) -> HeaderId { + pub(crate) fn id(number: u64) -> EthereumHeaderId { HeaderId(number, hash(number)) } #[test] fn total_headers_works() { // total headers just sums up number of headers in every queue - let mut queue = QueuedHeaders::default(); + let mut queue = QueuedHeaders::::new(); queue .maybe_orphan .entry(1) .or_default() - .insert(hash(1), Default::default()); + .insert(hash(1), QueuedHeader::::new(Default::default())); queue .maybe_orphan .entry(1) .or_default() - .insert(hash(2), Default::default()); + .insert(hash(2), QueuedHeader::::new(Default::default())); queue .maybe_orphan .entry(2) .or_default() - .insert(hash(3), Default::default()); - queue.orphan.entry(3).or_default().insert(hash(4), Default::default()); + .insert(hash(3), QueuedHeader::::new(Default::default())); + queue + .orphan + .entry(3) + .or_default() + .insert(hash(4), QueuedHeader::::new(Default::default())); queue - .maybe_receipts + .maybe_extra .entry(4) .or_default() - .insert(hash(5), Default::default()); - queue.ready.entry(5).or_default().insert(hash(6), Default::default()); + .insert(hash(5), QueuedHeader::::new(Default::default())); + queue + .ready + .entry(5) + .or_default() + .insert(hash(6), QueuedHeader::::new(Default::default())); assert_eq!(queue.total_headers(), 6); } #[test] fn best_queued_number_works() { // initially there are headers in MaybeOrphan queue only - let mut queue = QueuedHeaders::default(); + let mut queue = QueuedHeaders::::new(); queue .maybe_orphan .entry(1) .or_default() - .insert(hash(1), Default::default()); + .insert(hash(1), QueuedHeader::::new(Default::default())); queue .maybe_orphan .entry(1) .or_default() - .insert(hash(2), Default::default()); + .insert(hash(2), QueuedHeader::::new(Default::default())); queue .maybe_orphan .entry(3) .or_default() - .insert(hash(3), Default::default()); + .insert(hash(3), QueuedHeader::::new(Default::default())); assert_eq!(queue.best_queued_number(), 3); // and then there's better header in Orphan - queue.orphan.entry(10).or_default().insert(hash(10), Default::default()); + queue + .orphan + .entry(10) + .or_default() + .insert(hash(10), QueuedHeader::::new(Default::default())); assert_eq!(queue.best_queued_number(), 10); - // and then there's better header in MaybeReceipts + // and then there's better header in MaybeExtra queue - .maybe_receipts + .maybe_extra .entry(20) .or_default() - .insert(hash(20), Default::default()); + .insert(hash(20), QueuedHeader::::new(Default::default())); assert_eq!(queue.best_queued_number(), 20); // and then there's better header in Ready - queue.ready.entry(30).or_default().insert(hash(30), Default::default()); + queue + .ready + .entry(30) + .or_default() + .insert(hash(30), QueuedHeader::::new(Default::default())); assert_eq!(queue.best_queued_number(), 30); // and then there's better header in MaybeOrphan again queue .maybe_orphan .entry(40) .or_default() - .insert(hash(40), Default::default()); + .insert(hash(40), QueuedHeader::::new(Default::default())); assert_eq!(queue.best_queued_number(), 40); } #[test] fn status_works() { // all headers are unknown initially - let mut queue = QueuedHeaders::default(); + let mut queue = QueuedHeaders::::new(); assert_eq!(queue.status(&id(10)), HeaderStatus::Unknown); // and status is read from the KnownHeaders queue @@ -577,7 +673,7 @@ pub(crate) mod tests { #[test] fn header_works() { // initially we have oldest header #10 - let mut queue = QueuedHeaders::default(); + let mut queue = QueuedHeaders::::new(); queue.maybe_orphan.entry(10).or_default().insert(hash(1), header(100)); assert_eq!( queue.header(HeaderStatus::MaybeOrphan).unwrap().header().hash.unwrap(), @@ -599,48 +695,48 @@ pub(crate) mod tests { #[test] fn header_response_works() { - // when parent is Synced, we insert to MaybeReceipts - let mut queue = QueuedHeaders::default(); + // when parent is Synced, we insert to MaybeExtra + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) .or_default() .insert(hash(100), HeaderStatus::Synced); queue.header_response(header(101).header().clone()); - assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeReceipts); + assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeExtra); - // when parent is Ready, we insert to MaybeReceipts - let mut queue = QueuedHeaders::default(); + // when parent is Ready, we insert to MaybeExtra + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) .or_default() .insert(hash(100), HeaderStatus::Ready); queue.header_response(header(101).header().clone()); - assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeReceipts); + assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeExtra); - // when parent is Receipts, we insert to MaybeReceipts - let mut queue = QueuedHeaders::default(); + // when parent is Receipts, we insert to MaybeExtra + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) .or_default() - .insert(hash(100), HeaderStatus::Receipts); + .insert(hash(100), HeaderStatus::Extra); queue.header_response(header(101).header().clone()); - assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeReceipts); + assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeExtra); - // when parent is MaybeReceipts, we insert to MaybeReceipts - let mut queue = QueuedHeaders::default(); + // when parent is MaybeExtra, we insert to MaybeExtra + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) .or_default() - .insert(hash(100), HeaderStatus::MaybeReceipts); + .insert(hash(100), HeaderStatus::MaybeExtra); queue.header_response(header(101).header().clone()); - assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeReceipts); + assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeExtra); // when parent is Orphan, we insert to Orphan - let mut queue = QueuedHeaders::default(); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -650,7 +746,7 @@ pub(crate) mod tests { assert_eq!(queue.status(&id(101)), HeaderStatus::Orphan); // when parent is MaybeOrphan, we insert to MaybeOrphan - let mut queue = QueuedHeaders::default(); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -660,7 +756,7 @@ pub(crate) mod tests { assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeOrphan); // when parent is unknown, we insert to MaybeOrphan - let mut queue = QueuedHeaders::default(); + let mut queue = QueuedHeaders::::new(); queue.header_response(header(101).header().clone()); assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeOrphan); } @@ -671,10 +767,10 @@ pub(crate) mod tests { // its best block to #100. At this time we have: // #100 in MaybeOrphan // #99 in Orphan - // #98 in MaybeReceipts + // #98 in MaybeExtra // #97 in Receipts // #96 in Ready - let mut queue = QueuedHeaders::default(); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -695,27 +791,27 @@ pub(crate) mod tests { .known_headers .entry(98) .or_default() - .insert(hash(98), HeaderStatus::MaybeReceipts); - queue.maybe_receipts.entry(98).or_default().insert(hash(98), header(98)); + .insert(hash(98), HeaderStatus::MaybeExtra); + queue.maybe_extra.entry(98).or_default().insert(hash(98), header(98)); queue .known_headers .entry(97) .or_default() - .insert(hash(97), HeaderStatus::Receipts); - queue.receipts.entry(97).or_default().insert(hash(97), header(97)); + .insert(hash(97), HeaderStatus::Extra); + queue.extra.entry(97).or_default().insert(hash(97), header(97)); queue .known_headers .entry(96) .or_default() .insert(hash(96), HeaderStatus::Ready); queue.ready.entry(96).or_default().insert(hash(96), header(96)); - queue.substrate_best_header_response(&id(100)); + queue.target_best_header_response(&id(100)); // then the #100 and all ancestors of #100 (#96..#99) are treated as synced assert!(queue.maybe_orphan.is_empty()); assert!(queue.orphan.is_empty()); - assert!(queue.maybe_receipts.is_empty()); - assert!(queue.receipts.is_empty()); + assert!(queue.maybe_extra.is_empty()); + assert!(queue.extra.is_empty()); assert!(queue.ready.is_empty()); assert_eq!(queue.known_headers.len(), 5); assert!(queue @@ -731,7 +827,7 @@ pub(crate) mod tests { // #101 in Orphan // #102 in MaybeOrphan // #103 in Orphan - let mut queue = QueuedHeaders::default(); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(101) @@ -754,15 +850,15 @@ pub(crate) mod tests { .or_default() .insert(hash(103), HeaderStatus::Orphan); queue.orphan.entry(103).or_default().insert(hash(103), header(103)); - queue.substrate_best_header_response(&id(100)); + queue.target_best_header_response(&id(100)); - // all descendants are moved to MaybeReceipts + // all descendants are moved to MaybeExtra assert!(queue.maybe_orphan.is_empty()); assert!(queue.orphan.is_empty()); - assert_eq!(queue.maybe_receipts.len(), 3); - assert_eq!(queue.known_headers[&101][&hash(101)], HeaderStatus::MaybeReceipts); - assert_eq!(queue.known_headers[&102][&hash(102)], HeaderStatus::MaybeReceipts); - assert_eq!(queue.known_headers[&103][&hash(103)], HeaderStatus::MaybeReceipts); + assert_eq!(queue.maybe_extra.len(), 3); + assert_eq!(queue.known_headers[&101][&hash(101)], HeaderStatus::MaybeExtra); + assert_eq!(queue.known_headers[&102][&hash(102)], HeaderStatus::MaybeExtra); + assert_eq!(queue.known_headers[&103][&hash(103)], HeaderStatus::MaybeExtra); } #[test] @@ -773,7 +869,7 @@ pub(crate) mod tests { // #102 in MaybeOrphan // and we have asked for MaybeOrphan status of #100.parent (i.e. #99) // and the response is: YES, #99 is known to the Substrate runtime - let mut queue = QueuedHeaders::default(); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -802,13 +898,13 @@ pub(crate) mod tests { .insert(hash(102), header(102)); queue.maybe_orphan_response(&id(99), true); - // then all headers (#100..#103) are moved to the MaybeReceipts queue + // then all headers (#100..#103) are moved to the MaybeExtra queue assert!(queue.orphan.is_empty()); assert!(queue.maybe_orphan.is_empty()); - assert_eq!(queue.maybe_receipts.len(), 3); - assert_eq!(queue.known_headers[&100][&hash(100)], HeaderStatus::MaybeReceipts); - assert_eq!(queue.known_headers[&101][&hash(101)], HeaderStatus::MaybeReceipts); - assert_eq!(queue.known_headers[&102][&hash(102)], HeaderStatus::MaybeReceipts); + assert_eq!(queue.maybe_extra.len(), 3); + assert_eq!(queue.known_headers[&100][&hash(100)], HeaderStatus::MaybeExtra); + assert_eq!(queue.known_headers[&101][&hash(101)], HeaderStatus::MaybeExtra); + assert_eq!(queue.known_headers[&102][&hash(102)], HeaderStatus::MaybeExtra); } #[test] @@ -818,7 +914,7 @@ pub(crate) mod tests { // #101 in MaybeOrphan // and we have asked for MaybeOrphan status of #100.parent (i.e. #99) // and the response is: NO, #99 is NOT known to the Substrate runtime - let mut queue = QueuedHeaders::default(); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -849,61 +945,61 @@ pub(crate) mod tests { } #[test] - fn positive_maybe_receipts_response_works() { - let mut queue = QueuedHeaders::default(); + fn positive_maybe_extra_response_works() { + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) .or_default() - .insert(hash(100), HeaderStatus::MaybeReceipts); + .insert(hash(100), HeaderStatus::MaybeExtra); queue - .maybe_receipts + .maybe_extra .entry(100) .or_default() .insert(hash(100), header(100)); - queue.maybe_receipts_response(&id(100), true); - assert!(queue.maybe_receipts.is_empty()); - assert_eq!(queue.receipts.len(), 1); - assert_eq!(queue.known_headers[&100][&hash(100)], HeaderStatus::Receipts); + queue.maybe_extra_response(&id(100), true); + assert!(queue.maybe_extra.is_empty()); + assert_eq!(queue.extra.len(), 1); + assert_eq!(queue.known_headers[&100][&hash(100)], HeaderStatus::Extra); } #[test] - fn negative_maybe_receipts_response_works() { - let mut queue = QueuedHeaders::default(); + fn negative_maybe_extra_response_works() { + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) .or_default() - .insert(hash(100), HeaderStatus::MaybeReceipts); + .insert(hash(100), HeaderStatus::MaybeExtra); queue - .maybe_receipts + .maybe_extra .entry(100) .or_default() .insert(hash(100), header(100)); - queue.maybe_receipts_response(&id(100), false); - assert!(queue.maybe_receipts.is_empty()); + queue.maybe_extra_response(&id(100), false); + assert!(queue.maybe_extra.is_empty()); assert_eq!(queue.ready.len(), 1); assert_eq!(queue.known_headers[&100][&hash(100)], HeaderStatus::Ready); } #[test] fn receipts_response_works() { - let mut queue = QueuedHeaders::default(); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) .or_default() - .insert(hash(100), HeaderStatus::Receipts); - queue.receipts.entry(100).or_default().insert(hash(100), header(100)); - queue.receipts_response(&id(100), Vec::new()); - assert!(queue.receipts.is_empty()); + .insert(hash(100), HeaderStatus::Extra); + queue.extra.entry(100).or_default().insert(hash(100), header(100)); + queue.extra_response(&id(100), Vec::new()); + assert!(queue.extra.is_empty()); assert_eq!(queue.ready.len(), 1); assert_eq!(queue.known_headers[&100][&hash(100)], HeaderStatus::Ready); } #[test] fn header_submitted_works() { - let mut queue = QueuedHeaders::default(); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -917,7 +1013,7 @@ pub(crate) mod tests { #[test] fn prune_works() { - let mut queue = QueuedHeaders::default(); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(104) @@ -938,9 +1034,9 @@ pub(crate) mod tests { .known_headers .entry(102) .or_default() - .insert(hash(102), HeaderStatus::MaybeReceipts); + .insert(hash(102), HeaderStatus::MaybeExtra); queue - .maybe_receipts + .maybe_extra .entry(102) .or_default() .insert(hash(102), header(102)); @@ -948,8 +1044,8 @@ pub(crate) mod tests { .known_headers .entry(101) .or_default() - .insert(hash(101), HeaderStatus::Receipts); - queue.receipts.entry(101).or_default().insert(hash(101), header(101)); + .insert(hash(101), HeaderStatus::Extra); + queue.extra.entry(101).or_default().insert(hash(101), header(101)); queue .known_headers .entry(100) @@ -960,8 +1056,8 @@ pub(crate) mod tests { queue.prune(102); assert_eq!(queue.ready.len(), 0); - assert_eq!(queue.receipts.len(), 0); - assert_eq!(queue.maybe_receipts.len(), 1); + assert_eq!(queue.extra.len(), 0); + assert_eq!(queue.maybe_extra.len(), 1); assert_eq!(queue.orphan.len(), 1); assert_eq!(queue.maybe_orphan.len(), 1); assert_eq!(queue.known_headers.len(), 3); @@ -969,8 +1065,8 @@ pub(crate) mod tests { queue.prune(110); assert_eq!(queue.ready.len(), 0); - assert_eq!(queue.receipts.len(), 0); - assert_eq!(queue.maybe_receipts.len(), 0); + assert_eq!(queue.extra.len(), 0); + assert_eq!(queue.maybe_extra.len(), 0); assert_eq!(queue.orphan.len(), 0); assert_eq!(queue.maybe_orphan.len(), 0); assert_eq!(queue.known_headers.len(), 0); diff --git a/relays/ethereum/src/main.rs b/relays/ethereum/src/main.rs index fcec82a383..7668d7c15f 100644 --- a/relays/ethereum/src/main.rs +++ b/relays/ethereum/src/main.rs @@ -17,14 +17,14 @@ #![recursion_limit = "1024"] mod ethereum_client; -mod ethereum_sync; mod ethereum_sync_loop; mod ethereum_types; mod headers; mod substrate_client; -mod substrate_sync; mod substrate_sync_loop; mod substrate_types; +mod sync; +mod sync_types; mod utils; use parity_crypto::publickey::KeyPair; diff --git a/relays/ethereum/src/substrate_client.rs b/relays/ethereum/src/substrate_client.rs index f52690f3c5..6fbe009344 100644 --- a/relays/ethereum/src/substrate_client.rs +++ b/relays/ethereum/src/substrate_client.rs @@ -14,9 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::ethereum_sync_loop::MaybeConnectionError; -use crate::ethereum_types::{Bytes, HeaderId as EthereumHeaderId, QueuedHeader as QueuedEthereumHeader, H256}; +use crate::ethereum_types::{Bytes, EthereumHeaderId, H256, QueuedEthereumHeader}; use crate::substrate_types::{into_substrate_ethereum_header, into_substrate_ethereum_receipts, TransactionHash}; +use crate::sync_types::HeaderId; +use crate::utils::MaybeConnectionError; use codec::{Decode, Encode}; use jsonrpsee::common::Params; use jsonrpsee::raw::{RawClient, RawClientError}; @@ -75,7 +76,7 @@ pub async fn best_ethereum_block(client: Client) -> (Client, Result { - eth_best_block_number_required = false; - } - } + } }); } diff --git a/relays/ethereum/src/sync.rs b/relays/ethereum/src/sync.rs index bc69eb9a7c..7e2f901684 100644 --- a/relays/ethereum/src/sync.rs +++ b/relays/ethereum/src/sync.rs @@ -15,68 +15,82 @@ // along with Parity Bridges Common. If not, see . use crate::headers::QueuedHeaders; -use crate::ethereum_sync_loop::EthereumSyncParams; -use crate::ethereum_types::{HeaderId, HeaderStatus, QueuedHeader}; -use crate::substrate_types::{into_substrate_ethereum_header, into_substrate_ethereum_receipts}; -use codec::Encode; +use crate::sync_types::{HeaderId, HeaderStatus, HeadersSyncPipeline, QueuedHeader}; +use num_traits::{One, Saturating}; -/// Ethereum headers synchronization context. +/// Common sync params. #[derive(Debug)] -pub struct HeadersSync { +pub struct HeadersSyncParams { + /// Maximal number of ethereum headers to pre-download. + pub max_future_headers_to_download: usize, + /// Maximal number of active (we believe) submit header transactions. + pub max_headers_in_submitted_status: usize, + /// Maximal number of headers in single submit request. + pub max_headers_in_single_submit: usize, + /// Maximal total headers size in single submit request. + pub max_headers_size_in_single_submit: usize, + /// We only may store and accept (from Ethereum node) headers that have + /// number >= than best_substrate_header.number - prune_depth. + pub prune_depth: u32, +} + +/// Headers synchronization context. +#[derive(Debug)] +pub struct HeadersSync { /// Synchronization parameters. - params: EthereumSyncParams, - /// Best header number known to Ethereum node. - target_header_number: Option, - /// Best header known to Substrate node. - best_header: Option, + params: HeadersSyncParams, + /// Best header number known to source node. + source_best_number: Option, + /// Best header known to target node. + target_best_header: Option>, /// Headers queue. - headers: QueuedHeaders, + headers: QueuedHeaders

, } -impl HeadersSync { - /// Creates new Ethereum headers synchronizer. - pub fn new(params: EthereumSyncParams) -> Self { +impl HeadersSync

{ + /// Creates new headers synchronizer. + pub fn new(params: HeadersSyncParams) -> Self { HeadersSync { params, - target_header_number: None, - best_header: None, - headers: Default::default(), + source_best_number: None, + target_best_header: None, + headers: QueuedHeaders::new(), } } /// Returns true if we have synced almost all known headers. pub fn is_almost_synced(&self) -> bool { - match self.target_header_number { - Some(target_header_number) => self - .best_header - .map(|best| target_header_number.saturating_sub(best.0) < 4) + match self.source_best_number { + Some(source_best_number) => self + .target_best_header + .map(|best| source_best_number.saturating_sub(best.0) < 4.into()) .unwrap_or(false), None => true, } } /// Returns synchronization status. - pub fn status(&self) -> (&Option, &Option) { - (&self.best_header, &self.target_header_number) + pub fn status(&self) -> (&Option>, &Option) { + (&self.target_best_header, &self.source_best_number) } /// Returns reference to the headers queue. - pub fn headers(&self) -> &QueuedHeaders { + pub fn headers(&self) -> &QueuedHeaders

{ &self.headers } /// Returns mutable reference to the headers queue. - pub fn headers_mut(&mut self) -> &mut QueuedHeaders { + pub fn headers_mut(&mut self) -> &mut QueuedHeaders

{ &mut self.headers } - /// Select header that needs to be downloaded from the Ethereum node. - pub fn select_new_header_to_download(&self) -> Option { - // if we haven't received best header from Ethereum node yet, there's nothing we can download - let target_header_number = self.target_header_number.clone()?; + /// Select header that needs to be downloaded from the source node. + pub fn select_new_header_to_download(&self) -> Option { + // if we haven't received best header from source node yet, there's nothing we can download + let source_best_number = self.source_best_number.clone()?; - // if we haven't received known best header from Substrate node yet, there's nothing we can download - let best_header = self.best_header.as_ref()?; + // if we haven't received known best header from target node yet, there's nothing we can download + let target_best_header = self.target_best_header.as_ref()?; // if there's too many headers in the queue, stop downloading let in_memory_headers = self.headers.total_headers(); @@ -85,17 +99,17 @@ impl HeadersSync { } // we assume that there were no reorgs if we have already downloaded best header - let best_downloaded_number = std::cmp::max(self.headers.best_queued_number(), best_header.0); - if best_downloaded_number == target_header_number { + let best_downloaded_number = std::cmp::max(self.headers.best_queued_number(), target_best_header.0); + if best_downloaded_number == source_best_number { return None; } // download new header - Some(best_downloaded_number + 1) + Some(best_downloaded_number + One::one()) } - /// Select headers that need to be submitted to the Substrate node. - pub fn select_headers_to_submit(&self) -> Option> { + /// Select headers that need to be submitted to the target node. + pub fn select_headers_to_submit(&self) -> Option>> { let headers_in_submit_status = self.headers.headers_in_status(HeaderStatus::Submitted); let headers_to_submit_count = self .params @@ -112,10 +126,7 @@ impl HeadersSync { return false; } - let encoded_size = into_substrate_ethereum_header(header.header()).encode().len() - + into_substrate_ethereum_receipts(header.receipts()) - .map(|receipts| receipts.encode().len()) - .unwrap_or(0); + let encoded_size = P::estimate_size(header); if total_headers != 0 && total_size + encoded_size > self.params.max_headers_size_in_single_submit { return false; } @@ -127,48 +138,71 @@ impl HeadersSync { }) } - /// Receive new target header number from the Ethereum node. - pub fn ethereum_best_header_number_response(&mut self, best_header_number: u64) { - log::debug!(target: "bridge", "Received best header number from Ethereum: {}", best_header_number); - self.target_header_number = Some(best_header_number); + /// Receive new target header number from the source node. + pub fn source_best_header_number_response(&mut self, best_header_number: P::Number) { + log::debug!( + target: "bridge", + "Received best header number from {} node: {}", + P::source_name(), + best_header_number, + ); + self.source_best_number = Some(best_header_number); } - /// Receive new best header from the Substrate node. + /// Receive new best header from the target node. /// Returns true if it is different from the previous block known to us. - pub fn substrate_best_header_response(&mut self, best_header: HeaderId) -> bool { - log::debug!(target: "bridge", "Received best known header from Substrate: {:?}", best_header); + pub fn target_best_header_response(&mut self, best_header: HeaderId) -> bool { + log::debug!( + target: "bridge", + "Received best known header from {}: {:?}", + P::target_name(), + best_header, + ); // early return if it is still the same - if self.best_header == Some(best_header) { + if self.target_best_header == Some(best_header) { return false; } // remember that this header is now known to the Substrate runtime - self.headers.substrate_best_header_response(&best_header); + self.headers.target_best_header_response(&best_header); // prune ancient headers self.headers - .prune(best_header.0.saturating_sub(self.params.prune_depth)); + .prune(best_header.0.saturating_sub(self.params.prune_depth.into())); // finally remember the best header itself - self.best_header = Some(best_header); + self.target_best_header = Some(best_header); true } /// Restart synchronization. pub fn restart(&mut self) { - self.target_header_number = None; - self.best_header = None; + self.source_best_number = None; + self.target_best_header = None; self.headers.clear(); } } +impl Default for HeadersSyncParams { + fn default() -> Self { + HeadersSyncParams { + max_future_headers_to_download: 128, + max_headers_in_submitted_status: 128, + max_headers_in_single_submit: 32, + max_headers_size_in_single_submit: 131_072, + prune_depth: 4096, + } + } +} + #[cfg(test)] mod tests { use super::*; use crate::headers::tests::{header, id}; - use crate::ethereum_types::{HeaderStatus, H256}; + use crate::ethereum_types::{EthereumHeadersSyncPipeline, H256}; + use crate::sync_types::HeaderStatus; fn side_hash(number: u64) -> H256 { H256::from_low_u64_le(1000 + number) @@ -176,26 +210,26 @@ mod tests { #[test] fn select_new_header_to_download_works() { - let mut eth_sync = HeadersSync::new(Default::default()); + let mut eth_sync = HeadersSync::::new(Default::default()); // both best && target headers are unknown assert_eq!(eth_sync.select_new_header_to_download(), None); // best header is known, target header is unknown - eth_sync.best_header = Some(HeaderId(0, Default::default())); + eth_sync.target_best_header = Some(HeaderId(0, Default::default())); assert_eq!(eth_sync.select_new_header_to_download(), None); // target header is known, best header is unknown - eth_sync.best_header = None; - eth_sync.target_header_number = Some(100); + eth_sync.target_best_header = None; + eth_sync.source_best_number = Some(100); assert_eq!(eth_sync.select_new_header_to_download(), None); // when our best block has the same number as the target - eth_sync.best_header = Some(HeaderId(100, Default::default())); + eth_sync.target_best_header = Some(HeaderId(100, Default::default())); assert_eq!(eth_sync.select_new_header_to_download(), None); // when we actually need a new header - eth_sync.target_header_number = Some(101); + eth_sync.source_best_number = Some(101); assert_eq!(eth_sync.select_new_header_to_download(), Some(101)); // when there are too many headers scheduled for submitting @@ -211,18 +245,18 @@ mod tests { eth_sync.params.max_headers_in_submitted_status = 1; // ethereum reports best header #102 - eth_sync.ethereum_best_header_number_response(102); + eth_sync.source_best_header_number_response(102); // substrate reports that it is at block #100 - eth_sync.substrate_best_header_response(id(100)); + eth_sync.target_best_header_response(id(100)); // block #101 is downloaded first assert_eq!(eth_sync.select_new_header_to_download(), Some(101)); eth_sync.headers.header_response(header(101).header().clone()); // now header #101 is ready to be submitted - assert_eq!(eth_sync.headers.header(HeaderStatus::MaybeReceipts), Some(&header(101))); - eth_sync.headers.maybe_receipts_response(&id(101), false); + assert_eq!(eth_sync.headers.header(HeaderStatus::MaybeExtra), Some(&header(101))); + eth_sync.headers.maybe_extra_response(&id(101), false); assert_eq!(eth_sync.headers.header(HeaderStatus::Ready), Some(&header(101))); assert_eq!(eth_sync.select_headers_to_submit(), Some(vec![&header(101)])); @@ -235,20 +269,20 @@ mod tests { // we have nothing to submit because previous header hasn't been confirmed yet // (and we allow max 1 submit transaction in the wild) - assert_eq!(eth_sync.headers.header(HeaderStatus::MaybeReceipts), Some(&header(102))); - eth_sync.headers.maybe_receipts_response(&id(102), false); + assert_eq!(eth_sync.headers.header(HeaderStatus::MaybeExtra), Some(&header(102))); + eth_sync.headers.maybe_extra_response(&id(102), false); assert_eq!(eth_sync.headers.header(HeaderStatus::Ready), Some(&header(102))); assert_eq!(eth_sync.select_headers_to_submit(), None); // substrate reports that it has imported block #101 - eth_sync.substrate_best_header_response(id(101)); + eth_sync.target_best_header_response(id(101)); // and we are ready to submit #102 assert_eq!(eth_sync.select_headers_to_submit(), Some(vec![&header(102)])); eth_sync.headers.headers_submitted(vec![id(102)]); // substrate reports that it has imported block #102 - eth_sync.substrate_best_header_response(id(102)); + eth_sync.target_best_header_response(id(102)); // and we have nothing to download assert_eq!(eth_sync.select_new_header_to_download(), None); @@ -259,10 +293,10 @@ mod tests { let mut eth_sync = HeadersSync::new(Default::default()); // ethereum reports best header #102 - eth_sync.ethereum_best_header_number_response(102); + eth_sync.source_best_header_number_response(102); // substrate reports that it is at block #100, but it isn't part of best chain - eth_sync.substrate_best_header_response(HeaderId(100, side_hash(100))); + eth_sync.target_best_header_response(HeaderId(100, side_hash(100))); // block #101 is downloaded first assert_eq!(eth_sync.select_new_header_to_download(), Some(101)); @@ -291,23 +325,23 @@ mod tests { eth_sync.headers.maybe_orphan_response(&id(99), true); // and we are ready to submit #100 - assert_eq!(eth_sync.headers.header(HeaderStatus::MaybeReceipts), Some(&header(100))); - eth_sync.headers.maybe_receipts_response(&id(100), false); + assert_eq!(eth_sync.headers.header(HeaderStatus::MaybeExtra), Some(&header(100))); + eth_sync.headers.maybe_extra_response(&id(100), false); assert_eq!(eth_sync.select_headers_to_submit(), Some(vec![&header(100)])); eth_sync.headers.headers_submitted(vec![id(100)]); // and we are ready to submit #101 - assert_eq!(eth_sync.headers.header(HeaderStatus::MaybeReceipts), Some(&header(101))); - eth_sync.headers.maybe_receipts_response(&id(101), false); + assert_eq!(eth_sync.headers.header(HeaderStatus::MaybeExtra), Some(&header(101))); + eth_sync.headers.maybe_extra_response(&id(101), false); assert_eq!(eth_sync.select_headers_to_submit(), Some(vec![&header(101)])); eth_sync.headers.headers_submitted(vec![id(101)]); } #[test] - fn pruning_happens_on_substrate_best_header_response() { - let mut eth_sync = HeadersSync::new(Default::default()); + fn pruning_happens_on_target_best_header_response() { + let mut eth_sync = HeadersSync::::new(Default::default()); eth_sync.params.prune_depth = 50; - eth_sync.substrate_best_header_response(id(100)); + eth_sync.target_best_header_response(id(100)); assert_eq!(eth_sync.headers.prune_border(), 50); } } diff --git a/relays/ethereum/src/sync_types.rs b/relays/ethereum/src/sync_types.rs new file mode 100644 index 0000000000..7e38a2c1fd --- /dev/null +++ b/relays/ethereum/src/sync_types.rs @@ -0,0 +1,127 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +/// Ethereum header Id. +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct HeaderId(pub Number, pub Hash); + +/// Ethereum header synchronization status. +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum HeaderStatus { + /// Header is unknown. + Unknown, + /// Header is in MaybeOrphan queue. + MaybeOrphan, + /// Header is in Orphan queue. + Orphan, + /// Header is in MaybeExtra queue. + MaybeExtra, + /// Header is in Extra queue. + Extra, + /// Header is in Ready queue. + Ready, + /// Header has been recently submitted to the Substrate runtime. + Submitted, + /// Header is known to the Substrate runtime. + Synced, +} + +/// Headers synchronization pipeline. +pub trait HeadersSyncPipeline: Clone + Copy { + /// Headers we're synching are identified by this hash. + type Hash: + Eq + Clone + Copy + + std::fmt::Debug + std::fmt::Display + + std::hash::Hash; + /// Headers we're synching are identified by this number. + type Number: + From + Ord + Clone + Copy + + std::fmt::Debug + std::fmt::Display + + std::ops::Add + std::ops::Sub + + num_traits::Saturating + + num_traits::Zero + num_traits::One; + /// Type of header that we're syncing. + type Header: std::fmt::Debug + SourceHeader; + /// Type of extra data for the header that we're receiving from the source node. + type Extra: std::fmt::Debug; + + /// Name of the headers source. + fn source_name() -> &'static str; + /// Name of the headers target. + fn target_name() -> &'static str; + /// Function used to convert from queued header to target header. + fn estimate_size(source: &QueuedHeader) -> usize; +} + +/// Header that we're receiving from source node. +pub trait SourceHeader { + /// Returns ID of header. + fn id(&self) -> HeaderId; + /// Returns ID of parent header. + fn parent_id(&self) -> HeaderId; +} + +/// Header that we're submitting to target node. +pub trait TargetHeader { + /// Size of the header in bytes. + fn size(&self) -> usize; +} + +/// Header how it's stored in the synchronization queue. +#[derive(Clone, Debug, Default)] +#[cfg_attr(test, derive(PartialEq))] +pub struct QueuedHeader { + header: P::Header, + extra: Option, +} + +impl QueuedHeader

{ + /// Creates new queued header. + pub fn new(header: P::Header) -> Self { + QueuedHeader { header, extra: None } + } + + /// Returns ID of header. + pub fn id(&self) -> HeaderId { + self.header.id() + } + + /// Returns ID of parent header. + pub fn parent_id(&self) -> HeaderId { + self.header.parent_id() + } + + /// Returns reference to header. + pub fn header(&self) -> &P::Header { + &self.header + } + + /// Returns reference to associated extra data. + pub fn extra(&self) -> &Option { + &self.extra + } + + /// Extract header and extra from self. + pub fn extract(self) -> (P::Header, Option) { + (self.header, self.extra) + } + + /// Set associated extra data. + pub fn set_extra(mut self, extra: P::Extra) -> Self { + self.extra = Some(extra); + self + } +} diff --git a/relays/ethereum/src/utils.rs b/relays/ethereum/src/utils.rs index 9c82a93291..b1cbdb2d88 100644 --- a/relays/ethereum/src/utils.rs +++ b/relays/ethereum/src/utils.rs @@ -14,6 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +use crate::sync_types::HeadersSyncPipeline; +use futures::future::FutureExt; +use num_traits::Saturating; + /// Error type that can signal connection errors. pub trait MaybeConnectionError { /// Returns true if error (maybe) represents connection error. @@ -65,17 +69,18 @@ pub fn process_future_result( } /// Print synchronization progress. -pub fn print_sync_progress( - progress_context: (std::time::Instant, Option, Option), - eth_sync: &crate::ethereum_sync::HeadersSync, -) -> (std::time::Instant, Option, Option) { +pub fn print_sync_progress( + progress_context: (std::time::Instant, Option, Option), + eth_sync: &crate::sync::HeadersSync

, +) -> (std::time::Instant, Option, Option) { let (prev_time, prev_best_header, prev_target_header) = progress_context; let now_time = std::time::Instant::now(); let (now_best_header, now_target_header) = eth_sync.status(); let need_update = now_time - prev_time > std::time::Duration::from_secs(10) || match (prev_best_header, now_best_header) { - (Some(prev_best_header), Some(now_best_header)) => now_best_header.0.saturating_sub(prev_best_header) > 10, + (Some(prev_best_header), Some(now_best_header)) => + now_best_header.0.saturating_sub(prev_best_header) > 10.into(), _ => false, }; if !need_update { From 33e9e31f3cb94fe944d427d1a018f275e914de8a Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 7 Apr 2020 14:09:14 +0300 Subject: [PATCH 10/92] continue extracting --- relays/ethereum/src/ethereum_sync_loop.rs | 398 ++++++--------------- relays/ethereum/src/headers.rs | 83 +++-- relays/ethereum/src/main.rs | 1 + relays/ethereum/src/substrate_client.rs | 4 +- relays/ethereum/src/substrate_sync_loop.rs | 115 ++++-- relays/ethereum/src/sync.rs | 7 +- relays/ethereum/src/sync_loop.rs | 388 ++++++++++++++++++++ relays/ethereum/src/sync_types.rs | 7 +- relays/ethereum/src/utils.rs | 4 +- 9 files changed, 657 insertions(+), 350 deletions(-) create mode 100644 relays/ethereum/src/sync_loop.rs diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index e160ac74ca..aec6fa4b7d 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -15,11 +15,13 @@ // along with Parity Bridges Common. If not, see . use crate::ethereum_client; +use crate::ethereum_types::{EthereumHeaderId, EthereumHeadersSyncPipeline, Header, QueuedEthereumHeader, Receipt}; use crate::substrate_client; use crate::sync::HeadersSyncParams; -use crate::sync_types::HeaderStatus as EthereumHeaderStatus; -use crate::utils::{delay, interval, print_sync_progress, process_future_result}; -use futures::{future::FutureExt, stream::StreamExt}; +use crate::sync_loop::{SourceClient, TargetClient}; +use std::{future::Future, pin::Pin}; +use futures::future::FutureExt; +pub use web3::types::H256; // TODO: when SharedClient will be available, switch to Substrate headers subscription // (because we do not need old Substrate headers) @@ -28,7 +30,7 @@ use futures::{future::FutureExt, stream::StreamExt}; const ETHEREUM_TICK_INTERVAL_MS: u64 = 10_000; /// Interval (in ms) at which we check new Substrate blocks. const SUBSTRATE_TICK_INTERVAL_MS: u64 = 5_000; -/// When we submit Ethereum headers to Substrate runtime, but see no updates of best +/*/// When we submit Ethereum headers to Substrate runtime, but see no updates of best /// Ethereum block known to Substrate runtime during STALL_SYNC_TIMEOUT_MS milliseconds, /// we consider that our headers are rejected because there has been reorg in Substrate. /// This reorg could invalidate our knowledge about sync process (i.e. we have asked if @@ -42,7 +44,7 @@ const STALL_SYNC_TIMEOUT_MS: u64 = 30_000; /// Delay (in milliseconds) after connection-related error happened before we'll try /// reconnection again. const CONNECTION_ERROR_DELAY_MS: u64 = 10_000; - +*/ /// Ethereum synchronization parameters. pub struct EthereumSyncParams { /// Ethereum RPC host. @@ -84,306 +86,108 @@ impl Default for EthereumSyncParams { } } -/// Run Ethereum headers synchronization. -pub fn run(params: EthereumSyncParams) { - let mut local_pool = futures::executor::LocalPool::new(); - let mut progress_context = (std::time::Instant::now(), None, None); - - local_pool.run_until(async move { - let eth_uri = format!("http://{}:{}", params.eth_host, params.eth_port); - let sub_uri = format!("http://{}:{}", params.sub_host, params.sub_port); - let sub_signer = params.sub_signer.clone(); - - let mut eth_sync = crate::sync::HeadersSync::new(params.sync_params); - let mut stall_countdown = None; - - let mut eth_maybe_client = None; - let mut eth_best_block_number_required = false; - let eth_best_block_number_future = ethereum_client::best_block_number(ethereum_client::client(ð_uri)).fuse(); - let eth_new_header_future = futures::future::Fuse::terminated(); - let eth_orphan_header_future = futures::future::Fuse::terminated(); - let eth_receipts_future = futures::future::Fuse::terminated(); - let eth_go_offline_future = futures::future::Fuse::terminated(); - let eth_tick_stream = interval(ETHEREUM_TICK_INTERVAL_MS).fuse(); - - let mut sub_maybe_client = None; - let mut sub_best_block_required = false; - let sub_best_block_future = - substrate_client::best_ethereum_block(substrate_client::client(&sub_uri)).fuse(); - let sub_receipts_check_future = futures::future::Fuse::terminated(); - let sub_existence_status_future = futures::future::Fuse::terminated(); - let sub_submit_header_future = futures::future::Fuse::terminated(); - let sub_go_offline_future = futures::future::Fuse::terminated(); - let sub_tick_stream = interval(SUBSTRATE_TICK_INTERVAL_MS).fuse(); - - futures::pin_mut!( - eth_best_block_number_future, - eth_new_header_future, - eth_orphan_header_future, - eth_receipts_future, - eth_go_offline_future, - eth_tick_stream, - sub_best_block_future, - sub_receipts_check_future, - sub_existence_status_future, - sub_submit_header_future, - sub_go_offline_future, - sub_tick_stream - ); - - loop { - futures::select! { - (eth_client, eth_best_block_number) = eth_best_block_number_future => { - eth_best_block_number_required = false; - - process_future_result( - &mut eth_maybe_client, - eth_client, - eth_best_block_number, - |eth_best_block_number| eth_sync.source_best_header_number_response(eth_best_block_number), - &mut eth_go_offline_future, - |eth_client| delay(CONNECTION_ERROR_DELAY_MS, eth_client), - "Error retrieving best header number from Ethereum number", - ); - }, - (eth_client, eth_new_header) = eth_new_header_future => { - process_future_result( - &mut eth_maybe_client, - eth_client, - eth_new_header, - |eth_new_header| eth_sync.headers_mut().header_response(eth_new_header), - &mut eth_go_offline_future, - |eth_client| delay(CONNECTION_ERROR_DELAY_MS, eth_client), - "Error retrieving header from Ethereum node", - ); - }, - (eth_client, eth_orphan_header) = eth_orphan_header_future => { - process_future_result( - &mut eth_maybe_client, - eth_client, - eth_orphan_header, - |eth_orphan_header| eth_sync.headers_mut().header_response(eth_orphan_header), - &mut eth_go_offline_future, - |eth_client| delay(CONNECTION_ERROR_DELAY_MS, eth_client), - "Error retrieving orphan header from Ethereum node", - ); - }, - (eth_client, eth_receipts) = eth_receipts_future => { - process_future_result( - &mut eth_maybe_client, - eth_client, - eth_receipts, - |(header, receipts)| eth_sync.headers_mut().extra_response(&header, receipts), - &mut eth_go_offline_future, - |eth_client| delay(CONNECTION_ERROR_DELAY_MS, eth_client), - "Error retrieving transactions receipts from Ethereum node", - ); - }, - eth_client = eth_go_offline_future => { - eth_maybe_client = Some(eth_client); - }, - _ = eth_tick_stream.next() => { - if eth_sync.is_almost_synced() { - eth_best_block_number_required = true; - } - }, - (sub_client, sub_best_block) = sub_best_block_future => { - sub_best_block_required = false; - - process_future_result( - &mut sub_maybe_client, - sub_client, - sub_best_block, - |sub_best_block| { - let head_updated = eth_sync.target_best_header_response(sub_best_block); - match head_updated { - // IF head is updated AND there are still our transactions: - // => restart stall countdown timer - true if eth_sync.headers().headers_in_status(EthereumHeaderStatus::Submitted) != 0 => - stall_countdown = Some(std::time::Instant::now()), - // IF head is updated AND there are no our transactions: - // => stop stall countdown timer - true => stall_countdown = None, - // IF head is not updated AND stall countdown is not yet completed - // => do nothing - false if stall_countdown - .map(|stall_countdown| std::time::Instant::now() - stall_countdown < - std::time::Duration::from_millis(STALL_SYNC_TIMEOUT_MS)) - .unwrap_or(true) - => (), - // IF head is not updated AND stall countdown has completed - // => restart sync - false => { - log::info!( - target: "bridge", - "Possible Substrate fork detected. Restarting Ethereum headers synchronization.", - ); - stall_countdown = None; - eth_sync.restart(); - }, - } - }, - &mut sub_go_offline_future, - |sub_client| delay(CONNECTION_ERROR_DELAY_MS, sub_client), - "Error retrieving best known header from Substrate node", - ); - }, - (sub_client, sub_existence_status) = sub_existence_status_future => { - process_future_result( - &mut sub_maybe_client, - sub_client, - sub_existence_status, - |(sub_header, sub_existence_status)| eth_sync - .headers_mut() - .maybe_orphan_response(&sub_header, sub_existence_status), - &mut sub_go_offline_future, - |sub_client| delay(CONNECTION_ERROR_DELAY_MS, sub_client), - "Error retrieving existence status from Substrate node", - ); - }, - (sub_client, sub_submit_header_result) = sub_submit_header_future => { - process_future_result( - &mut sub_maybe_client, - sub_client, - sub_submit_header_result, - |(_, submitted_headers)| eth_sync.headers_mut().headers_submitted(submitted_headers), - &mut sub_go_offline_future, - |sub_client| delay(CONNECTION_ERROR_DELAY_MS, sub_client), - "Error submitting headers to Substrate node", - ); - }, - (sub_client, sub_receipts_check_result) = sub_receipts_check_future => { - // we can minimize number of receipts_check calls by checking header - // logs bloom here, but it may give us false positives (when authorities - // source is contract, we never need any logs) - process_future_result( - &mut sub_maybe_client, - sub_client, - sub_receipts_check_result, - |(header, receipts_check_result)| eth_sync - .headers_mut() - .maybe_extra_response(&header, receipts_check_result), - &mut sub_go_offline_future, - |sub_client| delay(CONNECTION_ERROR_DELAY_MS, sub_client), - "Error retrieving receipts requirement from Substrate node", - ); - }, - sub_client = sub_go_offline_future => { - sub_maybe_client = Some(sub_client); - }, - _ = sub_tick_stream.next() => { - sub_best_block_required = true; - }, - } - - // print progress - progress_context = print_sync_progress(progress_context, ð_sync); - - // if client is available: wait, or call Substrate RPC methods - if let Some(sub_client) = sub_maybe_client.take() { - // the priority is to: - // 1) get best block - it stops us from downloading/submitting new blocks + we call it rarely; - // 2) check transactions receipts - it stops us from downloading/submitting new blocks; - // 3) check existence - it stops us from submitting new blocks; - // 4) submit header - - if sub_best_block_required { - log::debug!(target: "bridge", "Asking Substrate about best block"); - sub_best_block_future.set(substrate_client::best_ethereum_block(sub_client).fuse()); - } else if let Some(header) = eth_sync.headers().header(EthereumHeaderStatus::MaybeExtra) { - log::debug!( - target: "bridge", - "Checking if header submission requires receipts: {:?}", - header.id(), - ); +/// Ethereum client as headers source. +struct EthereumHeadersSource { + /// Ethereum node client. + client: ethereum_client::Client, +} - let header = header.clone(); - sub_receipts_check_future - .set(substrate_client::ethereum_receipts_required(sub_client, header).fuse()); - } else if let Some(header) = eth_sync.headers().header(EthereumHeaderStatus::MaybeOrphan) { - // for MaybeOrphan we actually ask for parent' header existence - let parent_id = header.parent_id(); +impl SourceClient for EthereumHeadersSource { + type Error = ethereum_client::Error; + type BestBlockNumberFuture = Pin)>>>; + type HeaderByHashFuture = Pin)>>>; + type HeaderByNumberFuture = Pin)>>>; + type HeaderExtraFuture = Pin), Self::Error>)>>>; + + fn best_block_number(self) -> Self::BestBlockNumberFuture { + ethereum_client::best_block_number(self.client) + .map(|(client, result)| (EthereumHeadersSource { client }, result)) + .boxed() + } - log::debug!( - target: "bridge", - "Asking Substrate node for existence of: {:?}", - parent_id, - ); + fn header_by_hash(self, hash: H256) -> Self::HeaderByHashFuture { + ethereum_client::header_by_hash(self.client, hash) + .map(|(client, result)| (EthereumHeadersSource { client }, result)) + .boxed() + } - sub_existence_status_future - .set(substrate_client::ethereum_header_known(sub_client, parent_id).fuse()); - } else if let Some(headers) = eth_sync.select_headers_to_submit() { - let ids = match headers.len() { - 1 => format!("{:?}", headers[0].id()), - 2 => format!("[{:?}, {:?}]", headers[0].id(), headers[1].id()), - len => format!("[{:?} ... {:?}]", headers[0].id(), headers[len - 1].id()), - }; - log::debug!( - target: "bridge", - "Submitting {} header(s) to Substrate node: {:?}", - headers.len(), - ids, - ); + fn header_by_number(self, number: u64) -> Self::HeaderByNumberFuture { + ethereum_client::header_by_number(self.client, number) + .map(|(client, result)| (EthereumHeadersSource { client }, result)) + .boxed() + } - let headers = headers.into_iter().cloned().collect(); - sub_submit_header_future.set( - substrate_client::submit_ethereum_headers(sub_client, sub_signer.clone(), headers).fuse() - ); + fn header_extra(self, id: EthereumHeaderId, header: &Header) -> Self::HeaderExtraFuture { + ethereum_client::transactions_receipts(self.client, id, header.transactions.clone()) + .map(|(client, result)| (EthereumHeadersSource { client }, result)) + .boxed() + } +} - // remember that we have submitted some headers - if stall_countdown.is_none() { - stall_countdown = Some(std::time::Instant::now()); - } - } else { - sub_maybe_client = Some(sub_client); - } - } +/// Substrate client as Ethereum headers target. +struct SubstrateHeadersTarget { + /// Substrate node client. + client: substrate_client::Client, + /// Substrate transactions signer. + signer: sp_core::sr25519::Pair, +} - // if client is available: wait, or call Ethereum RPC methods - if let Some(eth_client) = eth_maybe_client.take() { - // the priority is to: - // 1) get best block - it stops us from downloading new blocks + we call it rarely; - // 2) check transactions receipts - it stops us from downloading/submitting new blocks; - // 3) check existence - it stops us from submitting new blocks; - // 4) submit header +impl TargetClient for SubstrateHeadersTarget { + type Error = substrate_client::Error; + type BestHeaderIdFuture = Pin)>>>; + type IsKnownHeaderFuture = Pin)>>>; + type RequiresExtraFuture = Pin)>>>; + type SubmitHeadersFuture = Pin, Self::Error>)>>>; + + fn best_header_id(self) -> Self::BestHeaderIdFuture { + let signer = self.signer; + substrate_client::best_ethereum_block(self.client) + .map(move |(client, result)| (SubstrateHeadersTarget { client, signer }, result)) + .boxed() + } - if eth_best_block_number_required { - log::debug!(target: "bridge", "Asking Ethereum node about best block number"); - eth_best_block_number_future.set(ethereum_client::best_block_number(eth_client).fuse()); - } else if let Some(header) = eth_sync.headers().header(EthereumHeaderStatus::Extra) { - let id = header.id(); - log::debug!( - target: "bridge", - "Retrieving receipts for header: {:?}", - id, - ); - eth_receipts_future.set( - ethereum_client::transactions_receipts(eth_client, id, header.header().transactions.clone()) - .fuse(), - ); - } else if let Some(header) = eth_sync.headers().header(EthereumHeaderStatus::Orphan) { - // for Orphan we actually ask for parent' header - let parent_id = header.parent_id(); + fn is_known_header(self, id: EthereumHeaderId) -> Self::IsKnownHeaderFuture { + let signer = self.signer; + substrate_client::ethereum_header_known(self.client, id) + .map(move |(client, result)| (SubstrateHeadersTarget { client, signer }, result)) + .boxed() + } - log::debug!( - target: "bridge", - "Going to download orphan header from Ethereum node: {:?}", - parent_id, - ); + fn requires_extra(self, header: &QueuedEthereumHeader) -> Self::RequiresExtraFuture { + // we can minimize number of receipts_check calls by checking header + // logs bloom here, but it may give us false positives (when authorities + // source is contract, we never need any logs) + let signer = self.signer; + substrate_client::ethereum_receipts_required(self.client, header.clone()) + .map(move |(client, result)| (SubstrateHeadersTarget { client, signer }, result)) + .boxed() + } - eth_orphan_header_future.set(ethereum_client::header_by_hash(eth_client, parent_id.1).fuse()); - } else if let Some(id) = eth_sync.select_new_header_to_download() { - log::debug!( - target: "bridge", - "Going to download new header from Ethereum node: {:?}", - id, - ); + fn submit_headers(self, headers: Vec) -> Self::SubmitHeadersFuture { + let signer = self.signer; + substrate_client::submit_ethereum_headers(self.client, signer.clone(), headers) + .map(move |(client, result)| ( + SubstrateHeadersTarget { client, signer }, + result.map(|(_, submitted_headers)| submitted_headers), // TODO: print tx hashes??? + )) + .boxed() + } +} - eth_new_header_future.set(ethereum_client::header_by_number(eth_client, id).fuse()); - } else { - eth_maybe_client = Some(eth_client); - } - } - } - }); +/// Run Ethereum headers synchronization. +pub fn run(params: EthereumSyncParams) { + let eth_uri = format!("http://{}:{}", params.eth_host, params.eth_port); + let eth_client = ethereum_client::client(ð_uri); + + let sub_uri = format!("http://{}:{}", params.sub_host, params.sub_port); + let sub_client = substrate_client::client(&sub_uri); + let sub_signer = params.sub_signer; + + crate::sync_loop::run( + EthereumHeadersSource { client: eth_client }, + ETHEREUM_TICK_INTERVAL_MS, + SubstrateHeadersTarget { client: sub_client, signer: sub_signer }, + SUBSTRATE_TICK_INTERVAL_MS, + params.sync_params, + ); } diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index dd772bcc13..97fe8fb01b 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -35,9 +35,23 @@ type KnownHeaders

= BTreeMap< >, >; +/// Extra data mode. +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum ExtraMode { + /// Extra data only affects single header. When extra data for header + /// is provided, we may submit this header to the target node. + PerHeader, + /// Extra data affects header and all its ancestors. When extra data + /// for header is provided, we may submit this header and all unsubmitted + /// ancestors (if they're waiting for extra data) to the target node. + PerChain, +} + /// Ethereum headers queue. #[derive(Debug)] pub struct QueuedHeaders { + /// How we are trating extra data. + extra_mode: ExtraMode, /// Headers that are received from source node, but we (native sync code) have /// never seen their parents. So we need to check if we can/should submit this header. maybe_orphan: HeadersQueue

, @@ -65,8 +79,9 @@ pub struct QueuedHeaders { impl QueuedHeaders

{ /// Returns new QueuedHeaders. - pub fn new() -> Self { + pub fn new(extra_mode: ExtraMode) -> Self { QueuedHeaders { + extra_mode, maybe_orphan: HeadersQueue::new(), orphan: HeadersQueue::new(), maybe_extra: HeadersQueue::new(), @@ -333,7 +348,8 @@ impl QueuedHeaders

{ /// Receive extra from source node. pub fn extra_response(&mut self, id: &HeaderId, extra: P::Extra) { - move_header( + // move header itself from extra to ready queue + let mut parent_id = move_header( &mut self.extra, &mut self.ready, &mut self.known_headers, @@ -341,6 +357,20 @@ impl QueuedHeaders

{ id, |header| header.set_extra(extra), ); + + // if extra affects all ancestors, move them from extra to ready queue + if self.extra_mode == ExtraMode::PerChain { + while let Some(current_id) = parent_id { + parent_id = move_header( + &mut self.extra, + &mut self.ready, + &mut self.known_headers, + HeaderStatus::Ready, + ¤t_id, + |header| header, + ); + } + } } /// When header is submitted to target node. @@ -413,6 +443,8 @@ fn remove_header( } /// Move header from source to destination queue. +/// +/// Returns ID of parent header, if header has been moved, or None otherwise. fn move_header( source_queue: &mut HeadersQueue

, destination_queue: &mut HeadersQueue

, @@ -420,12 +452,13 @@ fn move_header( destination_status: HeaderStatus, id: &HeaderId, prepare: impl FnOnce(QueuedHeader

) -> QueuedHeader

, -) { +) -> Option> { let header = match remove_header(source_queue, id) { Some(header) => prepare(header), - None => return, + None => return None, }; + let parent_id = header.header().parent_id(); known_headers.entry(id.0).or_default().insert(id.1, destination_status); destination_queue.entry(id.0).or_default().insert(id.1, header); @@ -436,6 +469,8 @@ fn move_header( id, destination_status, ); + + Some(parent_id) } /// Move all descendant headers from the source to destination queue. @@ -572,7 +607,7 @@ pub(crate) mod tests { #[test] fn total_headers_works() { // total headers just sums up number of headers in every queue - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue .maybe_orphan .entry(1) @@ -609,7 +644,7 @@ pub(crate) mod tests { #[test] fn best_queued_number_works() { // initially there are headers in MaybeOrphan queue only - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue .maybe_orphan .entry(1) @@ -659,7 +694,7 @@ pub(crate) mod tests { #[test] fn status_works() { // all headers are unknown initially - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); assert_eq!(queue.status(&id(10)), HeaderStatus::Unknown); // and status is read from the KnownHeaders queue @@ -673,7 +708,7 @@ pub(crate) mod tests { #[test] fn header_works() { // initially we have oldest header #10 - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue.maybe_orphan.entry(10).or_default().insert(hash(1), header(100)); assert_eq!( queue.header(HeaderStatus::MaybeOrphan).unwrap().header().hash.unwrap(), @@ -696,7 +731,7 @@ pub(crate) mod tests { #[test] fn header_response_works() { // when parent is Synced, we insert to MaybeExtra - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue .known_headers .entry(100) @@ -706,7 +741,7 @@ pub(crate) mod tests { assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeExtra); // when parent is Ready, we insert to MaybeExtra - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue .known_headers .entry(100) @@ -716,7 +751,7 @@ pub(crate) mod tests { assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeExtra); // when parent is Receipts, we insert to MaybeExtra - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue .known_headers .entry(100) @@ -726,7 +761,7 @@ pub(crate) mod tests { assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeExtra); // when parent is MaybeExtra, we insert to MaybeExtra - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue .known_headers .entry(100) @@ -736,7 +771,7 @@ pub(crate) mod tests { assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeExtra); // when parent is Orphan, we insert to Orphan - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue .known_headers .entry(100) @@ -746,7 +781,7 @@ pub(crate) mod tests { assert_eq!(queue.status(&id(101)), HeaderStatus::Orphan); // when parent is MaybeOrphan, we insert to MaybeOrphan - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue .known_headers .entry(100) @@ -756,7 +791,7 @@ pub(crate) mod tests { assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeOrphan); // when parent is unknown, we insert to MaybeOrphan - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue.header_response(header(101).header().clone()); assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeOrphan); } @@ -770,7 +805,7 @@ pub(crate) mod tests { // #98 in MaybeExtra // #97 in Receipts // #96 in Ready - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue .known_headers .entry(100) @@ -827,7 +862,7 @@ pub(crate) mod tests { // #101 in Orphan // #102 in MaybeOrphan // #103 in Orphan - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue .known_headers .entry(101) @@ -869,7 +904,7 @@ pub(crate) mod tests { // #102 in MaybeOrphan // and we have asked for MaybeOrphan status of #100.parent (i.e. #99) // and the response is: YES, #99 is known to the Substrate runtime - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue .known_headers .entry(100) @@ -914,7 +949,7 @@ pub(crate) mod tests { // #101 in MaybeOrphan // and we have asked for MaybeOrphan status of #100.parent (i.e. #99) // and the response is: NO, #99 is NOT known to the Substrate runtime - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue .known_headers .entry(100) @@ -946,7 +981,7 @@ pub(crate) mod tests { #[test] fn positive_maybe_extra_response_works() { - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue .known_headers .entry(100) @@ -965,7 +1000,7 @@ pub(crate) mod tests { #[test] fn negative_maybe_extra_response_works() { - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue .known_headers .entry(100) @@ -984,7 +1019,7 @@ pub(crate) mod tests { #[test] fn receipts_response_works() { - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue .known_headers .entry(100) @@ -999,7 +1034,7 @@ pub(crate) mod tests { #[test] fn header_submitted_works() { - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue .known_headers .entry(100) @@ -1013,7 +1048,7 @@ pub(crate) mod tests { #[test] fn prune_works() { - let mut queue = QueuedHeaders::::new(); + let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); queue .known_headers .entry(104) diff --git a/relays/ethereum/src/main.rs b/relays/ethereum/src/main.rs index 7668d7c15f..7681b8dc3a 100644 --- a/relays/ethereum/src/main.rs +++ b/relays/ethereum/src/main.rs @@ -24,6 +24,7 @@ mod substrate_client; mod substrate_sync_loop; mod substrate_types; mod sync; +mod sync_loop; mod sync_types; mod utils; diff --git a/relays/ethereum/src/substrate_client.rs b/relays/ethereum/src/substrate_client.rs index 6fbe009344..a95bfcaa91 100644 --- a/relays/ethereum/src/substrate_client.rs +++ b/relays/ethereum/src/substrate_client.rs @@ -16,7 +16,7 @@ use crate::ethereum_types::{Bytes, EthereumHeaderId, H256, QueuedEthereumHeader}; use crate::substrate_types::{into_substrate_ethereum_header, into_substrate_ethereum_receipts, TransactionHash}; -use crate::sync_types::HeaderId; +use crate::sync_types::{HeaderId, SourceHeader}; use crate::utils::MaybeConnectionError; use codec::{Decode, Encode}; use jsonrpsee::common::Params; @@ -84,7 +84,7 @@ pub async fn ethereum_receipts_required( client: Client, header: QueuedEthereumHeader, ) -> (Client, Result<(EthereumHeaderId, bool), Error>) { - let id = header.id(); + let id = header.header().id(); let header = into_substrate_ethereum_header(header.header()); let encoded_header = header.encode(); let (client, receipts_required) = call_rpc( diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index 53d4d23477..7d860ebc73 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -16,6 +16,7 @@ use crate::ethereum_client; use crate::substrate_client; +use crate::sync::HeadersSyncParams; use futures::future::FutureExt; use parity_crypto::publickey::KeyPair; @@ -31,17 +32,8 @@ pub struct SubstrateSyncParams { pub sub_host: String, /// Substrate RPC port. pub sub_port: u16, - /// Maximal number of ethereum headers to pre-download. - pub max_future_headers_to_download: usize, - /// Maximal number of active (we believe) submit header transactions. - pub max_headers_in_submitted_status: usize, - /// Maximal number of headers in single submit request. - pub max_headers_in_single_submit: usize, - /// Maximal total headers size in single submit request. - pub max_headers_size_in_single_submit: usize, - /// We only may store and accept (from Ethereum node) headers that have - /// number >= than best_substrate_header.number - prune_depth. - pub prune_depth: u64, + /// Synchronization parameters. + pub sync_params: HeadersSyncParams, } impl Default for SubstrateSyncParams { @@ -59,32 +51,113 @@ impl Default for SubstrateSyncParams { ).expect("secret is hardcoded, thus valid; qed"), sub_host: "localhost".into(), sub_port: 9933, - max_future_headers_to_download: 128, - max_headers_in_submitted_status: 128, - max_headers_in_single_submit: 32, - max_headers_size_in_single_submit: 131_072, - prune_depth: 4096, + sync_params: Default::default(), } } } /// Run Substrate headers synchronization. pub fn run(params: SubstrateSyncParams) { - let mut local_pool = futures::executor::LocalPool::new(); -// let mut progress_context = (std::time::Instant::now(), None, None); +/* let mut local_pool = futures::executor::LocalPool::new(); + let mut progress_context = (std::time::Instant::now(), None, None); local_pool.run_until(async move { let eth_uri = format!("http://{}:{}", params.eth_host, params.eth_port); let sub_uri = format!("http://{}:{}", params.sub_host, params.sub_port); - let _eth_best_block_number_future = ethereum_client::best_block_number(ethereum_client::client(ð_uri)).fuse(); + let mut sub_sync = crate::sync::HeadersSync::new(params.sync_params); + let mut stall_countdown = None; - let _sub_best_block_future = + let mut eth_maybe_client = None; + let mut eth_best_block_number_required = false; + let eth_best_block_number_future = ethereum_client::best_block_number(ethereum_client::client(ð_uri)).fuse(); + let eth_tick_stream = interval(ETHEREUM_TICK_INTERVAL_MS).fuse(); + + let mut sub_maybe_client = None; + let mut sub_best_block_required = false; + let sub_best_block_future = substrate_client::best_ethereum_block(substrate_client::client(&sub_uri)).fuse(); + let sub_tick_stream = interval(SUBSTRATE_TICK_INTERVAL_MS).fuse(); + + futures::pin_mut!( + eth_best_block_number_future, + eth_tick_stream, + sub_best_block_future, + sub_tick_stream + ); loop { + futures::select! { + (eth_client, eth_best_block_number) = eth_best_block_number_future => { + eth_best_block_number_required = false; + + process_future_result( + &mut eth_maybe_client, + eth_client, + eth_best_block_number, + |eth_best_block_number| eth_sync.source_best_header_number_response(eth_best_block_number), + &mut eth_go_offline_future, + |eth_client| delay(CONNECTION_ERROR_DELAY_MS, eth_client), + "Error retrieving best header number from Ethereum number", + ); + }, + eth_client = eth_go_offline_future => { + eth_maybe_client = Some(eth_client); + }, + _ = eth_tick_stream.next() => { + if eth_sync.is_almost_synced() { + eth_best_block_number_required = true; + } + }, + (sub_client, sub_best_block) = sub_best_block_future => { + sub_best_block_required = false; + process_future_result( + &mut sub_maybe_client, + sub_client, + sub_best_block, + |sub_best_block| { + let head_updated = eth_sync.target_best_header_response(sub_best_block); + match head_updated { + // IF head is updated AND there are still our transactions: + // => restart stall countdown timer + true if eth_sync.headers().headers_in_status(EthereumHeaderStatus::Submitted) != 0 => + stall_countdown = Some(std::time::Instant::now()), + // IF head is updated AND there are no our transactions: + // => stop stall countdown timer + true => stall_countdown = None, + // IF head is not updated AND stall countdown is not yet completed + // => do nothing + false if stall_countdown + .map(|stall_countdown| std::time::Instant::now() - stall_countdown < + std::time::Duration::from_millis(STALL_SYNC_TIMEOUT_MS)) + .unwrap_or(true) + => (), + // IF head is not updated AND stall countdown has completed + // => restart sync + false => { + log::info!( + target: "bridge", + "Possible Substrate fork detected. Restarting Ethereum headers synchronization.", + ); + stall_countdown = None; + eth_sync.restart(); + }, + } + }, + &mut sub_go_offline_future, + |sub_client| delay(CONNECTION_ERROR_DELAY_MS, sub_client), + "Error retrieving best known header from Substrate node", + ); + }, + sub_client = sub_go_offline_future => { + sub_maybe_client = Some(sub_client); + }, + _ = sub_tick_stream.next() => { + sub_best_block_required = true; + }, + } } - }); + });*/ } diff --git a/relays/ethereum/src/sync.rs b/relays/ethereum/src/sync.rs index 7e2f901684..5d1e102fde 100644 --- a/relays/ethereum/src/sync.rs +++ b/relays/ethereum/src/sync.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::headers::QueuedHeaders; +use crate::headers::{ExtraMode, QueuedHeaders}; use crate::sync_types::{HeaderId, HeaderStatus, HeadersSyncPipeline, QueuedHeader}; use num_traits::{One, Saturating}; @@ -32,6 +32,8 @@ pub struct HeadersSyncParams { /// We only may store and accept (from Ethereum node) headers that have /// number >= than best_substrate_header.number - prune_depth. pub prune_depth: u32, + /// Extra data synchronization mode. + pub extra_mode: ExtraMode, } /// Headers synchronization context. @@ -51,10 +53,10 @@ impl HeadersSync

{ /// Creates new headers synchronizer. pub fn new(params: HeadersSyncParams) -> Self { HeadersSync { + headers: QueuedHeaders::new(params.extra_mode), params, source_best_number: None, target_best_header: None, - headers: QueuedHeaders::new(), } } @@ -193,6 +195,7 @@ impl Default for HeadersSyncParams { max_headers_in_single_submit: 32, max_headers_size_in_single_submit: 131_072, prune_depth: 4096, + extra_mode: ExtraMode::PerHeader, } } } diff --git a/relays/ethereum/src/sync_loop.rs b/relays/ethereum/src/sync_loop.rs new file mode 100644 index 0000000000..a8b75dfac6 --- /dev/null +++ b/relays/ethereum/src/sync_loop.rs @@ -0,0 +1,388 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +use crate::sync::HeadersSyncParams; +use crate::sync_types::{HeadersSyncPipeline, HeaderId, HeaderStatus, QueuedHeader}; +use crate::utils::{MaybeConnectionError, delay, interval, print_sync_progress, process_future_result}; +use std::future::Future; +use futures::{future::FutureExt, stream::StreamExt}; + +/// When we submit Ethereum headers to Substrate runtime, but see no updates of best +/// Ethereum block known to Substrate runtime during STALL_SYNC_TIMEOUT_MS milliseconds, +/// we consider that our headers are rejected because there has been reorg in Substrate. +/// This reorg could invalidate our knowledge about sync process (i.e. we have asked if +/// HeaderA is known to Substrate, but then reorg happened and the answer is different +/// now) => we need to reset sync. +/// The other option is to receive **EVERY** best Substrate header and check if it is +/// direct child of previous best header. But: (1) subscription doesn't guarantee that +/// the subscriber will receive every best header (2) reorg won't always lead to sync +/// stall and restart is a heavy operation (we forget all in-memory headers). +const STALL_SYNC_TIMEOUT_MS: u64 = 30_000; +/// Delay (in milliseconds) after connection-related error happened before we'll try +/// reconnection again. +const CONNECTION_ERROR_DELAY_MS: u64 = 10_000; + +/// Source client trait. +pub trait SourceClient: Sized { + /// Type of error this clients returns. + type Error: std::fmt::Debug + MaybeConnectionError; + /// Future that returns best block number. + type BestBlockNumberFuture: Future)>; + /// Future that returns header by hash. + type HeaderByHashFuture: Future)>; + /// Future that returns header by number. + type HeaderByNumberFuture: Future)>; + /// Future that returns extra data associated with header. + type HeaderExtraFuture: Future, P::Extra), Self::Error>)>; + + /// Get best block number. + fn best_block_number(self) -> Self::BestBlockNumberFuture; + /// Get header by hash. + fn header_by_hash(self, hash: P::Hash) -> Self::HeaderByHashFuture; + /// Get canonical header by number. + fn header_by_number(self, number: P::Number) -> Self::HeaderByNumberFuture; + /// Get extra data by header hash. + fn header_extra(self, id: HeaderId, header: &P::Header) -> Self::HeaderExtraFuture; +} + +/// Target client trait. +pub trait TargetClient: Sized { + /// Type of error this clients returns. + type Error: std::fmt::Debug + MaybeConnectionError; + /// Future that returns best header id. + type BestHeaderIdFuture: Future, Self::Error>)>; + /// Future that returns known header check result. + type IsKnownHeaderFuture: Future, bool), Self::Error>)>; + /// Future that returns extra check result. + type RequiresExtraFuture: Future, bool), Self::Error>)>; + /// Future that returns header submission result. + type SubmitHeadersFuture: Future>, Self::Error>)>; + + /// Returns ID of best header known to the target node. + fn best_header_id(self) -> Self::BestHeaderIdFuture; + /// Returns true if header is known to the target node. + fn is_known_header(self, id: HeaderId) -> Self::IsKnownHeaderFuture; + /// Returns true if header requires extra data to be submitted. + fn requires_extra(self, header: &QueuedHeader

) -> Self::RequiresExtraFuture; + /// Submit headers. + fn submit_headers(self, headers: Vec>) -> Self::SubmitHeadersFuture; +} + +/// Run headers synchronization. +pub fn run( + source_client: impl SourceClient

, + source_tick_ms: u64, + target_client: impl TargetClient

, + target_tick_ms: u64, + sync_params: HeadersSyncParams, +) { + let mut local_pool = futures::executor::LocalPool::new(); + let mut progress_context = (std::time::Instant::now(), None, None); + + local_pool.run_until(async move { + let mut sync = crate::sync::HeadersSync::

::new(sync_params); + let mut stall_countdown = None; + + let mut source_maybe_client = None; + let mut source_best_block_number_required = false; + let source_best_block_number_future = source_client.best_block_number().fuse(); + let source_new_header_future = futures::future::Fuse::terminated(); + let source_orphan_header_future = futures::future::Fuse::terminated(); + let source_extra_future = futures::future::Fuse::terminated(); + let source_go_offline_future = futures::future::Fuse::terminated(); + let source_tick_stream = interval(source_tick_ms).fuse(); + + let mut target_maybe_client = None; + let mut target_best_block_required = false; + let target_best_block_future = target_client.best_header_id().fuse(); + let target_extra_check_future = futures::future::Fuse::terminated(); + let target_existence_status_future = futures::future::Fuse::terminated(); + let target_submit_header_future = futures::future::Fuse::terminated(); + let target_go_offline_future = futures::future::Fuse::terminated(); + let target_tick_stream = interval(target_tick_ms).fuse(); + + futures::pin_mut!( + source_best_block_number_future, + source_new_header_future, + source_orphan_header_future, + source_extra_future, + source_go_offline_future, + source_tick_stream, + target_best_block_future, + target_extra_check_future, + target_existence_status_future, + target_submit_header_future, + target_go_offline_future, + target_tick_stream + ); + + loop { + futures::select! { + (source_client, source_best_block_number) = source_best_block_number_future => { + source_best_block_number_required = false; + + process_future_result( + &mut source_maybe_client, + source_client, + source_best_block_number, + |source_best_block_number| sync.source_best_header_number_response(source_best_block_number), + &mut source_go_offline_future, + |source_client| delay(CONNECTION_ERROR_DELAY_MS, source_client), + || format!("Error retrieving best header number from {}", P::source_name()), + ); + }, + (source_client, source_new_header) = source_new_header_future => { + process_future_result( + &mut source_maybe_client, + source_client, + source_new_header, + |source_new_header| sync.headers_mut().header_response(source_new_header), + &mut source_go_offline_future, + |source_client| delay(CONNECTION_ERROR_DELAY_MS, source_client), + || format!("Error retrieving header from {} node", P::source_name()), + ); + }, + (source_client, source_orphan_header) = source_orphan_header_future => { + process_future_result( + &mut source_maybe_client, + source_client, + source_orphan_header, + |source_orphan_header| sync.headers_mut().header_response(source_orphan_header), + &mut source_go_offline_future, + |source_client| delay(CONNECTION_ERROR_DELAY_MS, source_client), + || format!("Error retrieving orphan header from {} node", P::source_name()), + ); + }, + (source_client, source_extra) = source_extra_future => { + process_future_result( + &mut source_maybe_client, + source_client, + source_extra, + |(header, extra)| sync.headers_mut().extra_response(&header, extra), + &mut source_go_offline_future, + |source_client| delay(CONNECTION_ERROR_DELAY_MS, source_client), + || format!("Error retrieving extra data from {} node", P::source_name()), + ); + }, + source_client = source_go_offline_future => { + source_maybe_client = Some(source_client); + }, + _ = source_tick_stream.next() => { + if sync.is_almost_synced() { + source_best_block_number_required = true; + } + }, + (target_client, target_best_block) = target_best_block_future => { + target_best_block_required = false; + + process_future_result( + &mut target_maybe_client, + target_client, + target_best_block, + |target_best_block| { + let head_updated = sync.target_best_header_response(target_best_block); + match head_updated { + // IF head is updated AND there are still our transactions: + // => restart stall countdown timer + true if sync.headers().headers_in_status(HeaderStatus::Submitted) != 0 => + stall_countdown = Some(std::time::Instant::now()), + // IF head is updated AND there are no our transactions: + // => stop stall countdown timer + true => stall_countdown = None, + // IF head is not updated AND stall countdown is not yet completed + // => do nothing + false if stall_countdown + .map(|stall_countdown| std::time::Instant::now() - stall_countdown < + std::time::Duration::from_millis(STALL_SYNC_TIMEOUT_MS)) + .unwrap_or(true) + => (), + // IF head is not updated AND stall countdown has completed + // => restart sync + false => { + log::info!( + target: "bridge", + "Possible {} fork detected. Restarting Ethereum headers synchronization.", + P::target_name(), + ); + stall_countdown = None; + sync.restart(); + }, + } + }, + &mut target_go_offline_future, + |target_client| delay(CONNECTION_ERROR_DELAY_MS, target_client), + || format!("Error retrieving best known header from {} node", P::target_name()), + ); + }, + (target_client, target_existence_status) = target_existence_status_future => { + process_future_result( + &mut target_maybe_client, + target_client, + target_existence_status, + |(target_header, target_existence_status)| sync + .headers_mut() + .maybe_orphan_response(&target_header, target_existence_status), + &mut target_go_offline_future, + |target_client| delay(CONNECTION_ERROR_DELAY_MS, target_client), + || format!("Error retrieving existence status from {} node", P::target_name()), + ); + }, + (target_client, target_submit_header_result) = target_submit_header_future => { + process_future_result( + &mut target_maybe_client, + target_client, + target_submit_header_result, + |submitted_headers| sync.headers_mut().headers_submitted(submitted_headers), + &mut target_go_offline_future, + |target_client| delay(CONNECTION_ERROR_DELAY_MS, target_client), + || format!("Error submitting headers to {} node", P::target_name()), + ); + }, + (target_client, target_extra_check_result) = target_extra_check_future => { + process_future_result( + &mut target_maybe_client, + target_client, + target_extra_check_result, + |(header, extra_check_result)| sync + .headers_mut() + .maybe_extra_response(&header, extra_check_result), + &mut target_go_offline_future, + |target_client| delay(CONNECTION_ERROR_DELAY_MS, target_client), + || format!("Error retrieving receipts requirement from {} node", P::target_name()), + ); + }, + target_client = target_go_offline_future => { + target_maybe_client = Some(target_client); + }, + _ = target_tick_stream.next() => { + target_best_block_required = true; + }, + } + + // print progress + progress_context = print_sync_progress(progress_context, &sync); + + // if target client is available: wait, or call required target methods + if let Some(target_client) = target_maybe_client.take() { + // the priority is to: + // 1) get best block - it stops us from downloading/submitting new blocks + we call it rarely; + // 2) check if we need extra data from source - it stops us from downloading/submitting new blocks; + // 3) check existence - it stops us from submitting new blocks; + // 4) submit header + + if target_best_block_required { + log::debug!(target: "bridge", "Asking {} about best block", P::target_name()); + target_best_block_future.set(target_client.best_header_id().fuse()); + } else if let Some(header) = sync.headers().header(HeaderStatus::MaybeExtra) { + log::debug!( + target: "bridge", + "Checking if header submission requires extra: {:?}", + header.id(), + ); + + target_extra_check_future + .set(target_client.requires_extra(header).fuse()); + } else if let Some(header) = sync.headers().header(HeaderStatus::MaybeOrphan) { + // for MaybeOrphan we actually ask for parent' header existence + let parent_id = header.parent_id(); + + log::debug!( + target: "bridge", + "Asking {} node for existence of: {:?}", + P::target_name(), + parent_id, + ); + + target_existence_status_future + .set(target_client.is_known_header(parent_id).fuse()); + } else if let Some(headers) = sync.select_headers_to_submit() { + let ids = match headers.len() { + 1 => format!("{:?}", headers[0].id()), + 2 => format!("[{:?}, {:?}]", headers[0].id(), headers[1].id()), + len => format!("[{:?} ... {:?}]", headers[0].id(), headers[len - 1].id()), + }; + log::debug!( + target: "bridge", + "Submitting {} header(s) to {} node: {:?}", + headers.len(), + P::target_name(), + ids, + ); + + let headers = headers.into_iter().cloned().collect(); + target_submit_header_future.set( + target_client.submit_headers(headers).fuse() + ); + + // remember that we have submitted some headers + if stall_countdown.is_none() { + stall_countdown = Some(std::time::Instant::now()); + } + } else { + target_maybe_client = Some(target_client); + } + } + + // if source client is available: wait, or call required source methods + if let Some(source_client) = source_maybe_client.take() { + // the priority is to: + // 1) get best block - it stops us from downloading new blocks + we call it rarely; + // 2) download extra data - it stops us from submitting new blocks; + // 3) download missing headers - it stops us from downloading/submitting new blocks; + // 4) downloading new headers + + if source_best_block_number_required { + log::debug!(target: "bridge", "Asking {} node about best block number", P::source_name()); + source_best_block_number_future.set(source_client.best_block_number().fuse()); + } else if let Some(header) = sync.headers().header(HeaderStatus::Extra) { + let id = header.id(); + log::debug!( + target: "bridge", + "Retrieving extra data for header: {:?}", + id, + ); + source_extra_future.set( + source_client.header_extra(id, header.header()).fuse(), + ); + } else if let Some(header) = sync.headers().header(HeaderStatus::Orphan) { + // for Orphan we actually ask for parent' header + let parent_id = header.parent_id(); + + log::debug!( + target: "bridge", + "Going to download orphan header from {} node: {:?}", + P::source_name(), + parent_id, + ); + + source_orphan_header_future.set(source_client.header_by_hash(parent_id.1).fuse()); + } else if let Some(id) = sync.select_new_header_to_download() { + log::debug!( + target: "bridge", + "Going to download new header from {} node: {:?}", + P::source_name(), + id, + ); + + source_new_header_future.set(source_client.header_by_number(id).fuse()); + } else { + source_maybe_client = Some(source_client); + } + } + } + }); +} + diff --git a/relays/ethereum/src/sync_types.rs b/relays/ethereum/src/sync_types.rs index 7e38a2c1fd..564650abf4 100644 --- a/relays/ethereum/src/sync_types.rs +++ b/relays/ethereum/src/sync_types.rs @@ -54,9 +54,12 @@ pub trait HeadersSyncPipeline: Clone + Copy { num_traits::Saturating + num_traits::Zero + num_traits::One; /// Type of header that we're syncing. - type Header: std::fmt::Debug + SourceHeader; + type Header: + Clone + + std::fmt::Debug + + SourceHeader; /// Type of extra data for the header that we're receiving from the source node. - type Extra: std::fmt::Debug; + type Extra: Clone + std::fmt::Debug; /// Name of the headers source. fn source_name() -> &'static str; diff --git a/relays/ethereum/src/utils.rs b/relays/ethereum/src/utils.rs index b1cbdb2d88..6245ce01d9 100644 --- a/relays/ethereum/src/utils.rs +++ b/relays/ethereum/src/utils.rs @@ -46,7 +46,7 @@ pub fn process_future_result( on_success: impl FnOnce(TResult), go_offline_future: &mut std::pin::Pin<&mut futures::future::Fuse>, go_offline: impl FnOnce(TClient) -> TGoOfflineFuture, - error_pattern: &'static str, + error_pattern: impl FnOnce() -> String, ) where TError: std::fmt::Debug + MaybeConnectionError, TGoOfflineFuture: FutureExt, @@ -63,7 +63,7 @@ pub fn process_future_result( *maybe_client = Some(client); } - log::error!(target: "bridge", "{}: {:?}", error_pattern, error); + log::error!(target: "bridge", "{}: {:?}", error_pattern(), error); } } } From 4ec3f6f370a52f13aa05b9c92d0965d193584456 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 8 Apr 2020 17:55:44 +0300 Subject: [PATCH 11/92] continue --- Cargo.lock | 55 +++- .../contracts/substrate-bridge.sol | 117 +++++--- relays/ethereum/Cargo.toml | 4 + relays/ethereum/res/substrate-bridge.json | 57 ++++ relays/ethereum/src/ethereum_client.rs | 179 ++++++++++- relays/ethereum/src/ethereum_types.rs | 2 +- relays/ethereum/src/substrate_client.rs | 50 +++- relays/ethereum/src/substrate_sync_loop.rs | 280 +++++++++++------- relays/ethereum/src/substrate_types.rs | 54 +++- 9 files changed, 644 insertions(+), 154 deletions(-) create mode 100644 relays/ethereum/res/substrate-bridge.json diff --git a/Cargo.lock b/Cargo.lock index 0fb6be6f64..0b5fcb29a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1007,6 +1007,39 @@ dependencies = [ "tiny-keccak 1.5.0", ] +[[package]] +name = "ethabi" +version = "11.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97652a7d1f2504d6c885c87e242a06ccef5bd3054093d3fb742d8fb64806231a" +dependencies = [ + "ethereum-types 0.8.0", + "rustc-hex", + "serde", + "serde_json", + "tiny-keccak 1.5.0", + "uint", +] + +[[package]] +name = "ethabi-contract" +version = "11.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d4002f1f77d8233685dafd8589efe1c9dfa63e21ca6c11134372acc7f68032" + +[[package]] +name = "ethabi-derive" +version = "11.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "587a3ff9748b24f38caecfec9654ae1aa5916ac2e7db2d15f2ab8f59b2fdc70a" +dependencies = [ + "ethabi 11.0.0", + "heck", + "proc-macro2 1.0.10", + "quote 1.0.3", + "syn 1.0.17", +] + [[package]] name = "ethbloom" version = "0.8.1" @@ -1055,6 +1088,10 @@ dependencies = [ "bridge-node-runtime", "clap", "env_logger", + "ethabi 11.0.0", + "ethabi-contract", + "ethabi-derive", + "ethereum-tx-sign", "frame-system", "futures 0.3.4", "jsonrpsee", @@ -1091,6 +1128,22 @@ dependencies = [ "tiny-keccak 1.5.0", ] +[[package]] +name = "ethereum-tx-sign" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d65552d3f9f24d3085823d47bb6cdee8a42a53b2ce8f262d69c1780262dd121" +dependencies = [ + "ethereum-types 0.8.0", + "num-traits", + "rlp", + "secp256k1 0.17.2", + "serde", + "serde_derive", + "serde_json", + "tiny-keccak 2.0.2", +] + [[package]] name = "ethereum-types" version = "0.8.0" @@ -7553,7 +7606,7 @@ dependencies = [ "arrayvec 0.5.1", "base64 0.11.0", "derive_more", - "ethabi", + "ethabi 9.0.1", "ethereum-transaction", "ethereum-types 0.8.0", "ethsign", diff --git a/modules/ethereum-contract/contracts/substrate-bridge.sol b/modules/ethereum-contract/contracts/substrate-bridge.sol index 3d16115e02..2effd65340 100644 --- a/modules/ethereum-contract/contracts/substrate-bridge.sol +++ b/modules/ethereum-contract/contracts/substrate-bridge.sol @@ -17,6 +17,8 @@ pragma solidity ^0.6.4; pragma experimental ABIEncoderV2; +// TODO: expose interface + switch to external+calldata after https://github.com/ethereum/solidity/issues/7929 + /// @title Substrate-to-PoA Bridge Contract. contract SubstrateBridge { /// Voter set as it is stored in the storage. @@ -37,24 +39,32 @@ contract SubstrateBridge { /// Header as it is stored in the storage. struct Header { - /// keccak256(rawHeader) of the next header, or bytes32(0) if it is the best header. - bytes32 nextHeaderHash; - /// Raw header data. - bytes rawHeader; + /// keccak256(header.hash) of the next header, or bytes32(0) if it is the best header. + bytes32 nextHeaderKeccak; + /// Header hash. + bytes hash; + /// Header number. + bytes number; } /// Initializes bridge contract. /// @param rawInitialHeader Raw finalized header that is ancestor of all importing headers. /// @param initialVoters GRANDPA voter set that must finalize direct children of the initial header. - /// @param voterSetSignals GRANDPA voter set signals (including signal from rawInitialHeader). + /// @param voterSetSignals Active GRANDPA voter set signals. constructor( bytes memory rawInitialHeader, VoterSet memory initialVoters, VoterSetSignal[] memory voterSetSignals ) public { // save initial header - bytes32 headerHash = saveBestHeader(rawInitialHeader); - oldestHeaderHash = headerHash; + ( + Header memory initialHeader, + VoterSetSignal memory voterSetSignal + ) = parseSubstrateHeader( + rawInitialHeader + ); + bytes32 headerKeccak = saveBestHeader(initialHeader); + oldestHeaderKeccak = headerKeccak; // save best voter set bestVoterSet.id = initialVoters.id; bestVoterSet.rawVoters = initialVoters.rawVoters; @@ -67,18 +77,32 @@ contract SubstrateBridge { /// Reject direct payments. fallback() external { revert(); } + /// Returns hash of the best known header. + function bestKnownHeader() public view returns (bytes memory, bytes memory) { + Header storage bestHeader = headerByKeccak[bestHeaderKeccak]; + return (bestHeader.number, bestHeader.hash); + } + + /// Returns true if header is known to the bridge. + /// @param headerHash Hash of the header we want to check. + function isKnownHeader( + bytes memory headerHash + ) public view returns (bool) { + return headerByKeccak[keccak256(headerHash)].hash.length != 0; + } + /// Import range of headers with finalization data. /// @param rawHeaders Finalized headers to import. /// @param rawFinalityProof Data required to finalize rawHeaders. function importHeaders( - bytes[] calldata rawHeaders, - bytes calldata rawFinalityProof - ) external { + bytes[] memory rawHeaders, + bytes memory rawFinalityProof + ) public { // verify finalization data (uint256 begin, uint256 end) = verifyFinalityProof( bestVoterSet.id, bestVoterSet.rawVoters, - headerByHash[bestHeaderHash].rawHeader, + headerByKeccak[bestHeaderKeccak].hash, rawHeaders, rawFinalityProof ); @@ -88,18 +112,22 @@ contract SubstrateBridge { for (uint256 i = begin; i < end; ++i) { // parse header bytes memory rawHeader = rawHeaders[i]; - (bytes32 headerNumber, VoterSetSignal memory voterSetSignal) = parseSubstrateHeader( + ( + Header memory header, + VoterSetSignal memory voterSetSignal + ) = parseSubstrateHeader( rawHeader ); // save header to the storage - saveBestHeader(rawHeader); + bytes32 headerNumberKeccak = keccak256(header.number); + saveBestHeader(header); // save voters set signal (if signalled by the header) if (voterSetSignal.rawVoters.length != 0) { saveSignal(voterSetSignal); } // check if header enacts new set - bytes memory newRawVoters = voterSetByEnactNumber[headerNumber]; + bytes memory newRawVoters = voterSetByEnactNumber[headerNumberKeccak]; if (newRawVoters.length != 0) { require( !enactedNewSet, @@ -122,26 +150,27 @@ contract SubstrateBridge { } /// Save best header to the storage. - /// @return keccak256(rawHeader) + /// @return keccak256(header.hash) function saveBestHeader( - bytes memory rawHeader + Header memory header ) private returns (bytes32) { - bytes32 headerHash = keccak256(rawHeader); - bytes32 previousHeaderHash = bestHeaderHash; - if (previousHeaderHash != bytes32(0)) { - headerByHash[previousHeaderHash].nextHeaderHash = headerHash; + bytes32 headerKeccak = keccak256(header.hash); + bytes32 previousHeaderKeccak = bestHeaderKeccak; + if (previousHeaderKeccak != bytes32(0)) { + headerByKeccak[previousHeaderKeccak].nextHeaderKeccak = headerKeccak; } - headerByHash[headerHash].rawHeader = rawHeader; - bestHeaderHash = headerHash; + headerByKeccak[headerKeccak] = header; + bestHeaderKeccak = headerKeccak; storedHeadersCount = storedHeadersCount + 1; - return headerHash; + return headerKeccak; } /// Prune oldest header. function pruneOldestHeader() private { - Header storage oldestHeader = headerByHash[oldestHeaderHash]; - oldestHeaderHash = oldestHeader.nextHeaderHash; - delete headerByHash[oldestHeaderHash]; + bytes32 headerKeccakToRemove = oldestHeaderKeccak; + Header storage oldestHeader = headerByKeccak[headerKeccakToRemove]; + oldestHeaderKeccak = oldestHeader.nextHeaderKeccak; + delete headerByKeccak[headerKeccakToRemove]; storedHeadersCount = storedHeadersCount - 1; } @@ -157,12 +186,16 @@ contract SubstrateBridge { } /// Parse Substrate header. - /// @return keccak256(header.number) and voter set signal (if signalled by the header). + /// @return header.hash, header.number and optional voter set signal. function parseSubstrateHeader( - bytes memory rawHeader - ) private pure returns (bytes32, VoterSetSignal memory) { + bytes memory /*rawHeader*/ + ) private pure returns (Header memory, VoterSetSignal memory) { return ( - bytes32(0), + Header({ + nextHeaderKeccak: bytes32(0), + hash: "", + number: "" + }), VoterSetSignal({ headerNumber: bytes32(0), rawVoters: "" @@ -173,11 +206,11 @@ contract SubstrateBridge { /// Verify finality proof. /// @return Range of headers within rawHeaders that are proved to be final. function verifyFinalityProof( - uint64 currentSetId, - bytes memory rawCurrentVoters, - bytes memory rawBestHeader, - bytes[] memory rawHeaders, - bytes memory rawFinalityProof + uint64 /*currentSetId*/, + bytes memory /*rawCurrentVoters*/, + bytes memory /*rawBestHeader*/, + bytes[] memory /*rawHeaders*/, + bytes memory /*rawFinalityProof*/ ) private pure returns (uint256, uint256) { return (0, 0); // TODO: replace with builtin call } @@ -187,15 +220,15 @@ contract SubstrateBridge { /// Current number of headers that we store. uint256 storedHeadersCount; - /// keccak32(rawHeader) of the oldest header. - bytes32 oldestHeaderHash; - /// keccak32(rawHeader) of the last finalized block. - bytes32 bestHeaderHash; + /// keccak256(header.hash) of the oldest header. + bytes32 oldestHeaderKeccak; + /// keccak256(header.hash) of the last finalized block. + bytes32 bestHeaderKeccak; /// Raw voter set for the last finalized block. VoterSet bestVoterSet; - /// Map of keccak256(raw header) => raw header. - mapping (bytes32 => Header) headerByHash; + /// Map of keccak256(header.hash) => header. + mapping (bytes32 => Header) headerByKeccak; /// Map of keccak256(header.number) => raw voter set that is enacted when block /// with given number is finalized. mapping (bytes32 => bytes) voterSetByEnactNumber; -} \ No newline at end of file +} diff --git a/relays/ethereum/Cargo.toml b/relays/ethereum/Cargo.toml index 965a9c8101..6825d37dde 100644 --- a/relays/ethereum/Cargo.toml +++ b/relays/ethereum/Cargo.toml @@ -11,6 +11,10 @@ async-stream = "0.2.0" clap = { version = "2.33.0", features = ["yaml"] } codec = { package = "parity-scale-codec", version = "1.0.0" } env_logger = "0.7.0" +ethabi = "11.0" +ethabi-contract = "11.0" +ethabi-derive = "11.0" +ethereum-tx-sign = "3.0" futures = "0.3.1" jsonrpsee = { git = "https://github.com/paritytech/jsonrpsee.git", default-features = false, features = ["http"] } linked-hash-map = "0.5.2" diff --git a/relays/ethereum/res/substrate-bridge.json b/relays/ethereum/res/substrate-bridge.json new file mode 100644 index 0000000000..c96fe55d63 --- /dev/null +++ b/relays/ethereum/res/substrate-bridge.json @@ -0,0 +1,57 @@ +[ + { + "inputs": [], + "name": "bestKnownHeader", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "rawHeaders", + "type": "bytes[]" + }, + { + "internalType": "bytes", + "name": "rawFinalityProof", + "type": "bytes" + } + ], + "name": "importHeaders", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "headerHash", + "type": "bytes" + } + ], + "name": "isKnownHeader", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index cddbc8bc14..e0806f857e 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -14,14 +14,20 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::ethereum_types::{EthereumHeaderId, Header, Receipt, H256, U64}; -use crate::sync_types::MaybeConnectionError; +use crate::ethereum_types::{Address, Bytes, EthereumHeaderId, Header, Receipt, H256, U256, U64}; +use crate::substrate_types::{SubstrateHeaderId, Hash as SubstrateHash, Number as SubstrateNumber, QueuedSubstrateHeader}; +use crate::sync_types::{HeaderId, MaybeConnectionError}; +use codec::{Encode, Decode}; +use ethabi::FunctionOutputDecoder; use jsonrpsee::common::Params; use jsonrpsee::raw::{RawClient, RawClientError}; use jsonrpsee::transport::http::{HttpTransportClient, RequestError}; -use serde::de::DeserializeOwned; +use serde::{Serialize, de::DeserializeOwned}; use serde_json::{from_value, to_value}; +// to encode/decode contract calls +ethabi_contract::use_contract!(bridge_contract, "res/substrate-bridge.json"); + /// Proof of hash serialization success. const HASH_SERIALIZATION_PROOF: &'static str = "hash serialization never fails; qed"; /// Proof of integer serialization success. @@ -32,6 +38,15 @@ const BOOL_SERIALIZATION_PROOF: &'static str = "bool serialization never fails; /// Ethereum client type. pub type Client = RawClient; +/// Ethereum contract call request. +#[derive(Debug, Default, PartialEq, Serialize)] +pub struct CallRequest { + /// Contract address. + pub to: Option

, + /// Call data. + pub data: Option, +} + /// All possible errors that can occur during interacting with Ethereum node. #[derive(Debug)] pub enum Error { @@ -42,11 +57,13 @@ pub enum Error { /// Failed to receive response. ResponseRetrievalFailed(RawClientError), /// Failed to parse response. - ResponseParseFailed(serde_json::Error), + ResponseParseFailed(String), /// We have received header with missing number and hash fields. IncompleteHeader, /// We have received receipt with missing gas_used field. IncompleteReceipt, + /// Justification for last Substrate header is missing. + MissingJustification, } impl MaybeConnectionError for Error { @@ -150,6 +167,158 @@ async fn transaction_receipt(client: Client, hash: H256) -> (Client, Result (Client, Result) { + let (encoded_call, call_decoder) = bridge_contract::functions::best_known_header::call(); + let (client, result) = call_rpc::( + client, + "eth_call", + Params::Array(vec![ + to_value(CallRequest { + to: Some(contract_address), + data: Some(encoded_call.into()), + }).unwrap(), + ]), + ) + .await; + let call_result = match result { + Ok(result) => result, + Err(error) => return (client, Err(error)), + }; + let (raw_number, raw_hash) = match call_decoder.decode(&call_result.0) { + Ok((raw_number, raw_hash)) => (raw_number, raw_hash), + Err(error) => return (client, Err(Error::ResponseParseFailed(format!("{}", error)))), + }; + let number = match SubstrateNumber::decode(&mut &raw_number[..]) { + Ok(number) => number, + Err(error) => return (client, Err(Error::ResponseParseFailed(format!("{}", error)))), + }; + let hash = match SubstrateHash::decode(&mut &raw_hash[..]) { + Ok(hash) => hash, + Err(error) => return (client, Err(Error::ResponseParseFailed(format!("{}", error)))), + }; + + ( + client, + Ok(HeaderId(number, hash)), + ) +} + +/// Returns true if Substrate header is known to Ethereum node. +pub async fn substrate_header_known( + client: Client, + contract_address: Address, + id: SubstrateHeaderId, +) -> (Client, Result<(SubstrateHeaderId, bool), Error>) { + // Ethereum contract could prune old headers. So this fn could return false even + // if header is synced. And we'll mark corresponding Ethereum header as Orphan. + // + // But when we'll read best header from Ethereum next time, we will know that + // there's a better header => this Orphan will either be marked as synced, or + // eventually pruned. + let (encoded_call, call_decoder) = bridge_contract::functions::is_known_header::call(id.1.encode()); + let (client, result) = call_rpc::( + client, + "eth_call", + Params::Array(vec![ + to_value(CallRequest { + to: Some(contract_address), + data: Some(encoded_call.into()), + }).unwrap(), + ]), + ) + .await; + let call_result = match result { + Ok(result) => result, + Err(error) => return (client, Err(error)), + }; + match call_decoder.decode(&call_result.0) { + Ok(is_known_block) => (client, Ok((id, is_known_block))), + Err(error) => (client, Err(Error::ResponseParseFailed(format!("{}", error)))), + } +} + +/// Submits Substrate headers to Ethereum contract. +pub async fn submit_substrate_headers( + client: Client, + signer: parity_crypto::publickey::KeyPair, + chain_id: u64, + contract_address: Address, + gas_price: U256, + headers: Vec, +) -> (Client, Result<(H256, Vec), Error>) { + let ids = headers.iter().map(|header| header.id()).collect(); + let num_headers = headers.len(); + let (headers, justification) = headers + .into_iter() + .fold((Vec::with_capacity(num_headers), None), |(mut headers, _), header| { + let (header, justification) = header.extract(); + headers.push(header.encode()); + (headers, justification) + }); + let justification = match justification { + Some(justification) => justification.encode(), + None => return (client, Err(Error::MissingJustification)), + }; + let encoded_call = bridge_contract::functions::import_headers::encode_input( + headers, + justification, + ); + let (client, nonce) = account_nonce(client, signer.address().as_fixed_bytes().into()).await; + let nonce = match nonce { + Ok(nonce) => nonce, + Err(error) => return (client, Err(error)), + }; + let (client, gas) = estimate_gas(client, CallRequest { + to: Some(contract_address), + data: Some(encoded_call.clone().into()), + }).await; + let gas = match gas { + Ok(gas) => gas, + Err(error) => return (client, Err(error)), + }; + let raw_transaction = ethereum_tx_sign::RawTransaction { + nonce, + to: Some(contract_address), + value: U256::zero(), + gas, + gas_price, + data: encoded_call, + }.sign(&signer.secret().as_fixed_bytes().into(), &chain_id); + let (client, result) = call_rpc( + client, + "eth_submitTransaction", + Params::Array(vec![ + to_value(raw_transaction).unwrap(), + ]), + ) + .await; + (client, result.map(|tx_hash| (tx_hash, ids))) +} + +/// Get account nonce. +async fn account_nonce( + client: Client, + caller_address: Address, +) -> (Client, Result) { + call_rpc(client, "eth_getTransactionCount", Params::Array(vec![ + to_value(caller_address).unwrap(), + ])).await +} + +/// Estimate gas usage for call. +async fn estimate_gas( + client: Client, + call_request: CallRequest, +) -> (Client, Result) { + call_rpc(client, "eth_getTransactionCount", Params::Array(vec![ + to_value(call_request).unwrap(), + ])).await +} + /// Calls RPC on Ethereum node. async fn call_rpc( mut client: Client, @@ -172,7 +341,7 @@ async fn call_rpc( .ok_or(Error::RequestNotFound)? .await .map_err(Error::ResponseRetrievalFailed)?; - from_value(response).map_err(Error::ResponseParseFailed) + from_value(response).map_err(|e| Error::ResponseParseFailed(format!("{}", e))) } let result = do_call_rpc(&mut client, method, params).await; diff --git a/relays/ethereum/src/ethereum_types.rs b/relays/ethereum/src/ethereum_types.rs index ea8cbfae07..618d46d856 100644 --- a/relays/ethereum/src/ethereum_types.rs +++ b/relays/ethereum/src/ethereum_types.rs @@ -18,7 +18,7 @@ use crate::sync_types::{HeaderId, HeadersSyncPipeline, SourceHeader, QueuedHeade use crate::substrate_types::{into_substrate_ethereum_header, into_substrate_ethereum_receipts}; use codec::Encode; -pub use web3::types::{Bytes, H256, U128, U64}; +pub use web3::types::{Address, Bytes, H256, U128, U256, U64}; /// When header is just received from the Ethereum node, we check that it has /// both number and hash fields filled. diff --git a/relays/ethereum/src/substrate_client.rs b/relays/ethereum/src/substrate_client.rs index 40a9047c5e..56748561f2 100644 --- a/relays/ethereum/src/substrate_client.rs +++ b/relays/ethereum/src/substrate_client.rs @@ -15,7 +15,11 @@ // along with Parity Bridges Common. If not, see . use crate::ethereum_types::{Bytes, EthereumHeaderId, QueuedEthereumHeader, H256}; -use crate::substrate_types::{into_substrate_ethereum_header, into_substrate_ethereum_receipts, TransactionHash}; +use crate::substrate_types::{ + into_substrate_ethereum_header, into_substrate_ethereum_receipts, + Hash, Header as SubstrateHeader, Justification, Number, + TransactionHash, +}; use crate::sync_types::{HeaderId, MaybeConnectionError, SourceHeader}; use codec::{Decode, Encode}; use jsonrpsee::common::Params; @@ -64,6 +68,50 @@ pub fn client(uri: &str) -> Client { } } +/// Returns best Substrate header. +pub async fn best_header(client: Client) -> (Client, Result) { + call_rpc( + client, + "chain_getHeader", + Params::None, + ) + .await +} + +/// Returns Substrate header by hash. +pub async fn header_by_hash(client: Client, hash: Hash) -> (Client, Result) { + call_rpc( + client, + "chain_getHeader", + Params::Array(vec![ + to_value(hash).unwrap(), + ]), + ) + .await +} + +/// Returns Substrate header by number. +pub async fn header_by_number(client: Client, number: Number) -> (Client, Result) { + let (client, hash) = call_rpc( + client, + "chain_getBlockHash", + Params::Array(vec![ + to_value(number).unwrap(), + ]), + ) + .await; + let hash = match hash { + Ok(hash) => hash, + Err(error) => return (client, Err(error)), + }; + header_by_hash(client, hash).await +} + +/// Returns justification for Substrate header. +pub async fn justification(client: Client, _hash: Hash) -> (Client, Result, Error>) { + (client, Ok(Some(vec![42]))) // TODO: implement me +} + /// Returns best Ethereum block that Substrate runtime knows of. pub async fn best_ethereum_block(client: Client) -> (Client, Result) { let (client, result) = call_rpc::<(u64, H256)>( diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index 7d860ebc73..f820e96351 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -15,19 +15,39 @@ // along with Parity Bridges Common. If not, see . use crate::ethereum_client; +use crate::ethereum_types::{Address, U256}; use crate::substrate_client; +use crate::substrate_types::{ + Header, Hash, Number, Justification, QueuedSubstrateHeader, + SubstrateHeaderId, SubstrateHeadersSyncPipeline, +}; use crate::sync::HeadersSyncParams; -use futures::future::FutureExt; +use crate::sync_loop::{SourceClient, TargetClient}; +use crate::sync_types::SourceHeader; +use futures::future::{FutureExt, Ready, ready}; use parity_crypto::publickey::KeyPair; +use std::{future::Future, pin::Pin}; + +/// Interval (in ms) at which we check new Substrate headers when we are synced/almost synced. +const SUBSTRATE_TICK_INTERVAL_MS: u64 = 10_000; +/// Interval (in ms) at which we check new Ethereum blocks. +const ETHEREUM_TICK_INTERVAL_MS: u64 = 5_000; /// Substrate synchronization parameters. +#[derive(Debug)] pub struct SubstrateSyncParams { /// Ethereum RPC host. pub eth_host: String, /// Ethereum RPC port. pub eth_port: u16, + /// Ethereum chain id. + pub eth_chain_id: u64, + /// Ethereum bridge contract address. + pub eth_contract_address: Address, /// Ethereum transactions signer. pub eth_signer: KeyPair, + /// Gas price we agree to pay. + pub eth_gas_price: U256, /// Substrate RPC host. pub sub_host: String, /// Substrate RPC port. @@ -41,6 +61,8 @@ impl Default for SubstrateSyncParams { SubstrateSyncParams { eth_host: "localhost".into(), eth_port: 8545, + eth_chain_id: 1, // Ethereum mainnet + eth_contract_address: Default::default(), // that the account that has a lot of ether when we run instant seal engine // address: 0x00a329c0648769a73afac7f9381e08fb43dbea72 // secret: 0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7 @@ -49,6 +71,7 @@ impl Default for SubstrateSyncParams { 0xe6, 0x3d, 0x73, 0xd7, 0x65, 0x8d, 0x40, 0x26, 0xf2, 0xee, 0xfd, 0x2f, 0x20, 0x4c, 0x81, 0x68, 0x2c, 0xb7] ).expect("secret is hardcoded, thus valid; qed"), + eth_gas_price: 8_000_000_000u64.into(), // 8 Gwei sub_host: "localhost".into(), sub_port: 9933, sync_params: Default::default(), @@ -56,108 +79,159 @@ impl Default for SubstrateSyncParams { } } -/// Run Substrate headers synchronization. -pub fn run(params: SubstrateSyncParams) { -/* let mut local_pool = futures::executor::LocalPool::new(); - let mut progress_context = (std::time::Instant::now(), None, None); - - local_pool.run_until(async move { - let eth_uri = format!("http://{}:{}", params.eth_host, params.eth_port); - let sub_uri = format!("http://{}:{}", params.sub_host, params.sub_port); - - let mut sub_sync = crate::sync::HeadersSync::new(params.sync_params); - let mut stall_countdown = None; - - let mut eth_maybe_client = None; - let mut eth_best_block_number_required = false; - let eth_best_block_number_future = ethereum_client::best_block_number(ethereum_client::client(ð_uri)).fuse(); - let eth_tick_stream = interval(ETHEREUM_TICK_INTERVAL_MS).fuse(); - - let mut sub_maybe_client = None; - let mut sub_best_block_required = false; - let sub_best_block_future = - substrate_client::best_ethereum_block(substrate_client::client(&sub_uri)).fuse(); - let sub_tick_stream = interval(SUBSTRATE_TICK_INTERVAL_MS).fuse(); - - futures::pin_mut!( - eth_best_block_number_future, - eth_tick_stream, - sub_best_block_future, - sub_tick_stream - ); - - loop { - futures::select! { - (eth_client, eth_best_block_number) = eth_best_block_number_future => { - eth_best_block_number_required = false; - - process_future_result( - &mut eth_maybe_client, - eth_client, - eth_best_block_number, - |eth_best_block_number| eth_sync.source_best_header_number_response(eth_best_block_number), - &mut eth_go_offline_future, - |eth_client| delay(CONNECTION_ERROR_DELAY_MS, eth_client), - "Error retrieving best header number from Ethereum number", - ); - }, - eth_client = eth_go_offline_future => { - eth_maybe_client = Some(eth_client); - }, - _ = eth_tick_stream.next() => { - if eth_sync.is_almost_synced() { - eth_best_block_number_required = true; - } - }, - (sub_client, sub_best_block) = sub_best_block_future => { - sub_best_block_required = false; - - process_future_result( - &mut sub_maybe_client, - sub_client, - sub_best_block, - |sub_best_block| { - let head_updated = eth_sync.target_best_header_response(sub_best_block); - match head_updated { - // IF head is updated AND there are still our transactions: - // => restart stall countdown timer - true if eth_sync.headers().headers_in_status(EthereumHeaderStatus::Submitted) != 0 => - stall_countdown = Some(std::time::Instant::now()), - // IF head is updated AND there are no our transactions: - // => stop stall countdown timer - true => stall_countdown = None, - // IF head is not updated AND stall countdown is not yet completed - // => do nothing - false if stall_countdown - .map(|stall_countdown| std::time::Instant::now() - stall_countdown < - std::time::Duration::from_millis(STALL_SYNC_TIMEOUT_MS)) - .unwrap_or(true) - => (), - // IF head is not updated AND stall countdown has completed - // => restart sync - false => { - log::info!( - target: "bridge", - "Possible Substrate fork detected. Restarting Ethereum headers synchronization.", - ); - stall_countdown = None; - eth_sync.restart(); - }, - } - }, - &mut sub_go_offline_future, - |sub_client| delay(CONNECTION_ERROR_DELAY_MS, sub_client), - "Error retrieving best known header from Substrate node", - ); - }, - sub_client = sub_go_offline_future => { - sub_maybe_client = Some(sub_client); - }, - _ = sub_tick_stream.next() => { - sub_best_block_required = true; +/// Substrate client as headers source. +struct SubstrateHeadersSource { + /// Substrate node client. + client: substrate_client::Client, +} + +impl SourceClient for SubstrateHeadersSource { + type Error = substrate_client::Error; + type BestBlockNumberFuture = Pin)>>>; + type HeaderByHashFuture = Pin)>>>; + type HeaderByNumberFuture = Pin)>>>; + type HeaderExtraFuture = Pin), Self::Error>)>>>; + + fn best_block_number(self) -> Self::BestBlockNumberFuture { + substrate_client::best_header(self.client) + .map(|(client, result)| ( + SubstrateHeadersSource { client }, + result.map(|header| header.number) + )) + .boxed() + } + + fn header_by_hash(self, hash: Hash) -> Self::HeaderByHashFuture { + substrate_client::header_by_hash(self.client, hash) + .map(|(client, result)| (SubstrateHeadersSource { client }, result)) + .boxed() + } + + fn header_by_number(self, number: Number) -> Self::HeaderByNumberFuture { + substrate_client::header_by_number(self.client, number) + .map(|(client, result)| (SubstrateHeadersSource { client }, result)) + .boxed() + } + + fn header_extra(self, id: SubstrateHeaderId, _header: &Header) -> Self::HeaderExtraFuture { + substrate_client::justification(self.client, id.1) + .map(move |(client, result)| ( + SubstrateHeadersSource { client }, + result.map(|justification| (id, justification)), + )) + .boxed() + } +} + +/// Ethereum client as Substrate headers target. +struct EthereumHeadersTarget { + /// Ethereum node client. + client: ethereum_client::Client, + /// Ethereum transactions signer. + signer: parity_crypto::publickey::KeyPair, + /// Ethereum chain id. + chain_id: u64, + /// Bridge contract address. + contract: Address, + /// Gas price we are paying for transactions. + gas_price: U256, +} + +impl TargetClient for EthereumHeadersTarget { + type Error = ethereum_client::Error; + type BestHeaderIdFuture = Pin)>>>; + type IsKnownHeaderFuture = Pin)>>>; + type RequiresExtraFuture = Ready<(Self, Result<(SubstrateHeaderId, bool), Self::Error>)>; + type SubmitHeadersFuture = Pin, Self::Error>)>>>; + + fn best_header_id(self) -> Self::BestHeaderIdFuture { + let (signer, chain_id, contract, gas_price) + = (self.signer, self.chain_id, self.contract, self.gas_price); + ethereum_client::best_substrate_block(self.client, contract) + .map(move |(client, result)| { + ( + EthereumHeadersTarget { + client, + signer, + chain_id, + contract, + gas_price, + }, + result, + ) + }) + .boxed() + } + + fn is_known_header(self, id: SubstrateHeaderId) -> Self::IsKnownHeaderFuture { + let (signer, chain_id, contract, gas_price) + = (self.signer, self.chain_id, self.contract, self.gas_price); + ethereum_client::substrate_header_known(self.client, contract, id) + .map(move |(client, result)| { + ( + EthereumHeadersTarget { + client, + signer, + chain_id, + contract, + gas_price, + }, + result, + ) + }) + .boxed() + } + + fn requires_extra(self, header: &QueuedSubstrateHeader) -> Self::RequiresExtraFuture { + // we would require justification for every header + ready((self, Ok((header.header().id(), true)))) + } + + fn submit_headers(self, headers: Vec) -> Self::SubmitHeadersFuture { + let (signer, chain_id, contract, gas_price) + = (self.signer, self.chain_id, self.contract, self.gas_price); + ethereum_client::submit_substrate_headers( + self.client, + signer.clone(), + chain_id, + contract, + gas_price, + headers, + ).map(move |(client, result)| { + ( + EthereumHeadersTarget { + client, + signer, + chain_id, + contract, + gas_price, }, - } - } - });*/ + result.map(|(_, submitted_headers)| submitted_headers), + ) + }) + .boxed() + } } +/// Run Substrate headers synchronization. +pub fn run(params: SubstrateSyncParams) { + let eth_uri = format!("http://{}:{}", params.eth_host, params.eth_port); + let eth_client = ethereum_client::client(ð_uri); + + let sub_uri = format!("http://{}:{}", params.sub_host, params.sub_port); + let sub_client = substrate_client::client(&sub_uri); + + crate::sync_loop::run( + SubstrateHeadersSource { client: sub_client }, + SUBSTRATE_TICK_INTERVAL_MS, + EthereumHeadersTarget { + client: eth_client, + signer: params.eth_signer, + chain_id: params.eth_chain_id, + contract: params.eth_contract_address, + gas_price: params.eth_gas_price, + }, + ETHEREUM_TICK_INTERVAL_MS, + params.sync_params, + ); +} diff --git a/relays/ethereum/src/substrate_types.rs b/relays/ethereum/src/substrate_types.rs index f056b71011..b97b49c517 100644 --- a/relays/ethereum/src/substrate_types.rs +++ b/relays/ethereum/src/substrate_types.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -pub use crate::ethereum_types::H256 as TransactionHash; +use crate::sync_types::{HeaderId, HeadersSyncPipeline, SourceHeader, QueuedHeader}; use crate::ethereum_types::{ Header as EthereumHeader, Receipt as EthereumReceipt, HEADER_ID_PROOF as ETHEREUM_HEADER_ID_PROOF, RECEIPT_GAS_USED_PROOF as ETHEREUM_RECEIPT_GAS_USED_PROOF, @@ -24,6 +24,58 @@ pub use sp_bridge_eth_poa::{ Receipt as SubstrateEthereumReceipt, TransactionOutcome as SubstrateEthereumTransactionOutcome, H256, U256, }; +/// Substrate transaction hash type. +pub type TransactionHash = bridge_node_runtime::Hash; + +/// Substrate header hash. +pub type Hash = bridge_node_runtime::Hash; + +/// Substrate header number. +pub type Number = bridge_node_runtime::BlockNumber; + +/// Substrate header type. +pub type Header = bridge_node_runtime::Header; + +/// Substrate justification type. +pub type Justification = Vec; + +/// Substrate header ID. +pub type SubstrateHeaderId = HeaderId; + +/// Queued substrate header ID. +pub type QueuedSubstrateHeader = QueuedHeader; + +/// Substrate synchronization pipeline. +#[derive(Clone, Copy, Debug)] +#[cfg_attr(test, derive(PartialEq))] +pub struct SubstrateHeadersSyncPipeline; + +impl HeadersSyncPipeline for SubstrateHeadersSyncPipeline { + const SOURCE_NAME: &'static str = "Substrate"; + const TARGET_NAME: &'static str = "Ethereum"; + + type Hash = bridge_node_runtime::Hash; + type Number = bridge_node_runtime::BlockNumber; + type Header = Header; + type Extra = Option; + + fn estimate_size(_source: &QueuedHeader) -> usize { + // we may only submit Substrate headers wit finality proof + // => this value should never be used + 0 + } +} + +impl SourceHeader for Header { + fn id(&self) -> SubstrateHeaderId { + HeaderId(self.number, self.hash()) + } + + fn parent_id(&self) -> SubstrateHeaderId { + HeaderId(self.number - 1, self.parent_hash) + } +} + /// Convert Ethereum header into Ethereum header for Substrate. pub fn into_substrate_ethereum_header(header: &EthereumHeader) -> SubstrateEthereumHeader { SubstrateEthereumHeader { From bf77451ff41ee0aaae7a5d1bcd31f3c1d8a6d188 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 8 Apr 2020 18:05:11 +0300 Subject: [PATCH 12/92] add eth-contract argument --- relays/ethereum/src/cli.yml | 6 ++++++ relays/ethereum/src/main.rs | 3 +++ 2 files changed, 9 insertions(+) diff --git a/relays/ethereum/src/cli.yml b/relays/ethereum/src/cli.yml index 8035b11098..48aa256cfd 100644 --- a/relays/ethereum/src/cli.yml +++ b/relays/ethereum/src/cli.yml @@ -56,6 +56,12 @@ subcommands: value_name: ETH_PORT help: Connect to Ethereum node at given port. takes_value: true + - eth-contract: + long: eth-contract + value_name: ETH_CONTRACT + help: Address of deployed bridge contract. + takes_value: true + required: true - eth-signer: long: eth-signer value_name: ETH_SIGNER diff --git a/relays/ethereum/src/main.rs b/relays/ethereum/src/main.rs index a39c5b17e7..8db2722072 100644 --- a/relays/ethereum/src/main.rs +++ b/relays/ethereum/src/main.rs @@ -144,6 +144,9 @@ fn substrate_sync_params(matches: &clap::ArgMatches) -> Result Date: Thu, 9 Apr 2020 16:52:43 +0300 Subject: [PATCH 13/92] continue --- Cargo.lock | 3 + .../contracts/substrate-bridge.sol | 42 ++--- relays/ethereum/Cargo.toml | 1 + relays/ethereum/res/substrate-bridge.json | 29 +++- relays/ethereum/src/cli.yml | 17 ++ relays/ethereum/src/ethereum_client.rs | 52 +++++- .../ethereum/src/ethereum_deploy_contract.rs | 162 ++++++++++++++++++ relays/ethereum/src/main.rs | 29 +++- relays/ethereum/src/substrate_client.rs | 57 ++++-- relays/ethereum/src/substrate_sync_loop.rs | 7 +- 10 files changed, 357 insertions(+), 42 deletions(-) create mode 100644 relays/ethereum/src/ethereum_deploy_contract.rs diff --git a/Cargo.lock b/Cargo.lock index 0b5fcb29a0..5f2a2218c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -447,8 +447,10 @@ version = "0.1.0" dependencies = [ "bridge-node-runtime", "futures 0.3.4", + "hex", "jsonrpc-core", "log 0.4.8", + "parity-scale-codec", "sc-basic-authorship", "sc-cli", "sc-client", @@ -1094,6 +1096,7 @@ dependencies = [ "ethereum-tx-sign", "frame-system", "futures 0.3.4", + "hex", "jsonrpsee", "linked-hash-map", "log 0.4.8", diff --git a/modules/ethereum-contract/contracts/substrate-bridge.sol b/modules/ethereum-contract/contracts/substrate-bridge.sol index 2effd65340..b73717ef00 100644 --- a/modules/ethereum-contract/contracts/substrate-bridge.sol +++ b/modules/ethereum-contract/contracts/substrate-bridge.sol @@ -15,10 +15,12 @@ // along with Parity Bridges Common. If not, see . pragma solidity ^0.6.4; -pragma experimental ABIEncoderV2; // TODO: expose interface + switch to external+calldata after https://github.com/ethereum/solidity/issues/7929 +// TODO: use ABIEncoderV2 to allow passing headers array as bytes[] and structs to constructor +// when ethabi will support it + /// @title Substrate-to-PoA Bridge Contract. contract SubstrateBridge { /// Voter set as it is stored in the storage. @@ -48,30 +50,27 @@ contract SubstrateBridge { } /// Initializes bridge contract. - /// @param rawInitialHeader Raw finalized header that is ancestor of all importing headers. - /// @param initialVoters GRANDPA voter set that must finalize direct children of the initial header. - /// @param voterSetSignals Active GRANDPA voter set signals. + /// @param rawInitialHeader Vec of single element - raw finalized header that will be ancestor of all importing headers. + /// @param initialVotersSetId ID of GRANDPA voter set that must finalize direct children of the initial header. + /// @param initialRawVoters Raw GRANDPA voter set that must finalize direct children of the initial header. constructor( bytes memory rawInitialHeader, - VoterSet memory initialVoters, - VoterSetSignal[] memory voterSetSignals + uint64 initialVotersSetId, + bytes memory initialRawVoters ) public { // save initial header ( Header memory initialHeader, VoterSetSignal memory voterSetSignal ) = parseSubstrateHeader( + 0, rawInitialHeader ); bytes32 headerKeccak = saveBestHeader(initialHeader); oldestHeaderKeccak = headerKeccak; // save best voter set - bestVoterSet.id = initialVoters.id; - bestVoterSet.rawVoters = initialVoters.rawVoters; - // save all signals - for (uint i = 0; i < voterSetSignals.length; ++i) { - saveSignal(voterSetSignals[i]); - } + bestVoterSet.id = initialVotersSetId; + bestVoterSet.rawVoters = initialRawVoters; } /// Reject direct payments. @@ -92,10 +91,10 @@ contract SubstrateBridge { } /// Import range of headers with finalization data. - /// @param rawHeaders Finalized headers to import. + /// @param rawHeaders Vec of encoded finalized headers to import. /// @param rawFinalityProof Data required to finalize rawHeaders. function importHeaders( - bytes[] memory rawHeaders, + bytes memory rawHeaders, bytes memory rawFinalityProof ) public { // verify finalization data @@ -111,12 +110,12 @@ contract SubstrateBridge { bool enactedNewSet = false; for (uint256 i = begin; i < end; ++i) { // parse header - bytes memory rawHeader = rawHeaders[i]; ( Header memory header, VoterSetSignal memory voterSetSignal ) = parseSubstrateHeader( - rawHeader + i, + rawHeaders ); // save header to the storage @@ -185,16 +184,17 @@ contract SubstrateBridge { voterSetByEnactNumber[voterSetSignal.headerNumber] = voterSetSignal.rawVoters; } - /// Parse Substrate header. + /// Parse i-th Substrate header from the raw headers vector. /// @return header.hash, header.number and optional voter set signal. function parseSubstrateHeader( - bytes memory /*rawHeader*/ + uint256 headerIndex, + bytes memory rawHeaders ) private pure returns (Header memory, VoterSetSignal memory) { return ( Header({ nextHeaderKeccak: bytes32(0), - hash: "", - number: "" + hash: abi.encodePacked(keccak256(abi.encode(headerIndex, rawHeaders))), + number: abi.encodePacked(headerIndex) }), VoterSetSignal({ headerNumber: bytes32(0), @@ -209,7 +209,7 @@ contract SubstrateBridge { uint64 /*currentSetId*/, bytes memory /*rawCurrentVoters*/, bytes memory /*rawBestHeader*/, - bytes[] memory /*rawHeaders*/, + bytes memory /*rawHeaders*/, bytes memory /*rawFinalityProof*/ ) private pure returns (uint256, uint256) { return (0, 0); // TODO: replace with builtin call diff --git a/relays/ethereum/Cargo.toml b/relays/ethereum/Cargo.toml index 6825d37dde..638b8f45da 100644 --- a/relays/ethereum/Cargo.toml +++ b/relays/ethereum/Cargo.toml @@ -16,6 +16,7 @@ ethabi-contract = "11.0" ethabi-derive = "11.0" ethereum-tx-sign = "3.0" futures = "0.3.1" +hex = "0.4" jsonrpsee = { git = "https://github.com/paritytech/jsonrpsee.git", default-features = false, features = ["http"] } linked-hash-map = "0.5.2" log = "0.4.8" diff --git a/relays/ethereum/res/substrate-bridge.json b/relays/ethereum/res/substrate-bridge.json index c96fe55d63..949bf23b3d 100644 --- a/relays/ethereum/res/substrate-bridge.json +++ b/relays/ethereum/res/substrate-bridge.json @@ -1,4 +1,29 @@ [ + { + "inputs": [ + { + "internalType": "bytes", + "name": "rawInitialHeader", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "initialVotersSetId", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "initialRawVoters", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "nonpayable", + "type": "fallback" + }, { "inputs": [], "name": "bestKnownHeader", @@ -20,9 +45,9 @@ { "inputs": [ { - "internalType": "bytes[]", + "internalType": "bytes", "name": "rawHeaders", - "type": "bytes[]" + "type": "bytes" }, { "internalType": "bytes", diff --git a/relays/ethereum/src/cli.yml b/relays/ethereum/src/cli.yml index 48aa256cfd..f9ff76edcd 100644 --- a/relays/ethereum/src/cli.yml +++ b/relays/ethereum/src/cli.yml @@ -76,3 +76,20 @@ subcommands: value_name: SUB_PORT help: Connect to Substrate node at given port. takes_value: true + - eth-deploy-contract: + about: Deploy Bridge contract on Ethereum node. + args: + - eth-host: + long: eth-host + value_name: ETH_HOST + help: Connect to Ethereum node at given host. + takes_value: true + - eth-port: + long: eth-port + value_name: ETH_PORT + help: Connect to Ethereum node at given port. + takes_value: true + - eth-signer: + long: eth-signer + value_name: ETH_SIGNER + help: Hex-encoded secret to use when transactions are submitted to the Ethereum node. \ No newline at end of file diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index e0806f857e..8de1eed482 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -264,7 +264,7 @@ pub async fn submit_substrate_headers( None => return (client, Err(Error::MissingJustification)), }; let encoded_call = bridge_contract::functions::import_headers::encode_input( - headers, + headers.encode(), justification, ); let (client, nonce) = account_nonce(client, signer.address().as_fixed_bytes().into()).await; @@ -299,6 +299,54 @@ pub async fn submit_substrate_headers( (client, result.map(|tx_hash| (tx_hash, ids))) } +/// Deploy bridge contract. +pub async fn deploy_bridge_contract( + client: Client, + signer: parity_crypto::publickey::KeyPair, + chain_id: u64, + gas_price: U256, + contract_code: Vec, + initial_header: Vec, + initial_set_id: u64, + initial_authorities: Vec, +) -> (Client, Result) { + let encoded_call = bridge_contract::constructor( + contract_code, + vec![initial_header].encode(), + initial_set_id, + initial_authorities, + ); + let (client, nonce) = account_nonce(client, signer.address().as_fixed_bytes().into()).await; + let nonce = match nonce { + Ok(nonce) => nonce, + Err(error) => return (client, Err(error)), + }; + let (client, gas) = estimate_gas(client, CallRequest { + data: Some(encoded_call.clone().into()), + ..Default::default() + }).await; + let gas = match gas { + Ok(gas) => gas, + Err(error) => return (client, Err(error)), + }; + let raw_transaction = ethereum_tx_sign::RawTransaction { + nonce: nonce, + to: None, + value: U256::zero(), + gas, + gas_price, + data: encoded_call, + }.sign(&signer.secret().as_fixed_bytes().into(), &chain_id); + call_rpc( + client, + "eth_submitTransaction", + Params::Array(vec![ + to_value(Bytes(raw_transaction)).unwrap(), + ]), + ) + .await +} + /// Get account nonce. async fn account_nonce( client: Client, @@ -314,7 +362,7 @@ async fn estimate_gas( client: Client, call_request: CallRequest, ) -> (Client, Result) { - call_rpc(client, "eth_getTransactionCount", Params::Array(vec![ + call_rpc(client, "eth_estimateGas", Params::Array(vec![ to_value(call_request).unwrap(), ])).await } diff --git a/relays/ethereum/src/ethereum_deploy_contract.rs b/relays/ethereum/src/ethereum_deploy_contract.rs new file mode 100644 index 0000000000..6e9ebeda12 --- /dev/null +++ b/relays/ethereum/src/ethereum_deploy_contract.rs @@ -0,0 +1,162 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +use crate::ethereum_client; +use crate::ethereum_types::U256; +use crate::substrate_client; +use crate::substrate_types::{Hash as SubstrateHash, Header as SubstrateHeader}; +use codec::{Decode, Encode}; +use num_traits::Zero; +use parity_crypto::publickey::KeyPair; + +/// Ethereum synchronization parameters. +#[derive(Debug)] +pub struct EthereumDeployContractParams { + /// Ethereum RPC host. + pub eth_host: String, + /// Ethereum RPC port. + pub eth_port: u16, + /// Ethereum chain id. + pub eth_chain_id: u64, + /// Ethereum transactions signer. + pub eth_signer: KeyPair, + /// Gas price we agree to pay. + pub eth_gas_price: U256, + /// Ethereum contract bytecode. + pub eth_contract_code: Vec, + /// Substrate RPC host. + pub sub_host: String, + /// Substrate RPC port. + pub sub_port: u16, + /// Initial authorities set id. + pub sub_initial_authorities_set_id: Option, + /// Initial authorities set. + pub sub_initial_authorities_set: Option>, + /// Initial header. + pub sub_initial_header: Option>, +} + +impl Default for EthereumDeployContractParams { + fn default() -> Self { + EthereumDeployContractParams { + eth_host: "localhost".into(), + eth_port: 8545, + eth_chain_id: 0x11, // Parity dev chain + // that the account that has a lot of ether when we run instant seal engine + // address: 0x00a329c0648769a73afac7f9381e08fb43dbea72 + // secret: 0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7 + eth_signer: KeyPair::from_secret_slice( + &hex::decode("4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7") + .expect("secret is hardcoded, thus valid; qed"), + ).expect("secret is hardcoded, thus valid; qed"), + eth_gas_price: 8_000_000_000u64.into(), // 8 Gwei + eth_contract_code: hex::decode("60806040523480156200001157600080fd5b50604051620012e2380380620012e2833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b838201915060208201858111156200006f57600080fd5b82518660018202830111640100000000821117156200008d57600080fd5b8083526020830192505050908051906020019080838360005b83811015620000c3578082015181840152602081019050620000a6565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b5060405260200180519060200190929190805160405193929190846401000000008211156200011f57600080fd5b838201915060208201858111156200013657600080fd5b82518660018202830111640100000000821117156200015457600080fd5b8083526020830192505050908051906020019080838360005b838110156200018a5780820151818401526020810190506200016d565b50505050905090810190601f168015620001b85780820380516001836020036101000a031916815260200191505b50604052505050620001c96200044d565b620001d362000471565b620001e66000866200025a60201b60201c565b915091506000620001fd836200039260201b60201c565b90508060018190555084600360000160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555083600360010190805190602001906200024d9291906200048e565b505050505050506200053d565b620002646200044d565b6200026e62000471565b60405180606001604052806000801b815260200185856040516020018083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015620002cf578082015181840152602081019050620002b2565b50505050905090810190601f168015620002fd5780820380516001836020036101000a031916815260200191505b50935050505060405160208183030381529060405280519060200120604051602001808281526020019150506040516020818303038152906040528152602001856040516020018082815260200191505060405160208183030381529060405281525060405180604001604052806000801b815260200160405180602001604052806000815250815250915091509250929050565b6000808260200151805190602001209050600060025490506000801b8114620003d1578160056000838152602001908152602001600020600001819055505b83600560008481526020019081526020016000206000820151816000015560208201518160010190805190602001906200040d9291906200048e565b5060408201518160020190805190602001906200042c9291906200048e565b50905050816002819055506001600054016000819055508192505050919050565b60405180606001604052806000801916815260200160608152602001606081525090565b604051806040016040528060008019168152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620004d157805160ff191683800117855562000502565b8280016001018555821562000502579182015b8281111562000501578251825591602001919060010190620004e4565b5b50905062000511919062000515565b5090565b6200053a91905b80821115620005365760008160009055506001016200051c565b5090565b90565b610d95806200054d6000396000f3fe608060405234801561001057600080fd5b50600436106100455760003560e01c80635fb234d31461004b578063bf3a82371461019d578063d96a2deb1461027057610046565b5b600080fd5b61019b6004803603604081101561006157600080fd5b810190808035906020019064010000000081111561007e57600080fd5b82018360208201111561009057600080fd5b803590602001918460018302840111640100000000831117156100b257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561011557600080fd5b82018360208201111561012757600080fd5b8035906020019184600183028401116401000000008311171561014957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061035f565b005b610256600480360360208110156101b357600080fd5b81019080803590602001906401000000008111156101d057600080fd5b8201836020820111156101e257600080fd5b8035906020019184600183028401116401000000008311171561020457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610704565b604051808215151515815260200191505060405180910390f35b610278610742565b604051808060200180602001838103835285818151815260200191508051906020019080838360005b838110156102bc5780820151818401526020810190506102a1565b50505050905090810190601f1680156102e95780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015610322578082015181840152602081019050610307565b50505050905090810190601f16801561034f5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390f35b6000806104d5600360000160009054906101000a900467ffffffffffffffff1660036001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104185780601f106103ed57610100808354040283529160200191610418565b820191906000526020600020905b8154815290600101906020018083116103fb57829003601f168201915b50505050506005600060025481526020019081526020016000206001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104c95780601f1061049e576101008083540402835291602001916104c9565b820191906000526020600020905b8154815290600101906020018083116104ac57829003601f168201915b505050505087876108a7565b91509150600080905060008390505b828110156106c1576104f4610bd6565b6104fc610bfa565b61050683896108c1565b9150915060008260400151805190602001209050610523836109f2565b5060008260200151511461053b5761053a82610aa8565b5b6060600660008381526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105e45780601f106105b9576101008083540402835291602001916105e4565b820191906000526020600020905b8154815290600101906020018083116105c757829003601f168201915b5050505050905060008151146106b257851561064b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180610d286038913960400191505060405180910390fd5b600195506001600360000160009054906101000a900467ffffffffffffffff1601600360000160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555080600360010190805190602001906106b0929190610c17565b505b505050508060010190506104e4565b5061040060005411156106fd57600061040060005403905060008090505b818110156106fa576106ef610b5f565b8060010190506106df565b50505b5050505050565b600080600560008480519060200120815260200190815260200160002060010180546001816001161561010002031660029004905014159050919050565b606080600060056000600254815260200190815260200160002090508060020181600101818054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156107fb5780601f106107d0576101008083540402835291602001916107fb565b820191906000526020600020905b8154815290600101906020018083116107de57829003601f168201915b50505050509150808054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108975780601f1061086c57610100808354040283529160200191610897565b820191906000526020600020905b81548152906001019060200180831161087a57829003601f168201915b5050505050905092509250509091565b600080600080819150809050915091509550959350505050565b6108c9610bd6565b6108d1610bfa565b60405180606001604052806000801b815260200185856040516020018083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610930578082015181840152602081019050610915565b50505050905090810190601f16801561095d5780820380516001836020036101000a031916815260200191505b50935050505060405160208183030381529060405280519060200120604051602001808281526020019150506040516020818303038152906040528152602001856040516020018082815260200191505060405160208183030381529060405281525060405180604001604052806000801b815260200160405180602001604052806000815250815250915091509250929050565b6000808260200151805190602001209050600060025490506000801b8114610a30578160056000838152602001908152602001600020600001819055505b8360056000848152602001908152602001600020600082015181600001556020820151816001019080519060200190610a6a929190610c17565b506040820151816002019080519060200190610a87929190610c17565b50905050816002819055506001600054016000819055508192505050919050565b6000600660008360000151815260200190815260200160002080546001816001161561010002031660029004905014610b2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180610d056023913960400191505060405180910390fd5b806020015160066000836000015181526020019081526020016000209080519060200190610b5b929190610c17565b5050565b600060015490506000600560008381526020019081526020016000209050806000015460018190555060056000838152602001908152602001600020600080820160009055600182016000610bb49190610c97565b600282016000610bc49190610c97565b50506001600054036000819055505050565b60405180606001604052806000801916815260200160608152602001606081525090565b604051806040016040528060008019168152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610c5857805160ff1916838001178555610c86565b82800160010185558215610c86579182015b82811115610c85578251825591602001919060010190610c6a565b5b509050610c939190610cdf565b5090565b50805460018160011615610100020316600290046000825580601f10610cbd5750610cdc565b601f016020900490600052602060002090810190610cdb9190610cdf565b5b50565b610d0191905b80821115610cfd576000816000905550600101610ce5565b5090565b9056fe4475706c6963617465207369676e616c20666f72207468652073616d6520626c6f636b547279696e6720746f20656e616374207365766572616c2073657473207573696e672073696e676c652066696e616c6974792070726f6f66a26469706673582212201dfa6c78befea4189891d2753946bda7e7033a5300d644d6ada1f098ea3a315464736f6c63430006050033") + .expect("code is hardcoded, thus valid; qed"), + sub_host: "localhost".into(), + sub_port: 9933, + sub_initial_authorities_set_id: None, + sub_initial_authorities_set: None, + sub_initial_header: None, + } + } +} + +/// Deploy Bridge contract on Ethereum chain. +pub fn run(params: EthereumDeployContractParams) { + let mut local_pool = futures::executor::LocalPool::new(); + + let result = local_pool.run_until(async move { + let eth_uri = format!("http://{}:{}", params.eth_host, params.eth_port); + let eth_client = ethereum_client::client(ð_uri); + + let sub_uri = format!("http://{}:{}", params.sub_host, params.sub_port); + let sub_client = substrate_client::client(&sub_uri); + + let (sub_client, initial_header) = prepare_initial_header(sub_client, params.sub_initial_header).await; + let (initial_header_hash, initial_header) = initial_header?; + + let initial_set_id = params.sub_initial_authorities_set_id.unwrap_or(0); + let (_, initial_set) = prepare_initial_authorities_set( + sub_client, + initial_header_hash, + params.sub_initial_authorities_set, + ).await; + let initial_set = initial_set?; + + ethereum_client::deploy_bridge_contract( + eth_client, + params.eth_signer, + params.eth_chain_id, + params.eth_gas_price, + params.eth_contract_code, + initial_header.encode(), + initial_set_id, + initial_set, + ).await.1.map_err(|error| format!("Error deploying contract: {:?}", error)) + }); + + if let Err(error) = result { + log::error!(target: "bridge", "{}", error); + } +} + +/// Prepare initial header. +async fn prepare_initial_header( + sub_client: substrate_client::Client, + sub_initial_header: Option>, +) -> (substrate_client::Client, Result<(SubstrateHash, Vec), String>) { + match sub_initial_header { + Some(raw_initial_header) => { + match SubstrateHeader::decode(&mut &raw_initial_header[..]) { + Ok(initial_header) => (sub_client, Ok((initial_header.hash(), raw_initial_header))), + Err(error) => (sub_client, Err(format!("Error decoding initial header: {}", error))), + } + }, + None => { + let (sub_client, initial_header) = substrate_client::header_by_number( + sub_client, + Zero::zero(), + ).await; + ( + sub_client, + initial_header + .map(|header| (header.hash(), header.encode())) + .map_err(|error| format!("Error reading Substrate genesis header: {:?}", error)) + ) + }, + } +} + +/// Prepare initial GRANDPA authorities set. +async fn prepare_initial_authorities_set( + sub_client: substrate_client::Client, + sub_initial_header_hash: SubstrateHash, + sub_initial_authorities_set: Option>, +) -> (substrate_client::Client, Result, String>) { + let (sub_client, initial_authorities_set) = match sub_initial_authorities_set { + Some(initial_authorities_set) => (sub_client, Ok(initial_authorities_set)), + None => substrate_client::grandpa_authorities_set( + sub_client, + sub_initial_header_hash, + ).await, + }; + + ( + sub_client, + initial_authorities_set + .map_err(|error| format!("Error reading GRANDPA authorities set: {:?}", error)), + ) +} diff --git a/relays/ethereum/src/main.rs b/relays/ethereum/src/main.rs index 8db2722072..f2456e1914 100644 --- a/relays/ethereum/src/main.rs +++ b/relays/ethereum/src/main.rs @@ -17,6 +17,7 @@ #![recursion_limit = "1024"] mod ethereum_client; +mod ethereum_deploy_contract; mod ethereum_sync_loop; mod ethereum_types; mod headers; @@ -55,6 +56,15 @@ fn main() { } }); }, + ("eth-deploy-contract", Some(eth_deploy_matches)) => { + ethereum_deploy_contract::run(match ethereum_deploy_contract_params(ð_deploy_matches) { + Ok(ethereum_deploy_matches) => ethereum_deploy_matches, + Err(err) => { + log::error!(target: "bridge", "Error parsing parameters: {}", err); + return; + } + }); + }, ("", _) => { log::error!(target: "bridge", "No subcommand specified"); return; @@ -145,7 +155,7 @@ fn substrate_sync_params(matches: &clap::ArgMatches) -> Result Result Result { + let mut eth_deploy_params = ethereum_deploy_contract::EthereumDeployContractParams::default(); + if let Some(eth_host) = matches.value_of("eth-host") { + eth_deploy_params.eth_host = eth_host.into(); + } + if let Some(eth_port) = matches.value_of("eth-port") { + eth_deploy_params.eth_port = eth_port.parse().map_err(|e| format!("{}", e))?; + } + if let Some(eth_signer) = matches.value_of("eth-signer") { + eth_deploy_params.eth_signer = KeyPair::from_secret( + eth_signer.parse().map_err(|e| format!("{}", e))? + ).map_err(|e| format!("{}", e))?; + } + + Ok(eth_deploy_params) +} diff --git a/relays/ethereum/src/substrate_client.rs b/relays/ethereum/src/substrate_client.rs index 56748561f2..0ef3dbc777 100644 --- a/relays/ethereum/src/substrate_client.rs +++ b/relays/ethereum/src/substrate_client.rs @@ -25,6 +25,7 @@ use codec::{Decode, Encode}; use jsonrpsee::common::Params; use jsonrpsee::raw::{RawClient, RawClientError}; use jsonrpsee::transport::http::{HttpTransportClient, RequestError}; +use num_traits::Zero; use serde_json::{from_value, to_value}; use sp_core::crypto::Pair; use sp_runtime::traits::IdentifyAccount; @@ -70,7 +71,7 @@ pub fn client(uri: &str) -> Client { /// Returns best Substrate header. pub async fn best_header(client: Client) -> (Client, Result) { - call_rpc( + call_rpc_header( client, "chain_getHeader", Params::None, @@ -80,7 +81,7 @@ pub async fn best_header(client: Client) -> (Client, Result (Client, Result) { - call_rpc( + call_rpc_header( client, "chain_getHeader", Params::Array(vec![ @@ -92,14 +93,7 @@ pub async fn header_by_hash(client: Client, hash: Hash) -> (Client, Result (Client, Result) { - let (client, hash) = call_rpc( - client, - "chain_getBlockHash", - Params::Array(vec![ - to_value(number).unwrap(), - ]), - ) - .await; + let (client, hash) = block_hash_by_number(client, number).await; let hash = match hash { Ok(hash) => hash, Err(error) => return (client, Err(error)), @@ -196,7 +190,7 @@ pub async fn submit_signed_ethereum_headers( let (client, genesis_hash) = match client.genesis_hash { Some(genesis_hash) => (client, genesis_hash), None => { - let (mut client, genesis_hash) = block_hash_by_number(client, 0).await; + let (mut client, genesis_hash) = block_hash_by_number(client, Zero::zero()).await; let genesis_hash = match genesis_hash { Ok(genesis_hash) => genesis_hash, Err(err) => return (client, Err(err)), @@ -255,14 +249,26 @@ pub async fn submit_unsigned_ethereum_headers( (client, Ok((transactions_hashes, ids))) } +/// Get GRANDPA authorities set at given block. +pub async fn grandpa_authorities_set(client: Client, block: Hash) -> (Client, Result, Error>) { + call_rpc( + client, + "state_call", + Params::Array(vec![ + to_value("GrandpaApi_grandpa_authorities").unwrap(), + to_value(block).unwrap(), + ]), + ) + .await +} + /// Get Substrate block hash by its number. -async fn block_hash_by_number(client: Client, number: u64) -> (Client, Result) { +async fn block_hash_by_number(client: Client, number: Number) -> (Client, Result) { call_rpc( client, "chain_getBlockHash", Params::Array(vec![to_value(number).unwrap()]), - ) - .await + ).await } /// Get substrate account nonce. @@ -305,6 +311,29 @@ async fn call_rpc(mut client: Client, method: &'static str, params: P (client, result) } +/// Calls RPC on Substrate node that returns Header. +async fn call_rpc_header(mut client: Client, method: &'static str, params: Params) -> (Client, Result) { + async fn do_call_rpc(client: &mut Client, method: &'static str, params: Params) -> Result { + let request_id = client + .rpc_client + .start_request(method, params) + .await + .map_err(Error::StartRequestFailed)?; + // WARN: if there'll be need for executing >1 request at a time, we should avoid + // calling request_by_id + let response = client + .rpc_client + .request_by_id(request_id) + .ok_or(Error::RequestNotFound)? + .await + .map_err(Error::ResponseRetrievalFailed)?; + from_value(response).map_err(|_| Error::ResponseParseFailed) + } + + let result = do_call_rpc(&mut client, method, params).await; + (client, result) +} + /// Calls RPC on Substrate node that returns u64. async fn call_rpc_u64(mut client: Client, method: &'static str, params: Params) -> (Client, Result) { async fn do_call_rpc(client: &mut Client, method: &'static str, params: Params) -> Result { diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index f820e96351..7aa3a528ac 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -61,8 +61,11 @@ impl Default for SubstrateSyncParams { SubstrateSyncParams { eth_host: "localhost".into(), eth_port: 8545, - eth_chain_id: 1, // Ethereum mainnet - eth_contract_address: Default::default(), + eth_chain_id: 0x11, // Parity dev chain + // the address 0x731a10897d267e19b34503ad902d0a29173ba4b1 is the address + // of the contract that is deployed by default signer and 0 nonce + eth_contract_address: "731a10897d267e19b34503ad902d0a29173ba4b1".parse() + .expect("address is hardcoded, thus valid; qed"), // that the account that has a lot of ether when we run instant seal engine // address: 0x00a329c0648769a73afac7f9381e08fb43dbea72 // secret: 0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7 From cfc92355e02d96626d2d6c49855957924d5a9a92 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 9 Apr 2020 17:14:30 +0300 Subject: [PATCH 14/92] some fixes --- Cargo.lock | 2 -- relays/ethereum/src/cli.yml | 1 - relays/ethereum/src/sync_loop.rs | 13 ++++++++++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5f2a2218c5..e297361d67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -447,10 +447,8 @@ version = "0.1.0" dependencies = [ "bridge-node-runtime", "futures 0.3.4", - "hex", "jsonrpc-core", "log 0.4.8", - "parity-scale-codec", "sc-basic-authorship", "sc-cli", "sc-client", diff --git a/relays/ethereum/src/cli.yml b/relays/ethereum/src/cli.yml index f9ff76edcd..31ba127590 100644 --- a/relays/ethereum/src/cli.yml +++ b/relays/ethereum/src/cli.yml @@ -61,7 +61,6 @@ subcommands: value_name: ETH_CONTRACT help: Address of deployed bridge contract. takes_value: true - required: true - eth-signer: long: eth-signer value_name: ETH_SIGNER diff --git a/relays/ethereum/src/sync_loop.rs b/relays/ethereum/src/sync_loop.rs index 803cfaf0c2..b2e97c9794 100644 --- a/relays/ethereum/src/sync_loop.rs +++ b/relays/ethereum/src/sync_loop.rs @@ -17,7 +17,7 @@ use crate::sync::HeadersSyncParams; use crate::sync_types::{HeaderId, HeaderStatus, HeadersSyncPipeline, MaybeConnectionError, QueuedHeader}; use futures::{future::FutureExt, stream::StreamExt}; -use num_traits::Saturating; +use num_traits::{Saturating, Zero}; use std::future::Future; /// When we submit headers to target node, but see no updates of best @@ -365,6 +365,17 @@ pub fn run( // for Orphan we actually ask for parent' header let parent_id = header.parent_id(); + // if we have end up with orphan header#0, then we are misconfigured + if parent_id.0.is_zero() { + log::error!( + target: "bridge", + "Misconfiguration. Genesis {} header is considered orphan by {} node", + P::SOURCE_NAME, + P::TARGET_NAME, + ); + return; + } + log::debug!( target: "bridge", "Going to download orphan header from {} node: {:?}", From b73aa54e16dbf5b3c22853bddaa423c1396d1a19 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 10 Apr 2020 17:15:33 +0300 Subject: [PATCH 15/92] contract v2 --- .../contracts/substrate-bridge.sol | 18 +- .../contracts/substrate-bridge2.sol | 312 ++++++++++++++++++ relays/ethereum/res/substrate-bridge.json | 59 +++- relays/ethereum/src/ethereum_client.rs | 2 +- .../ethereum/src/ethereum_deploy_contract.rs | 15 +- relays/ethereum/src/substrate_sync_loop.rs | 4 +- relays/ethereum/src/substrate_types.rs | 2 +- 7 files changed, 393 insertions(+), 19 deletions(-) create mode 100644 modules/ethereum-contract/contracts/substrate-bridge2.sol diff --git a/modules/ethereum-contract/contracts/substrate-bridge.sol b/modules/ethereum-contract/contracts/substrate-bridge.sol index b73717ef00..452d310101 100644 --- a/modules/ethereum-contract/contracts/substrate-bridge.sol +++ b/modules/ethereum-contract/contracts/substrate-bridge.sol @@ -189,7 +189,23 @@ contract SubstrateBridge { function parseSubstrateHeader( uint256 headerIndex, bytes memory rawHeaders - ) private pure returns (Header memory, VoterSetSignal memory) { + ) private returns (Header memory, VoterSetSignal memory) { + // https://ethereum.stackexchange.com/questions/76346/how-to-call-ecrecover-in-pure-assembly + assembly { + let pointer := mload(0x40) + let rawHeadersLength := mload(rawHeaders) + let rawHeadersPointer := add(rawHeaders, 0x20) +/* mstore(pointer, headerIndex) + mstore(add(pointer, 0x20), rawHeaders) + mstore(add(pointer, 0x40), rawHeadersLength)*/ + // ?, builtin_address, in_off, in_size, out_off, out_size + // call parse: staticcall(?, builtinAddress, inPointer, inSize, outPointer, outSize) + if iszero(staticcall(not(0), 0x10, rawHeadersPointer, rawHeadersLength, pointer, 0x00)) { + revert(0, 0) + } + } + + return ( Header({ nextHeaderKeccak: bytes32(0), diff --git a/modules/ethereum-contract/contracts/substrate-bridge2.sol b/modules/ethereum-contract/contracts/substrate-bridge2.sol new file mode 100644 index 0000000000..d48d17f818 --- /dev/null +++ b/modules/ethereum-contract/contracts/substrate-bridge2.sol @@ -0,0 +1,312 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +pragma solidity ^0.6.4; + +// for simplicity, this contract works with 32-bit headers hashes and headers +// numbers that can be represented as uint256 (supporting uint256 arithmetics) + +/// @title Substrate-to-PoA Bridge Contract. +contract SubstrateBridge { + /// Parsed header. + struct ParsedHeader { + /// Header hash. + bytes32 hash; + /// Parent header hash. + bytes32 parentHash; + /// Header number. + uint256 number; + /// Validators set change signal delay. + uint256 signalDelay; + /// Validators set change signal. + bytes signal; + } + + /// Header as it is stored in the storage. + struct Header { + /// Flag to ensure that the header exists :/ + bool isKnown; + + /// Parent header hash. + bytes32 parentHash; + /// Header number. + uint256 number; + + /// Validators set change signal. + bytes signal; + + /// ID of validators set that must finalize this header. This equals to same + /// field of the parent + 1 if parent header should enact new set. + uint64 validatorsSetId; + /// Hash of the latest header of this fork that has emitted last validators set + /// change signal. + bytes32 prevSignalHeaderHash; + /// Number of the header where latest signal of this fork must be enacted. + uint256 prevSignalTargetNumber; + } + + /// Initializes bridge contract. + /// @param rawInitialHeader Raw finalized header that will be ancestor of all importing headers. + /// @param initialValidatorsSetId ID of validators set that must finalize direct children of the initial header. + /// @param initialValidatorsSet Raw validators set that must finalize direct children of the initial header. + constructor( + bytes memory rawInitialHeader, + uint64 initialValidatorsSetId, + bytes memory initialValidatorsSet + ) public { + // parse and save header + ParsedHeader memory header = parseSubstrateHeader(rawInitialHeader); + lastImportedHeaderHash = header.hash; + bestFinalizedHeaderHash = header.hash; + bestFinalizedHeaderNumber = header.number; + headerByHash[header.hash] = Header({ + isKnown: true, + parentHash: header.parentHash, + number: header.number, + signal: header.signal, + validatorsSetId: initialValidatorsSetId, + prevSignalHeaderHash: bytes32(0), + prevSignalTargetNumber: 0 + }); + + // save best validators set + bestFinalizedValidatorsSetId = initialValidatorsSetId; + bestFinalizedValidatorsSet = initialValidatorsSet; + } + + /// Reject direct payments. + fallback() external { revert(); } + + /// Returns number and hash of the best known header. Best known header is + /// the last header we have received, no matter hash or number. We can't + /// verify unfinalized header => we are only signalling relay that we are + /// receiving new headers here, so honest relay can continue to submit valid + /// headers and, eventually, finality proofs. + function bestKnownHeader() public view returns (uint256, bytes32) { + Header storage lastImportedHeader = headerByHash[lastImportedHeaderHash]; + return (lastImportedHeader.number, lastImportedHeaderHash); + } + + /// Returns true if header is known to the bridge. + /// @param headerHash Hash of the header we want to check. + function isKnownHeader( + bytes32 headerHash + ) public view returns (bool) { + return headerByHash[headerHash].isKnown; + } + + /// Returns true if finality proof is required for this header. + function isFinalityProofRequired( + bytes32 headerHash + ) public view returns (bool) { + Header storage header = headerByHash[headerHash]; + return header.isKnown + && header.number > bestFinalizedHeaderNumber + && header.number == header.prevSignalTargetNumber + && header.validatorsSetId == bestFinalizedValidatorsSetId; + } + + /// Import header. + function importHeader( + bytes memory rawHeader + ) public { + // parse and save header + ParsedHeader memory header = parseSubstrateHeader(rawHeader); + Header storage parentHeader = headerByHash[header.parentHash]; + require( + parentHeader.number == header.number - 1, + "Missing parent header from the storage" + ); + + // check if parent header has emitted validators set change signal + uint64 validatorsSetId = parentHeader.validatorsSetId; + bytes32 prevSignalHeaderHash = parentHeader.prevSignalHeaderHash; + if (parentHeader.signal.length != 0) { + prevSignalHeaderHash = header.parentHash; + validatorsSetId = validatorsSetId + 1; + } + + // forbid overlapping signals + uint256 prevSignalTargetNumber = parentHeader.prevSignalTargetNumber; + if (header.signal.length != 0) { + require( + prevSignalTargetNumber < header.number, + "Overlapping signals found" + ); + prevSignalTargetNumber = header.number + header.signalDelay; + } + + // store header in the storage + headerByHash[header.hash] = Header({ + isKnown: true, + parentHash: header.parentHash, + number: header.number, + signal: header.signal, + validatorsSetId: validatorsSetId, + prevSignalHeaderHash: prevSignalHeaderHash, + prevSignalTargetNumber: prevSignalTargetNumber + }); + lastImportedHeaderHash = header.hash; + } + + /// Import finality proof. + function importFinalityProof( + uint256 finalityTargetNumber, + bytes32 finalityTargetHash, + bytes memory rawFinalityProof + ) public { + // check that header that we're going to finalize is already imported + require( + headerByHash[finalityTargetHash].number == finalityTargetNumber, + "Missing finality target header from the storage" + ); + + // verify finality proof + bytes32 oldBestFinalizedHeaderHash = bestFinalizedHeaderHash; + bytes32 newBestFinalizedHeaderHash = verifyFinalityProof( + finalityTargetNumber, + finalityTargetHash, + rawFinalityProof + ); + + // remember new best finalized header + Header storage newFinalizedHeader = headerByHash[newBestFinalizedHeaderHash]; + bestFinalizedHeaderHash = newBestFinalizedHeaderHash; + bestFinalizedHeaderNumber = newFinalizedHeader.number; + + // apply validators set change signal if required + while (newBestFinalizedHeaderHash != oldBestFinalizedHeaderHash) { + newFinalizedHeader = headerByHash[newBestFinalizedHeaderHash]; + newBestFinalizedHeaderHash = newFinalizedHeader.parentHash; + // if we are finalizing header that should enact validators set change, do this + // (this only affects latest scheduled change) + if (newFinalizedHeader.number == newFinalizedHeader.prevSignalTargetNumber) { + Header storage signalHeader = headerByHash[newFinalizedHeader.prevSignalHeaderHash]; + bestFinalizedValidatorsSetId += 1; + bestFinalizedValidatorsSet = signalHeader.signal; + break; + } + } + } + + /// Parse Substrate header. + function parseSubstrateHeader( + bytes memory rawHeader + ) private view returns (ParsedHeader memory) { + bytes32 headerHash; + bytes32 headerParentHash; + uint256 headerNumber; + uint256 headerSignalDelay; + uint256 headerSignalSize; + bytes memory headerSignal; + + assembly { + // inputs + let rawHeadersSize := mload(rawHeader) + let rawHeadersPointer := add(rawHeader, 0x20) + + // output + let headerHashPointer := mload(0x40) + let headerParentHashPointer := add(headerHashPointer, 0x20) + let headerNumberPointer := add(headerParentHashPointer, 0x20) + let headerSignalDelayPointer := add(headerNumberPointer, 0x20) + let headerSignalSizePointer := add(headerSignalDelayPointer, 0x20) + + // parse substrate header + if iszero(staticcall( + not(0), + SUBSTRATE_PARSE_HEADER_BUILTIN_ADDRESS, + rawHeadersPointer, + rawHeadersSize, + headerHashPointer, + 0xA0 + )) { + revert(0, 0) + } + + // fill basic header fields + headerHash := mload(headerHashPointer) + headerParentHash := mload(headerParentHashPointer) + headerNumber := mload(headerNumberPointer) + headerSignalDelay := mload(headerSignalDelayPointer) + headerSignalSize := mload(headerSignalSizePointer) + } + + // if validators set change is signalled, read it + if (headerSignalSize != 0) { + headerSignal = new bytes(headerSignalSize); + + assembly { + // inputs + let rawHeadersSize := mload(rawHeader) + let rawHeadersPointer := add(rawHeader, 0x20) + + // output + let headerSignalPointer := add(headerSignal, 0x20) + + // get substrate header valdiators set change signal + if iszero(staticcall( + not(0), + SUBSTRATE_GET_HEADER_SIGNAL_BUILTIN_ADDRESS, + rawHeadersPointer, + rawHeadersSize, + headerSignalPointer, + headerSignalSize + )) { + revert(0, 0) + } + } + } + + return ParsedHeader({ + hash: headerHash, + parentHash: headerParentHash, + number: headerNumber, + signalDelay: headerSignalDelay, + signal: headerSignal + }); + } + + + /// Verify finality proof. + function verifyFinalityProof( + uint256 /*finalityTargetNumber*/, + bytes32 /*finalityTargetHash*/, + bytes memory /*rawFinalityProof*/ + ) private view returns (bytes32) { + return bestFinalizedHeaderHash; // TODO: call builtin instead + } + + /// Address of parse_substrate_header builtin. + uint256 constant SUBSTRATE_PARSE_HEADER_BUILTIN_ADDRESS = 0x10; + /// Address of get_substrate_validators_set_signal builtin. + uint256 constant SUBSTRATE_GET_HEADER_SIGNAL_BUILTIN_ADDRESS = 0x11; + + /// Last imported header hash. + bytes32 lastImportedHeaderHash; + + /// Best finalized header number. + uint256 bestFinalizedHeaderNumber; + /// Best finalized header hash. + bytes32 bestFinalizedHeaderHash; + /// Best finalized validators set id. + uint64 bestFinalizedValidatorsSetId; + /// Best finalized validators set. + bytes bestFinalizedValidatorsSet; + + /// Map of headers by their hashes. + mapping (bytes32 => Header) headerByHash; +} diff --git a/relays/ethereum/res/substrate-bridge.json b/relays/ethereum/res/substrate-bridge.json index 949bf23b3d..58576c29b8 100644 --- a/relays/ethereum/res/substrate-bridge.json +++ b/relays/ethereum/res/substrate-bridge.json @@ -8,12 +8,12 @@ }, { "internalType": "uint64", - "name": "initialVotersSetId", + "name": "initialValidatorsSetId", "type": "uint64" }, { "internalType": "bytes", - "name": "initialRawVoters", + "name": "initialValidatorsSet", "type": "bytes" } ], @@ -29,14 +29,14 @@ "name": "bestKnownHeader", "outputs": [ { - "internalType": "bytes", + "internalType": "uint256", "name": "", - "type": "bytes" + "type": "uint256" }, { - "internalType": "bytes", + "internalType": "bytes32", "name": "", - "type": "bytes" + "type": "bytes32" } ], "stateMutability": "view", @@ -45,9 +45,14 @@ { "inputs": [ { - "internalType": "bytes", - "name": "rawHeaders", - "type": "bytes" + "internalType": "uint256", + "name": "finalityTargetNumber", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "finalityTargetHash", + "type": "bytes32" }, { "internalType": "bytes", @@ -55,7 +60,7 @@ "type": "bytes" } ], - "name": "importHeaders", + "name": "importFinalityProof", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -64,10 +69,42 @@ "inputs": [ { "internalType": "bytes", - "name": "headerHash", + "name": "rawHeader", "type": "bytes" } ], + "name": "importHeader", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "headerHash", + "type": "bytes32" + } + ], + "name": "isFinalityProofRequired", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "headerHash", + "type": "bytes32" + } + ], "name": "isKnownHeader", "outputs": [ { diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index 8de1eed482..d6abb2ec48 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -312,7 +312,7 @@ pub async fn deploy_bridge_contract( ) -> (Client, Result) { let encoded_call = bridge_contract::constructor( contract_code, - vec![initial_header].encode(), + initial_header.encode(), initial_set_id, initial_authorities, ); diff --git a/relays/ethereum/src/ethereum_deploy_contract.rs b/relays/ethereum/src/ethereum_deploy_contract.rs index 6e9ebeda12..af673d2e98 100644 --- a/relays/ethereum/src/ethereum_deploy_contract.rs +++ b/relays/ethereum/src/ethereum_deploy_contract.rs @@ -63,7 +63,7 @@ impl Default for EthereumDeployContractParams { .expect("secret is hardcoded, thus valid; qed"), ).expect("secret is hardcoded, thus valid; qed"), eth_gas_price: 8_000_000_000u64.into(), // 8 Gwei - eth_contract_code: hex::decode("60806040523480156200001157600080fd5b50604051620012e2380380620012e2833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b838201915060208201858111156200006f57600080fd5b82518660018202830111640100000000821117156200008d57600080fd5b8083526020830192505050908051906020019080838360005b83811015620000c3578082015181840152602081019050620000a6565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b5060405260200180519060200190929190805160405193929190846401000000008211156200011f57600080fd5b838201915060208201858111156200013657600080fd5b82518660018202830111640100000000821117156200015457600080fd5b8083526020830192505050908051906020019080838360005b838110156200018a5780820151818401526020810190506200016d565b50505050905090810190601f168015620001b85780820380516001836020036101000a031916815260200191505b50604052505050620001c96200044d565b620001d362000471565b620001e66000866200025a60201b60201c565b915091506000620001fd836200039260201b60201c565b90508060018190555084600360000160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555083600360010190805190602001906200024d9291906200048e565b505050505050506200053d565b620002646200044d565b6200026e62000471565b60405180606001604052806000801b815260200185856040516020018083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015620002cf578082015181840152602081019050620002b2565b50505050905090810190601f168015620002fd5780820380516001836020036101000a031916815260200191505b50935050505060405160208183030381529060405280519060200120604051602001808281526020019150506040516020818303038152906040528152602001856040516020018082815260200191505060405160208183030381529060405281525060405180604001604052806000801b815260200160405180602001604052806000815250815250915091509250929050565b6000808260200151805190602001209050600060025490506000801b8114620003d1578160056000838152602001908152602001600020600001819055505b83600560008481526020019081526020016000206000820151816000015560208201518160010190805190602001906200040d9291906200048e565b5060408201518160020190805190602001906200042c9291906200048e565b50905050816002819055506001600054016000819055508192505050919050565b60405180606001604052806000801916815260200160608152602001606081525090565b604051806040016040528060008019168152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620004d157805160ff191683800117855562000502565b8280016001018555821562000502579182015b8281111562000501578251825591602001919060010190620004e4565b5b50905062000511919062000515565b5090565b6200053a91905b80821115620005365760008160009055506001016200051c565b5090565b90565b610d95806200054d6000396000f3fe608060405234801561001057600080fd5b50600436106100455760003560e01c80635fb234d31461004b578063bf3a82371461019d578063d96a2deb1461027057610046565b5b600080fd5b61019b6004803603604081101561006157600080fd5b810190808035906020019064010000000081111561007e57600080fd5b82018360208201111561009057600080fd5b803590602001918460018302840111640100000000831117156100b257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561011557600080fd5b82018360208201111561012757600080fd5b8035906020019184600183028401116401000000008311171561014957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061035f565b005b610256600480360360208110156101b357600080fd5b81019080803590602001906401000000008111156101d057600080fd5b8201836020820111156101e257600080fd5b8035906020019184600183028401116401000000008311171561020457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610704565b604051808215151515815260200191505060405180910390f35b610278610742565b604051808060200180602001838103835285818151815260200191508051906020019080838360005b838110156102bc5780820151818401526020810190506102a1565b50505050905090810190601f1680156102e95780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015610322578082015181840152602081019050610307565b50505050905090810190601f16801561034f5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390f35b6000806104d5600360000160009054906101000a900467ffffffffffffffff1660036001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104185780601f106103ed57610100808354040283529160200191610418565b820191906000526020600020905b8154815290600101906020018083116103fb57829003601f168201915b50505050506005600060025481526020019081526020016000206001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104c95780601f1061049e576101008083540402835291602001916104c9565b820191906000526020600020905b8154815290600101906020018083116104ac57829003601f168201915b505050505087876108a7565b91509150600080905060008390505b828110156106c1576104f4610bd6565b6104fc610bfa565b61050683896108c1565b9150915060008260400151805190602001209050610523836109f2565b5060008260200151511461053b5761053a82610aa8565b5b6060600660008381526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105e45780601f106105b9576101008083540402835291602001916105e4565b820191906000526020600020905b8154815290600101906020018083116105c757829003601f168201915b5050505050905060008151146106b257851561064b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180610d286038913960400191505060405180910390fd5b600195506001600360000160009054906101000a900467ffffffffffffffff1601600360000160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555080600360010190805190602001906106b0929190610c17565b505b505050508060010190506104e4565b5061040060005411156106fd57600061040060005403905060008090505b818110156106fa576106ef610b5f565b8060010190506106df565b50505b5050505050565b600080600560008480519060200120815260200190815260200160002060010180546001816001161561010002031660029004905014159050919050565b606080600060056000600254815260200190815260200160002090508060020181600101818054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156107fb5780601f106107d0576101008083540402835291602001916107fb565b820191906000526020600020905b8154815290600101906020018083116107de57829003601f168201915b50505050509150808054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108975780601f1061086c57610100808354040283529160200191610897565b820191906000526020600020905b81548152906001019060200180831161087a57829003601f168201915b5050505050905092509250509091565b600080600080819150809050915091509550959350505050565b6108c9610bd6565b6108d1610bfa565b60405180606001604052806000801b815260200185856040516020018083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610930578082015181840152602081019050610915565b50505050905090810190601f16801561095d5780820380516001836020036101000a031916815260200191505b50935050505060405160208183030381529060405280519060200120604051602001808281526020019150506040516020818303038152906040528152602001856040516020018082815260200191505060405160208183030381529060405281525060405180604001604052806000801b815260200160405180602001604052806000815250815250915091509250929050565b6000808260200151805190602001209050600060025490506000801b8114610a30578160056000838152602001908152602001600020600001819055505b8360056000848152602001908152602001600020600082015181600001556020820151816001019080519060200190610a6a929190610c17565b506040820151816002019080519060200190610a87929190610c17565b50905050816002819055506001600054016000819055508192505050919050565b6000600660008360000151815260200190815260200160002080546001816001161561010002031660029004905014610b2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180610d056023913960400191505060405180910390fd5b806020015160066000836000015181526020019081526020016000209080519060200190610b5b929190610c17565b5050565b600060015490506000600560008381526020019081526020016000209050806000015460018190555060056000838152602001908152602001600020600080820160009055600182016000610bb49190610c97565b600282016000610bc49190610c97565b50506001600054036000819055505050565b60405180606001604052806000801916815260200160608152602001606081525090565b604051806040016040528060008019168152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610c5857805160ff1916838001178555610c86565b82800160010185558215610c86579182015b82811115610c85578251825591602001919060010190610c6a565b5b509050610c939190610cdf565b5090565b50805460018160011615610100020316600290046000825580601f10610cbd5750610cdc565b601f016020900490600052602060002090810190610cdb9190610cdf565b5b50565b610d0191905b80821115610cfd576000816000905550600101610ce5565b5090565b9056fe4475706c6963617465207369676e616c20666f72207468652073616d6520626c6f636b547279696e6720746f20656e616374207365766572616c2073657473207573696e672073696e676c652066696e616c6974792070726f6f66a26469706673582212201dfa6c78befea4189891d2753946bda7e7033a5300d644d6ada1f098ea3a315464736f6c63430006050033") + eth_contract_code: hex::decode("60806040523480156200001157600080fd5b5060405162000fe538038062000fe5833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b838201915060208201858111156200006f57600080fd5b82518660018202830111640100000000821117156200008d57600080fd5b8083526020830192505050908051906020019080838360005b83811015620000c3578082015181840152602081019050620000a6565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b5060405260200180519060200190929190805160405193929190846401000000008211156200011f57600080fd5b838201915060208201858111156200013657600080fd5b82518660018202830111640100000000821117156200015457600080fd5b8083526020830192505050908051906020019080838360005b838110156200018a5780820151818401526020810190506200016d565b50505050905090810190601f168015620001b85780820380516001836020036101000a031916815260200191505b50604052505050620001c962000454565b620001da846200034960201b60201c565b90508060000151600081905550806000015160028190555080604001516001819055506040518060e001604052806001151581526020018260200151815260200182604001518152602001826080015181526020018467ffffffffffffffff1681526020016000801b81526020016000815250600560008360000151815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160010155604082015181600201556060820151816003019080519060200190620002b692919062000489565b5060808201518160040160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060a0820151816005015560c0820151816006015590505082600360006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555081600490805190602001906200033e92919062000489565b505050505062000538565b6200035362000454565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa6200038b57600080fd5b84519c5083519b5082519a508151995080519850505050505050506000821462000420578167ffffffffffffffff81118015620003c757600080fd5b506040519080825280601f01601f191660200182016040528015620003fb5781602001600182028036833780820191505090505b50905087516020890160208301848184846011600019fa6200041c57600080fd5b5050505b6040518060a00160405280878152602001868152602001858152602001848152602001828152509650505050505050919050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620004cc57805160ff1916838001178555620004fd565b82800160010185558215620004fd579182015b82811115620004fc578251825591602001919060010190620004df565b5b5090506200050c919062000510565b5090565b6200053591905b808211156200053157600081600090555060010162000517565b5090565b90565b610a9d80620005486000396000f3fe608060405234801561001057600080fd5b506004361061005b5760003560e01c8063871ebe1814610061578063a98bfaad146100a7578063d96a2deb146100ed578063e7af077914610112578063fae71ae8146101cd5761005c565b5b600080fd5b61008d6004803603602081101561007757600080fd5b810190808035906020019092919050505061029c565b604051808215151515815260200191505060405180910390f35b6100d3600480360360208110156100bd57600080fd5b81019080803590602001909291905050506102c9565b604051808215151515815260200191505060405180910390f35b6100f561036c565b604051808381526020018281526020019250505060405180910390f35b6101cb6004803603602081101561012857600080fd5b810190808035906020019064010000000081111561014557600080fd5b82018360208201111561015757600080fd5b8035906020019184600183028401116401000000008311171561017957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610398565b005b61029a600480360360608110156101e357600080fd5b8101908080359060200190929190803590602001909291908035906020019064010000000081111561021457600080fd5b82018360208201111561022657600080fd5b8035906020019184600183028401116401000000008311171561024857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610627565b005b60006005600083815260200190815260200160002060000160009054906101000a900460ff169050919050565b6000806005600084815260200190815260200160002090508060000160009054906101000a900460ff16801561030457506001548160020154115b8015610317575080600601548160020154145b80156103645750600360009054906101000a900467ffffffffffffffff1667ffffffffffffffff168160040160009054906101000a900467ffffffffffffffff1667ffffffffffffffff16145b915050919050565b600080600060056000805481526020019081526020016000209050806002015460005492509250509091565b6103a06108b1565b6103a98261079f565b90506000600560008360200151815260200190815260200160002090506001826040015103816002015414610429576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610a136026913960400191505060405180910390fd5b60008160040160009054906101000a900467ffffffffffffffff1690506000826005015490506000836003018054600181600116156101000203166002900490501461047d57836020015190506001820191505b60008360060154905060008560800151511461051a578460400151811061050c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4f7665726c617070696e67207369676e616c7320666f756e640000000000000081525060200191505060405180910390fd5b846060015185604001510190505b6040518060e001604052806001151581526020018660200151815260200186604001518152602001866080015181526020018467ffffffffffffffff16815260200183815260200182815250600560008760000151815260200190815260200160002060008201518160000160006101000a81548160ff021916908315150217905550602082015181600101556040820151816002015560608201518160030190805190602001906105cd9291906108e6565b5060808201518160040160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060a0820151816005015560c082015181600601559050508460000151600081905550505050505050565b82600560008481526020019081526020016000206002015414610695576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180610a39602f913960400191505060405180910390fd5b6000600254905060006106a98585856108a3565b905060006005600083815260200190815260200160002090508160028190555080600201546001819055505b8282146107975760056000838152602001908152602001600020905080600101549150806006015481600201541415610792576000600560008360050154815260200190815260200160002090506001600360008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550806003016004908054600181600116156101000203166002900461078b929190610966565b5050610797565b6106d5565b505050505050565b6107a76108b1565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa6107de57600080fd5b84519c5083519b5082519a508151995080519850505050505050506000821461086f578167ffffffffffffffff8111801561081857600080fd5b506040519080825280601f01601f19166020018201604052801561084b5781602001600182028036833780820191505090505b50905087516020890160208301848184846011600019fa61086b57600080fd5b5050505b6040518060a00160405280878152602001868152602001858152602001848152602001828152509650505050505050919050565b600060025490509392505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061092757805160ff1916838001178555610955565b82800160010185558215610955579182015b82811115610954578251825591602001919060010190610939565b5b50905061096291906109ed565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061099f57805485556109dc565b828001600101855582156109dc57600052602060002091601f016020900482015b828111156109db5782548255916001019190600101906109c0565b5b5090506109e991906109ed565b5090565b610a0f91905b80821115610a0b5760008160009055506001016109f3565b5090565b9056fe4d697373696e6720706172656e74206865616465722066726f6d207468652073746f726167654d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f72616765a26469706673582212206e906d6f9a0d3370970670a70ebca5eac84698d1c6f1dc9d923a0c0fe40dfc9b64736f6c63430006060033") .expect("code is hardcoded, thus valid; qed"), sub_host: "localhost".into(), sub_port: 9933, @@ -87,7 +87,6 @@ pub fn run(params: EthereumDeployContractParams) { let (sub_client, initial_header) = prepare_initial_header(sub_client, params.sub_initial_header).await; let (initial_header_hash, initial_header) = initial_header?; - let initial_set_id = params.sub_initial_authorities_set_id.unwrap_or(0); let (_, initial_set) = prepare_initial_authorities_set( sub_client, @@ -96,13 +95,23 @@ pub fn run(params: EthereumDeployContractParams) { ).await; let initial_set = initial_set?; + let raw_initial_header = initial_header.encode(); + + log::info!( + target: "bridge", + "Deploying Ethereum contract.\r\n\tInitial header: {}\r\n\tInitial authorities set ID: {}\r\n\tInitial authorities set: {}", + hex::encode(raw_initial_header), + initial_set_id, + initial_set, + ); + ethereum_client::deploy_bridge_contract( eth_client, params.eth_signer, params.eth_chain_id, params.eth_gas_price, params.eth_contract_code, - initial_header.encode(), + raw_initial_header, initial_set_id, initial_set, ).await.1.map_err(|error| format!("Error deploying contract: {:?}", error)) diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index 7aa3a528ac..8d9c30a393 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -186,8 +186,8 @@ impl TargetClient for EthereumHeadersTarget { } fn requires_extra(self, header: &QueuedSubstrateHeader) -> Self::RequiresExtraFuture { - // we would require justification for every header - ready((self, Ok((header.header().id(), true)))) + // we do not require any extra data for substrate headers + ready((self, Ok((header.header().id(), false)))) } fn submit_headers(self, headers: Vec) -> Self::SubmitHeadersFuture { diff --git a/relays/ethereum/src/substrate_types.rs b/relays/ethereum/src/substrate_types.rs index b97b49c517..ed73bd974d 100644 --- a/relays/ethereum/src/substrate_types.rs +++ b/relays/ethereum/src/substrate_types.rs @@ -57,7 +57,7 @@ impl HeadersSyncPipeline for SubstrateHeadersSyncPipeline { type Hash = bridge_node_runtime::Hash; type Number = bridge_node_runtime::BlockNumber; type Header = Header; - type Extra = Option; + type Extra = (); fn estimate_size(_source: &QueuedHeader) -> usize { // we may only submit Substrate headers wit finality proof From f29b2e5594da6002035f68350fd2cd3740deb681 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 10 Apr 2020 18:09:05 +0300 Subject: [PATCH 16/92] continue --- .../contracts/substrate-bridge2.sol | 21 +++- relays/ethereum/src/ethereum_client.rs | 105 +++++++++--------- .../ethereum/src/ethereum_deploy_contract.rs | 6 +- relays/ethereum/src/ethereum_sync_loop.rs | 12 +- relays/ethereum/src/ethereum_types.rs | 1 + relays/ethereum/src/substrate_sync_loop.rs | 15 ++- relays/ethereum/src/substrate_types.rs | 1 + relays/ethereum/src/sync_loop.rs | 8 ++ relays/ethereum/src/sync_types.rs | 2 + 9 files changed, 103 insertions(+), 68 deletions(-) diff --git a/modules/ethereum-contract/contracts/substrate-bridge2.sol b/modules/ethereum-contract/contracts/substrate-bridge2.sol index d48d17f818..7fed6d62b5 100644 --- a/modules/ethereum-contract/contracts/substrate-bridge2.sol +++ b/modules/ethereum-contract/contracts/substrate-bridge2.sol @@ -131,12 +131,13 @@ contract SubstrateBridge { "Missing parent header from the storage" ); - // check if parent header has emitted validators set change signal - uint64 validatorsSetId = parentHeader.validatorsSetId; - bytes32 prevSignalHeaderHash = parentHeader.prevSignalHeaderHash; - if (parentHeader.signal.length != 0) { - prevSignalHeaderHash = header.parentHash; - validatorsSetId = validatorsSetId + 1; + // forbid appending to fork until we'll get finality proof for header that + // requires it + if (parentHeader.prevSignalTargetNumber == parentHeader.number) { + require( + bestFinalizedHeaderHash == header.parentHash, + "Missing required finality proof for parent header" + ); } // forbid overlapping signals @@ -149,6 +150,14 @@ contract SubstrateBridge { prevSignalTargetNumber = header.number + header.signalDelay; } + // check if parent header has emitted validators set change signal + uint64 validatorsSetId = parentHeader.validatorsSetId; + bytes32 prevSignalHeaderHash = parentHeader.prevSignalHeaderHash; + if (parentHeader.signal.length != 0) { + prevSignalHeaderHash = header.parentHash; + validatorsSetId = validatorsSetId + 1; + } + // store header in the storage headerByHash[header.hash] = Header({ isKnown: true, diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index d6abb2ec48..a822a157e0 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -15,7 +15,7 @@ // along with Parity Bridges Common. If not, see . use crate::ethereum_types::{Address, Bytes, EthereumHeaderId, Header, Receipt, H256, U256, U64}; -use crate::substrate_types::{SubstrateHeaderId, Hash as SubstrateHash, Number as SubstrateNumber, QueuedSubstrateHeader}; +use crate::substrate_types::{SubstrateHeaderId, Hash as SubstrateHash, QueuedSubstrateHeader}; use crate::sync_types::{HeaderId, MaybeConnectionError}; use codec::{Encode, Decode}; use ethabi::FunctionOutputDecoder; @@ -62,8 +62,6 @@ pub enum Error { IncompleteHeader, /// We have received receipt with missing gas_used field. IncompleteReceipt, - /// Justification for last Substrate header is missing. - MissingJustification, } impl MaybeConnectionError for Error { @@ -188,14 +186,10 @@ pub async fn best_substrate_block( Ok(result) => result, Err(error) => return (client, Err(error)), }; - let (raw_number, raw_hash) = match call_decoder.decode(&call_result.0) { + let (number, raw_hash) = match call_decoder.decode(&call_result.0) { Ok((raw_number, raw_hash)) => (raw_number, raw_hash), Err(error) => return (client, Err(Error::ResponseParseFailed(format!("{}", error)))), }; - let number = match SubstrateNumber::decode(&mut &raw_number[..]) { - Ok(number) => number, - Err(error) => return (client, Err(Error::ResponseParseFailed(format!("{}", error)))), - }; let hash = match SubstrateHash::decode(&mut &raw_hash[..]) { Ok(hash) => hash, Err(error) => return (client, Err(Error::ResponseParseFailed(format!("{}", error)))), @@ -203,7 +197,7 @@ pub async fn best_substrate_block( ( client, - Ok(HeaderId(number, hash)), + Ok(HeaderId(number.low_u32(), hash)), // TODO: verify that low_u32().into() == self ) } @@ -219,7 +213,7 @@ pub async fn substrate_header_known( // But when we'll read best header from Ethereum next time, we will know that // there's a better header => this Orphan will either be marked as synced, or // eventually pruned. - let (encoded_call, call_decoder) = bridge_contract::functions::is_known_header::call(id.1.encode()); + let (encoded_call, call_decoder) = bridge_contract::functions::is_known_header::call(id.1); let (client, result) = call_rpc::( client, "eth_call", @@ -249,54 +243,55 @@ pub async fn submit_substrate_headers( contract_address: Address, gas_price: U256, headers: Vec, -) -> (Client, Result<(H256, Vec), Error>) { - let ids = headers.iter().map(|header| header.id()).collect(); - let num_headers = headers.len(); - let (headers, justification) = headers - .into_iter() - .fold((Vec::with_capacity(num_headers), None), |(mut headers, _), header| { - let (header, justification) = header.extract(); - headers.push(header.encode()); - (headers, justification) - }); - let justification = match justification { - Some(justification) => justification.encode(), - None => return (client, Err(Error::MissingJustification)), - }; - let encoded_call = bridge_contract::functions::import_headers::encode_input( - headers.encode(), - justification, - ); - let (client, nonce) = account_nonce(client, signer.address().as_fixed_bytes().into()).await; - let nonce = match nonce { +) -> (Client, Result<(Vec, Vec), Error>) { + let (mut client, nonce) = account_nonce(client, signer.address().as_fixed_bytes().into()).await; + let mut nonce = match nonce { Ok(nonce) => nonce, Err(error) => return (client, Err(error)), }; - let (client, gas) = estimate_gas(client, CallRequest { - to: Some(contract_address), - data: Some(encoded_call.clone().into()), - }).await; - let gas = match gas { - Ok(gas) => gas, - Err(error) => return (client, Err(error)), - }; - let raw_transaction = ethereum_tx_sign::RawTransaction { - nonce, - to: Some(contract_address), - value: U256::zero(), - gas, - gas_price, - data: encoded_call, - }.sign(&signer.secret().as_fixed_bytes().into(), &chain_id); - let (client, result) = call_rpc( - client, - "eth_submitTransaction", - Params::Array(vec![ - to_value(raw_transaction).unwrap(), - ]), - ) - .await; - (client, result.map(|tx_hash| (tx_hash, ids))) + + let mut tx_hashes = Vec::with_capacity(headers.len()); + let ids = headers.iter().map(|header| header.id()).collect(); + for header in headers { + let raw_header = header.extract().0.encode(); + let encoded_call = bridge_contract::functions::import_header::encode_input( + raw_header, + ); + let (ret_client, gas) = estimate_gas(client, CallRequest { + to: Some(contract_address), + data: Some(encoded_call.clone().into()), + }).await; + let gas = match gas { + Ok(gas) => gas, + Err(error) => return (ret_client, Err(error)), + }; + let raw_transaction = ethereum_tx_sign::RawTransaction { + nonce, + to: Some(contract_address), + value: U256::zero(), + gas: gas * 2, + gas_price, + data: encoded_call, + }.sign(&signer.secret().as_fixed_bytes().into(), &chain_id); + let (ret_client, result) = call_rpc( + ret_client, + "eth_submitTransaction", + Params::Array(vec![ + to_value(raw_transaction).unwrap(), + ]), + ) + .await; + let tx_hash = match result { + Ok(tx_hash) => tx_hash, + Err(error) => return (ret_client, Err(error)), + }; + + tx_hashes.push(tx_hash); + nonce += 1.into(); + client = ret_client; + } + + (client, Ok((tx_hashes, ids))) } /// Deploy bridge contract. diff --git a/relays/ethereum/src/ethereum_deploy_contract.rs b/relays/ethereum/src/ethereum_deploy_contract.rs index af673d2e98..625c50351a 100644 --- a/relays/ethereum/src/ethereum_deploy_contract.rs +++ b/relays/ethereum/src/ethereum_deploy_contract.rs @@ -63,7 +63,7 @@ impl Default for EthereumDeployContractParams { .expect("secret is hardcoded, thus valid; qed"), ).expect("secret is hardcoded, thus valid; qed"), eth_gas_price: 8_000_000_000u64.into(), // 8 Gwei - eth_contract_code: hex::decode("60806040523480156200001157600080fd5b5060405162000fe538038062000fe5833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b838201915060208201858111156200006f57600080fd5b82518660018202830111640100000000821117156200008d57600080fd5b8083526020830192505050908051906020019080838360005b83811015620000c3578082015181840152602081019050620000a6565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b5060405260200180519060200190929190805160405193929190846401000000008211156200011f57600080fd5b838201915060208201858111156200013657600080fd5b82518660018202830111640100000000821117156200015457600080fd5b8083526020830192505050908051906020019080838360005b838110156200018a5780820151818401526020810190506200016d565b50505050905090810190601f168015620001b85780820380516001836020036101000a031916815260200191505b50604052505050620001c962000454565b620001da846200034960201b60201c565b90508060000151600081905550806000015160028190555080604001516001819055506040518060e001604052806001151581526020018260200151815260200182604001518152602001826080015181526020018467ffffffffffffffff1681526020016000801b81526020016000815250600560008360000151815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160010155604082015181600201556060820151816003019080519060200190620002b692919062000489565b5060808201518160040160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060a0820151816005015560c0820151816006015590505082600360006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555081600490805190602001906200033e92919062000489565b505050505062000538565b6200035362000454565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa6200038b57600080fd5b84519c5083519b5082519a508151995080519850505050505050506000821462000420578167ffffffffffffffff81118015620003c757600080fd5b506040519080825280601f01601f191660200182016040528015620003fb5781602001600182028036833780820191505090505b50905087516020890160208301848184846011600019fa6200041c57600080fd5b5050505b6040518060a00160405280878152602001868152602001858152602001848152602001828152509650505050505050919050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620004cc57805160ff1916838001178555620004fd565b82800160010185558215620004fd579182015b82811115620004fc578251825591602001919060010190620004df565b5b5090506200050c919062000510565b5090565b6200053591905b808211156200053157600081600090555060010162000517565b5090565b90565b610a9d80620005486000396000f3fe608060405234801561001057600080fd5b506004361061005b5760003560e01c8063871ebe1814610061578063a98bfaad146100a7578063d96a2deb146100ed578063e7af077914610112578063fae71ae8146101cd5761005c565b5b600080fd5b61008d6004803603602081101561007757600080fd5b810190808035906020019092919050505061029c565b604051808215151515815260200191505060405180910390f35b6100d3600480360360208110156100bd57600080fd5b81019080803590602001909291905050506102c9565b604051808215151515815260200191505060405180910390f35b6100f561036c565b604051808381526020018281526020019250505060405180910390f35b6101cb6004803603602081101561012857600080fd5b810190808035906020019064010000000081111561014557600080fd5b82018360208201111561015757600080fd5b8035906020019184600183028401116401000000008311171561017957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610398565b005b61029a600480360360608110156101e357600080fd5b8101908080359060200190929190803590602001909291908035906020019064010000000081111561021457600080fd5b82018360208201111561022657600080fd5b8035906020019184600183028401116401000000008311171561024857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610627565b005b60006005600083815260200190815260200160002060000160009054906101000a900460ff169050919050565b6000806005600084815260200190815260200160002090508060000160009054906101000a900460ff16801561030457506001548160020154115b8015610317575080600601548160020154145b80156103645750600360009054906101000a900467ffffffffffffffff1667ffffffffffffffff168160040160009054906101000a900467ffffffffffffffff1667ffffffffffffffff16145b915050919050565b600080600060056000805481526020019081526020016000209050806002015460005492509250509091565b6103a06108b1565b6103a98261079f565b90506000600560008360200151815260200190815260200160002090506001826040015103816002015414610429576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610a136026913960400191505060405180910390fd5b60008160040160009054906101000a900467ffffffffffffffff1690506000826005015490506000836003018054600181600116156101000203166002900490501461047d57836020015190506001820191505b60008360060154905060008560800151511461051a578460400151811061050c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4f7665726c617070696e67207369676e616c7320666f756e640000000000000081525060200191505060405180910390fd5b846060015185604001510190505b6040518060e001604052806001151581526020018660200151815260200186604001518152602001866080015181526020018467ffffffffffffffff16815260200183815260200182815250600560008760000151815260200190815260200160002060008201518160000160006101000a81548160ff021916908315150217905550602082015181600101556040820151816002015560608201518160030190805190602001906105cd9291906108e6565b5060808201518160040160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060a0820151816005015560c082015181600601559050508460000151600081905550505050505050565b82600560008481526020019081526020016000206002015414610695576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180610a39602f913960400191505060405180910390fd5b6000600254905060006106a98585856108a3565b905060006005600083815260200190815260200160002090508160028190555080600201546001819055505b8282146107975760056000838152602001908152602001600020905080600101549150806006015481600201541415610792576000600560008360050154815260200190815260200160002090506001600360008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550806003016004908054600181600116156101000203166002900461078b929190610966565b5050610797565b6106d5565b505050505050565b6107a76108b1565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa6107de57600080fd5b84519c5083519b5082519a508151995080519850505050505050506000821461086f578167ffffffffffffffff8111801561081857600080fd5b506040519080825280601f01601f19166020018201604052801561084b5781602001600182028036833780820191505090505b50905087516020890160208301848184846011600019fa61086b57600080fd5b5050505b6040518060a00160405280878152602001868152602001858152602001848152602001828152509650505050505050919050565b600060025490509392505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061092757805160ff1916838001178555610955565b82800160010185558215610955579182015b82811115610954578251825591602001919060010190610939565b5b50905061096291906109ed565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061099f57805485556109dc565b828001600101855582156109dc57600052602060002091601f016020900482015b828111156109db5782548255916001019190600101906109c0565b5b5090506109e991906109ed565b5090565b610a0f91905b80821115610a0b5760008160009055506001016109f3565b5090565b9056fe4d697373696e6720706172656e74206865616465722066726f6d207468652073746f726167654d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f72616765a26469706673582212206e906d6f9a0d3370970670a70ebca5eac84698d1c6f1dc9d923a0c0fe40dfc9b64736f6c63430006060033") + eth_contract_code: hex::decode("60806040523480156200001157600080fd5b506040516200108538038062001085833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b838201915060208201858111156200006f57600080fd5b82518660018202830111640100000000821117156200008d57600080fd5b8083526020830192505050908051906020019080838360005b83811015620000c3578082015181840152602081019050620000a6565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b5060405260200180519060200190929190805160405193929190846401000000008211156200011f57600080fd5b838201915060208201858111156200013657600080fd5b82518660018202830111640100000000821117156200015457600080fd5b8083526020830192505050908051906020019080838360005b838110156200018a5780820151818401526020810190506200016d565b50505050905090810190601f168015620001b85780820380516001836020036101000a031916815260200191505b50604052505050620001c962000454565b620001da846200034960201b60201c565b90508060000151600081905550806000015160028190555080604001516001819055506040518060e001604052806001151581526020018260200151815260200182604001518152602001826080015181526020018467ffffffffffffffff1681526020016000801b81526020016000815250600560008360000151815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160010155604082015181600201556060820151816003019080519060200190620002b692919062000489565b5060808201518160040160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060a0820151816005015560c0820151816006015590505082600360006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555081600490805190602001906200033e92919062000489565b505050505062000538565b6200035362000454565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa6200038b57600080fd5b84519c5083519b5082519a508151995080519850505050505050506000821462000420578167ffffffffffffffff81118015620003c757600080fd5b506040519080825280601f01601f191660200182016040528015620003fb5781602001600182028036833780820191505090505b50905087516020890160208301848184846011600019fa6200041c57600080fd5b5050505b6040518060a00160405280878152602001868152602001858152602001848152602001828152509650505050505050919050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620004cc57805160ff1916838001178555620004fd565b82800160010185558215620004fd579182015b82811115620004fc578251825591602001919060010190620004df565b5b5090506200050c919062000510565b5090565b6200053591905b808211156200053157600081600090555060010162000517565b5090565b90565b610b3d80620005486000396000f3fe608060405234801561001057600080fd5b506004361061005b5760003560e01c8063871ebe1814610061578063a98bfaad146100a7578063d96a2deb146100ed578063e7af077914610112578063fae71ae8146101cd5761005c565b5b600080fd5b61008d6004803603602081101561007757600080fd5b810190808035906020019092919050505061029c565b604051808215151515815260200191505060405180910390f35b6100d3600480360360208110156100bd57600080fd5b81019080803590602001909291905050506102c9565b604051808215151515815260200191505060405180910390f35b6100f561036c565b604051808381526020018281526020019250505060405180910390f35b6101cb6004803603602081101561012857600080fd5b810190808035906020019064010000000081111561014557600080fd5b82018360208201111561015757600080fd5b8035906020019184600183028401116401000000008311171561017957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610398565b005b61029a600480360360608110156101e357600080fd5b8101908080359060200190929190803590602001909291908035906020019064010000000081111561021457600080fd5b82018360208201111561022657600080fd5b8035906020019184600183028401116401000000008311171561024857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610696565b005b60006005600083815260200190815260200160002060000160009054906101000a900460ff169050919050565b6000806005600084815260200190815260200160002090508060000160009054906101000a900460ff16801561030457506001548160020154115b8015610317575080600601548160020154145b80156103645750600360009054906101000a900467ffffffffffffffff1667ffffffffffffffff168160040160009054906101000a900467ffffffffffffffff1667ffffffffffffffff16145b915050919050565b600080600060056000805481526020019081526020016000209050806002015460005492509250509091565b6103a0610920565b6103a98261080e565b90506000600560008360200151815260200190815260200160002090506001826040015103816002015414610429576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610a826026913960400191505060405180910390fd5b80600201548160060154141561049857816020015160025414610497576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180610ad76031913960400191505060405180910390fd5b5b6000816006015490506000836080015151146105355782604001518110610527576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4f7665726c617070696e67207369676e616c7320666f756e640000000000000081525060200191505060405180910390fd5b826060015183604001510190505b60008260040160009054906101000a900467ffffffffffffffff1690506000836005015490506000846003018054600181600116156101000203166002900490501461058957846020015190506001820191505b6040518060e001604052806001151581526020018660200151815260200186604001518152602001866080015181526020018367ffffffffffffffff16815260200182815260200184815250600560008760000151815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301908051906020019061063c929190610955565b5060808201518160040160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060a0820151816005015560c082015181600601559050508460000151600081905550505050505050565b82600560008481526020019081526020016000206002015414610704576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180610aa8602f913960400191505060405180910390fd5b600060025490506000610718858585610912565b905060006005600083815260200190815260200160002090508160028190555080600201546001819055505b8282146108065760056000838152602001908152602001600020905080600101549150806006015481600201541415610801576000600560008360050154815260200190815260200160002090506001600360008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555080600301600490805460018160011615610100020316600290046107fa9291906109d5565b5050610806565b610744565b505050505050565b610816610920565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa61084d57600080fd5b84519c5083519b5082519a50815199508051985050505050505050600082146108de578167ffffffffffffffff8111801561088757600080fd5b506040519080825280601f01601f1916602001820160405280156108ba5781602001600182028036833780820191505090505b50905087516020890160208301848184846011600019fa6108da57600080fd5b5050505b6040518060a00160405280878152602001868152602001858152602001848152602001828152509650505050505050919050565b600060025490509392505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061099657805160ff19168380011785556109c4565b828001600101855582156109c4579182015b828111156109c35782518255916020019190600101906109a8565b5b5090506109d19190610a5c565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610a0e5780548555610a4b565b82800160010185558215610a4b57600052602060002091601f016020900482015b82811115610a4a578254825591600101919060010190610a2f565b5b509050610a589190610a5c565b5090565b610a7e91905b80821115610a7a576000816000905550600101610a62565b5090565b9056fe4d697373696e6720706172656e74206865616465722066726f6d207468652073746f726167654d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f726167654d697373696e672072657175697265642066696e616c6974792070726f6f6620666f7220706172656e7420686561646572a2646970667358221220f74cd1fc82a451b2c9c76ce5c5dafd9e990911373721d7fa49fc18bfc2fb1eec64736f6c63430006060033") .expect("code is hardcoded, thus valid; qed"), sub_host: "localhost".into(), sub_port: 9933, @@ -100,9 +100,9 @@ pub fn run(params: EthereumDeployContractParams) { log::info!( target: "bridge", "Deploying Ethereum contract.\r\n\tInitial header: {}\r\n\tInitial authorities set ID: {}\r\n\tInitial authorities set: {}", - hex::encode(raw_initial_header), + hex::encode(&raw_initial_header), initial_set_id, - initial_set, + hex::encode(&initial_set), ); ethereum_client::deploy_bridge_contract( diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index 42a006054f..128562f685 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -19,7 +19,7 @@ use crate::ethereum_types::{EthereumHeaderId, EthereumHeadersSyncPipeline, Heade use crate::substrate_client; use crate::sync::{HeadersSyncParams, TargetTransactionMode}; use crate::sync_loop::{SourceClient, TargetClient}; -use futures::future::FutureExt; +use futures::future::{FutureExt, Ready, ready}; use std::{future::Future, pin::Pin}; use web3::types::H256; @@ -80,6 +80,7 @@ impl SourceClient for EthereumHeadersSource { type BestBlockNumberFuture = Pin)>>>; type HeaderByHashFuture = Pin)>>>; type HeaderByNumberFuture = Pin)>>>; + type HeaderAsyncExtraFuture = Ready<(Self, Result<(EthereumHeaderId, Option<()>), Self::Error>)>; type HeaderExtraFuture = Pin), Self::Error>)>>>; fn best_block_number(self) -> Self::BestBlockNumberFuture { @@ -100,6 +101,10 @@ impl SourceClient for EthereumHeadersSource { .boxed() } + fn header_async_extra(self, id: EthereumHeaderId) -> Self::HeaderAsyncExtraFuture { + ready((self, Ok((id, Some(()))))) + } + fn header_extra(self, id: EthereumHeaderId, header: &Header) -> Self::HeaderExtraFuture { ethereum_client::transactions_receipts(self.client, id, header.transactions.clone()) .map(|(client, result)| (EthereumHeadersSource { client }, result)) @@ -121,6 +126,7 @@ impl TargetClient for SubstrateHeadersTarget { type Error = substrate_client::Error; type BestHeaderIdFuture = Pin)>>>; type IsKnownHeaderFuture = Pin)>>>; + type RequiresAsyncExtraFuture = Ready<(Self, Result<(EthereumHeaderId, bool), Self::Error>)>; type RequiresExtraFuture = Pin)>>>; type SubmitHeadersFuture = Pin, Self::Error>)>>>; @@ -156,6 +162,10 @@ impl TargetClient for SubstrateHeadersTarget { .boxed() } + fn requires_async_extra(self, id: EthereumHeaderId) -> Self::RequiresAsyncExtraFuture { + ready((self, Ok((id, false)))) + } + fn requires_extra(self, header: &QueuedEthereumHeader) -> Self::RequiresExtraFuture { // we can minimize number of receipts_check calls by checking header // logs bloom here, but it may give us false positives (when authorities diff --git a/relays/ethereum/src/ethereum_types.rs b/relays/ethereum/src/ethereum_types.rs index 618d46d856..eccbbd601e 100644 --- a/relays/ethereum/src/ethereum_types.rs +++ b/relays/ethereum/src/ethereum_types.rs @@ -52,6 +52,7 @@ impl HeadersSyncPipeline for EthereumHeadersSyncPipeline { type Hash = H256; type Number = u64; type Header = Header; + type AsyncExtra = (); type Extra = Vec; fn estimate_size(source: &QueuedHeader) -> usize { diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index 8d9c30a393..09c0724809 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -93,7 +93,8 @@ impl SourceClient for SubstrateHeadersSource { type BestBlockNumberFuture = Pin)>>>; type HeaderByHashFuture = Pin)>>>; type HeaderByNumberFuture = Pin)>>>; - type HeaderExtraFuture = Pin), Self::Error>)>>>; + type HeaderAsyncExtraFuture = Pin), Self::Error>)>>>; + type HeaderExtraFuture = Ready<(Self, Result<(SubstrateHeaderId, ()), Self::Error>)>; fn best_block_number(self) -> Self::BestBlockNumberFuture { substrate_client::best_header(self.client) @@ -116,7 +117,7 @@ impl SourceClient for SubstrateHeadersSource { .boxed() } - fn header_extra(self, id: SubstrateHeaderId, _header: &Header) -> Self::HeaderExtraFuture { + fn header_async_extra(self, id: SubstrateHeaderId) -> Self::HeaderAsyncExtraFuture { substrate_client::justification(self.client, id.1) .map(move |(client, result)| ( SubstrateHeadersSource { client }, @@ -124,6 +125,10 @@ impl SourceClient for SubstrateHeadersSource { )) .boxed() } + + fn header_extra(self, id: SubstrateHeaderId, _header: &Header) -> Self::HeaderExtraFuture { + ready((self, Ok((id, ())))) + } } /// Ethereum client as Substrate headers target. @@ -144,6 +149,7 @@ impl TargetClient for EthereumHeadersTarget { type Error = ethereum_client::Error; type BestHeaderIdFuture = Pin)>>>; type IsKnownHeaderFuture = Pin)>>>; + type RequiresAsyncExtraFuture = Pin)>>>; type RequiresExtraFuture = Ready<(Self, Result<(SubstrateHeaderId, bool), Self::Error>)>; type SubmitHeadersFuture = Pin, Self::Error>)>>>; @@ -185,8 +191,11 @@ impl TargetClient for EthereumHeadersTarget { .boxed() } + fn requires_async_extra(self, id: SubstrateHeaderId) -> Self::RequiresAsyncExtraFuture { + ready((self, Ok((id, false)))).boxed() // TODO: actual impl + } + fn requires_extra(self, header: &QueuedSubstrateHeader) -> Self::RequiresExtraFuture { - // we do not require any extra data for substrate headers ready((self, Ok((header.header().id(), false)))) } diff --git a/relays/ethereum/src/substrate_types.rs b/relays/ethereum/src/substrate_types.rs index ed73bd974d..ed29a2e71d 100644 --- a/relays/ethereum/src/substrate_types.rs +++ b/relays/ethereum/src/substrate_types.rs @@ -57,6 +57,7 @@ impl HeadersSyncPipeline for SubstrateHeadersSyncPipeline { type Hash = bridge_node_runtime::Hash; type Number = bridge_node_runtime::BlockNumber; type Header = Header; + type AsyncExtra = Justification; type Extra = (); fn estimate_size(_source: &QueuedHeader) -> usize { diff --git a/relays/ethereum/src/sync_loop.rs b/relays/ethereum/src/sync_loop.rs index b2e97c9794..ffad4ff8ff 100644 --- a/relays/ethereum/src/sync_loop.rs +++ b/relays/ethereum/src/sync_loop.rs @@ -48,6 +48,8 @@ pub trait SourceClient: Sized { type HeaderByHashFuture: Future)>; /// Future that returns header by number. type HeaderByNumberFuture: Future)>; + /// Future that returns async extra data associated with header. + type HeaderAsyncExtraFuture: Future, Option), Self::Error>)>; /// Future that returns extra data associated with header. type HeaderExtraFuture: Future, P::Extra), Self::Error>)>; @@ -57,6 +59,8 @@ pub trait SourceClient: Sized { fn header_by_hash(self, hash: P::Hash) -> Self::HeaderByHashFuture; /// Get canonical header by number. fn header_by_number(self, number: P::Number) -> Self::HeaderByNumberFuture; + /// Get async extra data by header hash. + fn header_async_extra(self, id: HeaderId) -> Self::HeaderAsyncExtraFuture; /// Get extra data by header hash. fn header_extra(self, id: HeaderId, header: &P::Header) -> Self::HeaderExtraFuture; } @@ -69,6 +73,8 @@ pub trait TargetClient: Sized { type BestHeaderIdFuture: Future, Self::Error>)>; /// Future that returns known header check result. type IsKnownHeaderFuture: Future, bool), Self::Error>)>; + /// Future that returns async extra check result. + type RequiresAsyncExtraFuture: Future, bool), Self::Error>)>; /// Future that returns extra check result. type RequiresExtraFuture: Future, bool), Self::Error>)>; /// Future that returns header submission result. @@ -78,6 +84,8 @@ pub trait TargetClient: Sized { fn best_header_id(self) -> Self::BestHeaderIdFuture; /// Returns true if header is known to the target node. fn is_known_header(self, id: HeaderId) -> Self::IsKnownHeaderFuture; + /// Returns true if header requires async extra data to be submitted. + fn requires_async_extra(self, id: HeaderId) -> Self::RequiresAsyncExtraFuture; /// Returns true if header requires extra data to be submitted. fn requires_extra(self, header: &QueuedHeader

) -> Self::RequiresExtraFuture; /// Submit headers. diff --git a/relays/ethereum/src/sync_types.rs b/relays/ethereum/src/sync_types.rs index 9b9712c739..28b7646b85 100644 --- a/relays/ethereum/src/sync_types.rs +++ b/relays/ethereum/src/sync_types.rs @@ -70,6 +70,8 @@ pub trait HeadersSyncPipeline: Clone + Copy { type Header: Clone + std::fmt::Debug + SourceHeader; /// Type of extra data for the header that we're receiving from the source node. type Extra: Clone + std::fmt::Debug; + /// Type of extra data that we're sending separately from the header itself. + type AsyncExtra: Clone + std::fmt::Debug; /// Function used to convert from queued header to target header. fn estimate_size(source: &QueuedHeader) -> usize; From d90dff333df8c5ed01168b8a7f8e441e057d752f Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 13 Apr 2020 12:51:25 +0300 Subject: [PATCH 17/92] more fixes --- modules/ethereum-contract/builtin/src/lib.rs | 22 +++- .../contracts/substrate-bridge2.sol | 10 +- relays/ethereum/src/ethereum_client.rs | 4 +- .../ethereum/src/ethereum_deploy_contract.rs | 6 +- relays/ethereum/src/ethereum_sync_loop.rs | 9 +- relays/ethereum/src/headers.rs | 108 +++++++----------- relays/ethereum/src/substrate_sync_loop.rs | 11 +- relays/ethereum/src/sync.rs | 20 +--- 8 files changed, 92 insertions(+), 98 deletions(-) diff --git a/modules/ethereum-contract/builtin/src/lib.rs b/modules/ethereum-contract/builtin/src/lib.rs index 6d3f33dc86..4528ebeab9 100644 --- a/modules/ethereum-contract/builtin/src/lib.rs +++ b/modules/ethereum-contract/builtin/src/lib.rs @@ -15,11 +15,12 @@ // along with Parity Bridges Common. If not, see . use codec::{Encode, Decode}; -use bridge_node_runtime::{BlockNumber, Header as RuntimeHeader}; +use bridge_node_runtime::{BlockNumber, Hash, Header as RuntimeHeader}; use sp_blockchain::Error as ClientError; use sp_finality_grandpa::AuthorityList; /// Builtin errors. +#[derive(Debug)] pub enum Error { /// Failed to decode Substrate header. HeaderDecode(codec::Error), @@ -34,9 +35,25 @@ pub enum Error { } /// Substrate header. +#[derive(Debug)] pub struct Header { + /// Header hash. + pub hash: Hash, + /// Parent header hash. + pub parent_hash: Hash, /// Header number. pub number: BlockNumber, + /// GRANDPA validators change signal. + pub signal: Option, +} + +/// GRANDPA validators set change signal. +#[derive(Debug)] +pub struct ValidatorsSetSignal { + /// Signal delay. + pub delay: BlockNumber, + /// New validators set. + pub validators: Vec, } /// All types of finality proofs. @@ -50,7 +67,10 @@ pub enum FinalityProof { pub fn parse_substrate_header(raw_header: &[u8]) -> Result { RuntimeHeader::decode(&mut &raw_header[..]) .map(|header| Header { + hash: header.hash(), + parent_hash: header.parent_hash, number: header.number, + signal: None, // TODO }) .map_err(Error::HeaderDecode) } diff --git a/modules/ethereum-contract/contracts/substrate-bridge2.sol b/modules/ethereum-contract/contracts/substrate-bridge2.sol index 7fed6d62b5..befd358c70 100644 --- a/modules/ethereum-contract/contracts/substrate-bridge2.sol +++ b/modules/ethereum-contract/contracts/substrate-bridge2.sol @@ -133,7 +133,7 @@ contract SubstrateBridge { // forbid appending to fork until we'll get finality proof for header that // requires it - if (parentHeader.prevSignalTargetNumber == parentHeader.number) { + if (parentHeader.prevSignalTargetNumber != 0 && parentHeader.prevSignalTargetNumber == parentHeader.number) { require( bestFinalizedHeaderHash == header.parentHash, "Missing required finality proof for parent header" @@ -224,8 +224,8 @@ contract SubstrateBridge { assembly { // inputs - let rawHeadersSize := mload(rawHeader) - let rawHeadersPointer := add(rawHeader, 0x20) + let rawHeaderSize := mload(rawHeader) + let rawHeaderPointer := add(rawHeader, 0x20) // output let headerHashPointer := mload(0x40) @@ -238,8 +238,8 @@ contract SubstrateBridge { if iszero(staticcall( not(0), SUBSTRATE_PARSE_HEADER_BUILTIN_ADDRESS, - rawHeadersPointer, - rawHeadersSize, + rawHeaderPointer, + rawHeaderSize, headerHashPointer, 0xA0 )) { diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index a822a157e0..fb80b33cdf 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -277,7 +277,7 @@ pub async fn submit_substrate_headers( ret_client, "eth_submitTransaction", Params::Array(vec![ - to_value(raw_transaction).unwrap(), + to_value(Bytes(raw_transaction)).unwrap(), ]), ) .await; @@ -307,7 +307,7 @@ pub async fn deploy_bridge_contract( ) -> (Client, Result) { let encoded_call = bridge_contract::constructor( contract_code, - initial_header.encode(), + initial_header, initial_set_id, initial_authorities, ); diff --git a/relays/ethereum/src/ethereum_deploy_contract.rs b/relays/ethereum/src/ethereum_deploy_contract.rs index 625c50351a..4d82510544 100644 --- a/relays/ethereum/src/ethereum_deploy_contract.rs +++ b/relays/ethereum/src/ethereum_deploy_contract.rs @@ -63,7 +63,7 @@ impl Default for EthereumDeployContractParams { .expect("secret is hardcoded, thus valid; qed"), ).expect("secret is hardcoded, thus valid; qed"), eth_gas_price: 8_000_000_000u64.into(), // 8 Gwei - eth_contract_code: hex::decode("60806040523480156200001157600080fd5b506040516200108538038062001085833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b838201915060208201858111156200006f57600080fd5b82518660018202830111640100000000821117156200008d57600080fd5b8083526020830192505050908051906020019080838360005b83811015620000c3578082015181840152602081019050620000a6565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b5060405260200180519060200190929190805160405193929190846401000000008211156200011f57600080fd5b838201915060208201858111156200013657600080fd5b82518660018202830111640100000000821117156200015457600080fd5b8083526020830192505050908051906020019080838360005b838110156200018a5780820151818401526020810190506200016d565b50505050905090810190601f168015620001b85780820380516001836020036101000a031916815260200191505b50604052505050620001c962000454565b620001da846200034960201b60201c565b90508060000151600081905550806000015160028190555080604001516001819055506040518060e001604052806001151581526020018260200151815260200182604001518152602001826080015181526020018467ffffffffffffffff1681526020016000801b81526020016000815250600560008360000151815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160010155604082015181600201556060820151816003019080519060200190620002b692919062000489565b5060808201518160040160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060a0820151816005015560c0820151816006015590505082600360006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555081600490805190602001906200033e92919062000489565b505050505062000538565b6200035362000454565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa6200038b57600080fd5b84519c5083519b5082519a508151995080519850505050505050506000821462000420578167ffffffffffffffff81118015620003c757600080fd5b506040519080825280601f01601f191660200182016040528015620003fb5781602001600182028036833780820191505090505b50905087516020890160208301848184846011600019fa6200041c57600080fd5b5050505b6040518060a00160405280878152602001868152602001858152602001848152602001828152509650505050505050919050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620004cc57805160ff1916838001178555620004fd565b82800160010185558215620004fd579182015b82811115620004fc578251825591602001919060010190620004df565b5b5090506200050c919062000510565b5090565b6200053591905b808211156200053157600081600090555060010162000517565b5090565b90565b610b3d80620005486000396000f3fe608060405234801561001057600080fd5b506004361061005b5760003560e01c8063871ebe1814610061578063a98bfaad146100a7578063d96a2deb146100ed578063e7af077914610112578063fae71ae8146101cd5761005c565b5b600080fd5b61008d6004803603602081101561007757600080fd5b810190808035906020019092919050505061029c565b604051808215151515815260200191505060405180910390f35b6100d3600480360360208110156100bd57600080fd5b81019080803590602001909291905050506102c9565b604051808215151515815260200191505060405180910390f35b6100f561036c565b604051808381526020018281526020019250505060405180910390f35b6101cb6004803603602081101561012857600080fd5b810190808035906020019064010000000081111561014557600080fd5b82018360208201111561015757600080fd5b8035906020019184600183028401116401000000008311171561017957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610398565b005b61029a600480360360608110156101e357600080fd5b8101908080359060200190929190803590602001909291908035906020019064010000000081111561021457600080fd5b82018360208201111561022657600080fd5b8035906020019184600183028401116401000000008311171561024857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610696565b005b60006005600083815260200190815260200160002060000160009054906101000a900460ff169050919050565b6000806005600084815260200190815260200160002090508060000160009054906101000a900460ff16801561030457506001548160020154115b8015610317575080600601548160020154145b80156103645750600360009054906101000a900467ffffffffffffffff1667ffffffffffffffff168160040160009054906101000a900467ffffffffffffffff1667ffffffffffffffff16145b915050919050565b600080600060056000805481526020019081526020016000209050806002015460005492509250509091565b6103a0610920565b6103a98261080e565b90506000600560008360200151815260200190815260200160002090506001826040015103816002015414610429576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610a826026913960400191505060405180910390fd5b80600201548160060154141561049857816020015160025414610497576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180610ad76031913960400191505060405180910390fd5b5b6000816006015490506000836080015151146105355782604001518110610527576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4f7665726c617070696e67207369676e616c7320666f756e640000000000000081525060200191505060405180910390fd5b826060015183604001510190505b60008260040160009054906101000a900467ffffffffffffffff1690506000836005015490506000846003018054600181600116156101000203166002900490501461058957846020015190506001820191505b6040518060e001604052806001151581526020018660200151815260200186604001518152602001866080015181526020018367ffffffffffffffff16815260200182815260200184815250600560008760000151815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301908051906020019061063c929190610955565b5060808201518160040160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060a0820151816005015560c082015181600601559050508460000151600081905550505050505050565b82600560008481526020019081526020016000206002015414610704576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180610aa8602f913960400191505060405180910390fd5b600060025490506000610718858585610912565b905060006005600083815260200190815260200160002090508160028190555080600201546001819055505b8282146108065760056000838152602001908152602001600020905080600101549150806006015481600201541415610801576000600560008360050154815260200190815260200160002090506001600360008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555080600301600490805460018160011615610100020316600290046107fa9291906109d5565b5050610806565b610744565b505050505050565b610816610920565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa61084d57600080fd5b84519c5083519b5082519a50815199508051985050505050505050600082146108de578167ffffffffffffffff8111801561088757600080fd5b506040519080825280601f01601f1916602001820160405280156108ba5781602001600182028036833780820191505090505b50905087516020890160208301848184846011600019fa6108da57600080fd5b5050505b6040518060a00160405280878152602001868152602001858152602001848152602001828152509650505050505050919050565b600060025490509392505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061099657805160ff19168380011785556109c4565b828001600101855582156109c4579182015b828111156109c35782518255916020019190600101906109a8565b5b5090506109d19190610a5c565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610a0e5780548555610a4b565b82800160010185558215610a4b57600052602060002091601f016020900482015b82811115610a4a578254825591600101919060010190610a2f565b5b509050610a589190610a5c565b5090565b610a7e91905b80821115610a7a576000816000905550600101610a62565b5090565b9056fe4d697373696e6720706172656e74206865616465722066726f6d207468652073746f726167654d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f726167654d697373696e672072657175697265642066696e616c6974792070726f6f6620666f7220706172656e7420686561646572a2646970667358221220f74cd1fc82a451b2c9c76ce5c5dafd9e990911373721d7fa49fc18bfc2fb1eec64736f6c63430006060033") + eth_contract_code: hex::decode("60806040523480156200001157600080fd5b506040516200109638038062001096833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b838201915060208201858111156200006f57600080fd5b82518660018202830111640100000000821117156200008d57600080fd5b8083526020830192505050908051906020019080838360005b83811015620000c3578082015181840152602081019050620000a6565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b5060405260200180519060200190929190805160405193929190846401000000008211156200011f57600080fd5b838201915060208201858111156200013657600080fd5b82518660018202830111640100000000821117156200015457600080fd5b8083526020830192505050908051906020019080838360005b838110156200018a5780820151818401526020810190506200016d565b50505050905090810190601f168015620001b85780820380516001836020036101000a031916815260200191505b50604052505050620001c962000454565b620001da846200034960201b60201c565b90508060000151600081905550806000015160028190555080604001516001819055506040518060e001604052806001151581526020018260200151815260200182604001518152602001826080015181526020018467ffffffffffffffff1681526020016000801b81526020016000815250600560008360000151815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160010155604082015181600201556060820151816003019080519060200190620002b692919062000489565b5060808201518160040160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060a0820151816005015560c0820151816006015590505082600360006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555081600490805190602001906200033e92919062000489565b505050505062000538565b6200035362000454565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa6200038b57600080fd5b84519c5083519b5082519a508151995080519850505050505050506000821462000420578167ffffffffffffffff81118015620003c757600080fd5b506040519080825280601f01601f191660200182016040528015620003fb5781602001600182028036833780820191505090505b50905087516020890160208301848184846011600019fa6200041c57600080fd5b5050505b6040518060a00160405280878152602001868152602001858152602001848152602001828152509650505050505050919050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620004cc57805160ff1916838001178555620004fd565b82800160010185558215620004fd579182015b82811115620004fc578251825591602001919060010190620004df565b5b5090506200050c919062000510565b5090565b6200053591905b808211156200053157600081600090555060010162000517565b5090565b90565b610b4e80620005486000396000f3fe608060405234801561001057600080fd5b506004361061005b5760003560e01c8063871ebe1814610061578063a98bfaad146100a7578063d96a2deb146100ed578063e7af077914610112578063fae71ae8146101cd5761005c565b5b600080fd5b61008d6004803603602081101561007757600080fd5b810190808035906020019092919050505061029c565b604051808215151515815260200191505060405180910390f35b6100d3600480360360208110156100bd57600080fd5b81019080803590602001909291905050506102c9565b604051808215151515815260200191505060405180910390f35b6100f561036c565b604051808381526020018281526020019250505060405180910390f35b6101cb6004803603602081101561012857600080fd5b810190808035906020019064010000000081111561014557600080fd5b82018360208201111561015757600080fd5b8035906020019184600183028401116401000000008311171561017957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610398565b005b61029a600480360360608110156101e357600080fd5b8101908080359060200190929190803590602001909291908035906020019064010000000081111561021457600080fd5b82018360208201111561022657600080fd5b8035906020019184600183028401116401000000008311171561024857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506106a7565b005b60006005600083815260200190815260200160002060000160009054906101000a900460ff169050919050565b6000806005600084815260200190815260200160002090508060000160009054906101000a900460ff16801561030457506001548160020154115b8015610317575080600601548160020154145b80156103645750600360009054906101000a900467ffffffffffffffff1667ffffffffffffffff168160040160009054906101000a900467ffffffffffffffff1667ffffffffffffffff16145b915050919050565b600080600060056000805481526020019081526020016000209050806002015460005492509250509091565b6103a0610931565b6103a98261081f565b90506000600560008360200151815260200190815260200160002090506001826040015103816002015414610429576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610a936026913960400191505060405180910390fd5b6000816006015414158015610445575080600201548160060154145b156104a9578160200151600254146104a8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180610ae86031913960400191505060405180910390fd5b5b6000816006015490506000836080015151146105465782604001518110610538576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4f7665726c617070696e67207369676e616c7320666f756e640000000000000081525060200191505060405180910390fd5b826060015183604001510190505b60008260040160009054906101000a900467ffffffffffffffff1690506000836005015490506000846003018054600181600116156101000203166002900490501461059a57846020015190506001820191505b6040518060e001604052806001151581526020018660200151815260200186604001518152602001866080015181526020018367ffffffffffffffff16815260200182815260200184815250600560008760000151815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301908051906020019061064d929190610966565b5060808201518160040160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060a0820151816005015560c082015181600601559050508460000151600081905550505050505050565b82600560008481526020019081526020016000206002015414610715576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180610ab9602f913960400191505060405180910390fd5b600060025490506000610729858585610923565b905060006005600083815260200190815260200160002090508160028190555080600201546001819055505b8282146108175760056000838152602001908152602001600020905080600101549150806006015481600201541415610812576000600560008360050154815260200190815260200160002090506001600360008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550806003016004908054600181600116156101000203166002900461080b9291906109e6565b5050610817565b610755565b505050505050565b610827610931565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa61085e57600080fd5b84519c5083519b5082519a50815199508051985050505050505050600082146108ef578167ffffffffffffffff8111801561089857600080fd5b506040519080825280601f01601f1916602001820160405280156108cb5781602001600182028036833780820191505090505b50905087516020890160208301848184846011600019fa6108eb57600080fd5b5050505b6040518060a00160405280878152602001868152602001858152602001848152602001828152509650505050505050919050565b600060025490509392505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106109a757805160ff19168380011785556109d5565b828001600101855582156109d5579182015b828111156109d45782518255916020019190600101906109b9565b5b5090506109e29190610a6d565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610a1f5780548555610a5c565b82800160010185558215610a5c57600052602060002091601f016020900482015b82811115610a5b578254825591600101919060010190610a40565b5b509050610a699190610a6d565b5090565b610a8f91905b80821115610a8b576000816000905550600101610a73565b5090565b9056fe4d697373696e6720706172656e74206865616465722066726f6d207468652073746f726167654d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f726167654d697373696e672072657175697265642066696e616c6974792070726f6f6620666f7220706172656e7420686561646572a26469706673582212207308ab4a5ec1ebd068b9ef3c5008f786849b0907d0b878561bbbd39b2561c84164736f6c63430006060033") .expect("code is hardcoded, thus valid; qed"), sub_host: "localhost".into(), sub_port: 9933, @@ -86,7 +86,7 @@ pub fn run(params: EthereumDeployContractParams) { let sub_client = substrate_client::client(&sub_uri); let (sub_client, initial_header) = prepare_initial_header(sub_client, params.sub_initial_header).await; - let (initial_header_hash, initial_header) = initial_header?; + let (initial_header_hash, raw_initial_header) = initial_header?; let initial_set_id = params.sub_initial_authorities_set_id.unwrap_or(0); let (_, initial_set) = prepare_initial_authorities_set( sub_client, @@ -95,8 +95,6 @@ pub fn run(params: EthereumDeployContractParams) { ).await; let initial_set = initial_set?; - let raw_initial_header = initial_header.encode(); - log::info!( target: "bridge", "Deploying Ethereum contract.\r\n\tInitial header: {}\r\n\tInitial authorities set ID: {}\r\n\tInitial authorities set: {}", diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index 128562f685..3c0fb56472 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -64,7 +64,14 @@ impl Default for EthereumSyncParams { sub_host: "localhost".into(), sub_port: 9933, sub_signer: sp_keyring::AccountKeyring::Alice.pair(), - sync_params: Default::default(), + sync_params: HeadersSyncParams { + max_future_headers_to_download: 8, + max_headers_in_submitted_status: 4, + max_headers_in_single_submit: 4, + max_headers_size_in_single_submit: 8 * 1024 * 1024, // we should never hit it + prune_depth: 256, + target_tx_mode: TargetTransactionMode::Signed, + }, } } } diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index 11f8354274..27fc85008a 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -35,23 +35,9 @@ type KnownHeaders

= BTreeMap< >, >; -/// Extra data mode. -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum ExtraMode { - /// Extra data only affects single header. When extra data for header - /// is provided, we may submit this header to the target node. - PerHeader, - /// Extra data affects header and all its ancestors. When extra data - /// for header is provided, we may submit this header and all unsubmitted - /// ancestors (if they're waiting for extra data) to the target node. - PerChain, -} - /// Ethereum headers queue. #[derive(Debug)] pub struct QueuedHeaders { - /// How we are trating extra data. - extra_mode: ExtraMode, /// Headers that are received from source node, but we (native sync code) have /// never seen their parents. So we need to check if we can/should submit this header. maybe_orphan: HeadersQueue

, @@ -79,9 +65,8 @@ pub struct QueuedHeaders { impl QueuedHeaders

{ /// Returns new QueuedHeaders. - pub fn new(extra_mode: ExtraMode) -> Self { + pub fn new() -> Self { QueuedHeaders { - extra_mode, maybe_orphan: HeadersQueue::new(), orphan: HeadersQueue::new(), maybe_extra: HeadersQueue::new(), @@ -142,7 +127,10 @@ impl QueuedHeaders

{ self.maybe_extra.keys().next_back().cloned().unwrap_or_else(Zero::zero), std::cmp::max( self.extra.keys().next_back().cloned().unwrap_or_else(Zero::zero), - self.ready.keys().next_back().cloned().unwrap_or_else(Zero::zero), + std::cmp::max( + self.ready.keys().next_back().cloned().unwrap_or_else(Zero::zero), + self.submitted.keys().next_back().cloned().unwrap_or_else(Zero::zero), + ), ), ), ), @@ -251,6 +239,7 @@ impl QueuedHeaders

{ // all ancestors of this header are now synced => let's remove them from // queues let mut current = *id; + let mut id_processed = false; loop { let header = match self.status(¤t) { HeaderStatus::Unknown => break, @@ -278,22 +267,25 @@ impl QueuedHeaders

{ .entry(current.1) .or_insert(HeaderStatus::Synced) = HeaderStatus::Synced; current = header.parent_id(); + id_processed = true; } // remember that the header is synced - log::debug!( - target: "bridge", - "{} header {:?} is now {:?}", - P::SOURCE_NAME, - id, - HeaderStatus::Synced, - ); - *self - .known_headers - .entry(id.0) - .or_default() - .entry(id.1) - .or_insert(HeaderStatus::Synced) = HeaderStatus::Synced; + if !id_processed { // to avoid duplicate log message + log::debug!( + target: "bridge", + "{} header {:?} is now {:?}", + P::SOURCE_NAME, + id, + HeaderStatus::Synced, + ); + *self + .known_headers + .entry(id.0) + .or_default() + .entry(id.1) + .or_insert(HeaderStatus::Synced) = HeaderStatus::Synced; + } // now let's move all descendants from maybe_orphan && orphan queues to // maybe_extra queue @@ -349,7 +341,7 @@ impl QueuedHeaders

{ /// Receive extra from source node. pub fn extra_response(&mut self, id: &HeaderId, extra: P::Extra) { // move header itself from extra to ready queue - let mut parent_id = move_header( + move_header( &mut self.extra, &mut self.ready, &mut self.known_headers, @@ -357,20 +349,6 @@ impl QueuedHeaders

{ id, |header| header.set_extra(extra), ); - - // if extra affects all ancestors, move them from extra to ready queue - if self.extra_mode == ExtraMode::PerChain { - while let Some(current_id) = parent_id { - parent_id = move_header( - &mut self.extra, - &mut self.ready, - &mut self.known_headers, - HeaderStatus::Ready, - ¤t_id, - |header| header, - ); - } - } } /// When header is submitted to target node. @@ -607,7 +585,7 @@ pub(crate) mod tests { #[test] fn total_headers_works() { // total headers just sums up number of headers in every queue - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue .maybe_orphan .entry(1) @@ -644,7 +622,7 @@ pub(crate) mod tests { #[test] fn best_queued_number_works() { // initially there are headers in MaybeOrphan queue only - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue .maybe_orphan .entry(1) @@ -694,7 +672,7 @@ pub(crate) mod tests { #[test] fn status_works() { // all headers are unknown initially - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); assert_eq!(queue.status(&id(10)), HeaderStatus::Unknown); // and status is read from the KnownHeaders queue @@ -708,7 +686,7 @@ pub(crate) mod tests { #[test] fn header_works() { // initially we have oldest header #10 - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue.maybe_orphan.entry(10).or_default().insert(hash(1), header(100)); assert_eq!( queue.header(HeaderStatus::MaybeOrphan).unwrap().header().hash.unwrap(), @@ -731,7 +709,7 @@ pub(crate) mod tests { #[test] fn header_response_works() { // when parent is Synced, we insert to MaybeExtra - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -741,7 +719,7 @@ pub(crate) mod tests { assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeExtra); // when parent is Ready, we insert to MaybeExtra - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -751,7 +729,7 @@ pub(crate) mod tests { assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeExtra); // when parent is Receipts, we insert to MaybeExtra - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -761,7 +739,7 @@ pub(crate) mod tests { assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeExtra); // when parent is MaybeExtra, we insert to MaybeExtra - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -771,7 +749,7 @@ pub(crate) mod tests { assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeExtra); // when parent is Orphan, we insert to Orphan - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -781,7 +759,7 @@ pub(crate) mod tests { assert_eq!(queue.status(&id(101)), HeaderStatus::Orphan); // when parent is MaybeOrphan, we insert to MaybeOrphan - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -791,7 +769,7 @@ pub(crate) mod tests { assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeOrphan); // when parent is unknown, we insert to MaybeOrphan - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue.header_response(header(101).header().clone()); assert_eq!(queue.status(&id(101)), HeaderStatus::MaybeOrphan); } @@ -805,7 +783,7 @@ pub(crate) mod tests { // #98 in MaybeExtra // #97 in Receipts // #96 in Ready - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -862,7 +840,7 @@ pub(crate) mod tests { // #101 in Orphan // #102 in MaybeOrphan // #103 in Orphan - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(101) @@ -904,7 +882,7 @@ pub(crate) mod tests { // #102 in MaybeOrphan // and we have asked for MaybeOrphan status of #100.parent (i.e. #99) // and the response is: YES, #99 is known to the Substrate runtime - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -949,7 +927,7 @@ pub(crate) mod tests { // #101 in MaybeOrphan // and we have asked for MaybeOrphan status of #100.parent (i.e. #99) // and the response is: NO, #99 is NOT known to the Substrate runtime - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -981,7 +959,7 @@ pub(crate) mod tests { #[test] fn positive_maybe_extra_response_works() { - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -1000,7 +978,7 @@ pub(crate) mod tests { #[test] fn negative_maybe_extra_response_works() { - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -1019,7 +997,7 @@ pub(crate) mod tests { #[test] fn receipts_response_works() { - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -1034,7 +1012,7 @@ pub(crate) mod tests { #[test] fn header_submitted_works() { - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(100) @@ -1048,7 +1026,7 @@ pub(crate) mod tests { #[test] fn prune_works() { - let mut queue = QueuedHeaders::::new(ExtraMode::PerHeader); + let mut queue = QueuedHeaders::::new(); queue .known_headers .entry(104) diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index 09c0724809..d27b1967ed 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -21,7 +21,7 @@ use crate::substrate_types::{ Header, Hash, Number, Justification, QueuedSubstrateHeader, SubstrateHeaderId, SubstrateHeadersSyncPipeline, }; -use crate::sync::HeadersSyncParams; +use crate::sync::{HeadersSyncParams, TargetTransactionMode}; use crate::sync_loop::{SourceClient, TargetClient}; use crate::sync_types::SourceHeader; use futures::future::{FutureExt, Ready, ready}; @@ -77,7 +77,14 @@ impl Default for SubstrateSyncParams { eth_gas_price: 8_000_000_000u64.into(), // 8 Gwei sub_host: "localhost".into(), sub_port: 9933, - sync_params: Default::default(), + sync_params: HeadersSyncParams { + max_future_headers_to_download: 128, + max_headers_in_submitted_status: 128, + max_headers_in_single_submit: 32, + max_headers_size_in_single_submit: 131_072, + prune_depth: 4096, + target_tx_mode: TargetTransactionMode::Signed, + }, } } } diff --git a/relays/ethereum/src/sync.rs b/relays/ethereum/src/sync.rs index 0fea40a17e..5eb2011e73 100644 --- a/relays/ethereum/src/sync.rs +++ b/relays/ethereum/src/sync.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::headers::{ExtraMode, QueuedHeaders}; +use crate::headers::QueuedHeaders; use crate::sync_types::{HeaderId, HeaderStatus, HeadersSyncPipeline, QueuedHeader}; use num_traits::{One, Saturating}; @@ -34,8 +34,6 @@ pub struct HeadersSyncParams { pub prune_depth: u32, /// Target transactions mode. pub target_tx_mode: TargetTransactionMode, - /// Extra data synchronization mode. - pub extra_mode: ExtraMode, } /// Target transaction mode. @@ -67,7 +65,7 @@ impl HeadersSync

{ /// Creates new headers synchronizer. pub fn new(params: HeadersSyncParams) -> Self { HeadersSync { - headers: QueuedHeaders::new(params.extra_mode), + headers: QueuedHeaders::new(), params, source_best_number: None, target_best_header: None, @@ -206,20 +204,6 @@ impl HeadersSync

{ } } -impl Default for HeadersSyncParams { - fn default() -> Self { - HeadersSyncParams { - max_future_headers_to_download: 128, - max_headers_in_submitted_status: 128, - max_headers_in_single_submit: 32, - max_headers_size_in_single_submit: 131_072, - prune_depth: 4096, - target_tx_mode: TargetTransactionMode::Signed, - extra_mode: ExtraMode::PerHeader, - } - } -} - #[cfg(test)] mod tests { use super::*; From ac393dabcb7c0462f24e17fb7f305177b18501d4 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 13 Apr 2020 13:06:13 +0300 Subject: [PATCH 18/92] more fixes --- modules/ethereum-contract/builtin/src/lib.rs | 204 +-------- .../contracts/substrate-bridge.sol | 419 ++++++++++-------- .../contracts/substrate-bridge2.sol | 321 -------------- relays/ethereum/res/substrate-bridge.json | 2 +- 4 files changed, 255 insertions(+), 691 deletions(-) delete mode 100644 modules/ethereum-contract/contracts/substrate-bridge2.sol diff --git a/modules/ethereum-contract/builtin/src/lib.rs b/modules/ethereum-contract/builtin/src/lib.rs index 4528ebeab9..e59f604b01 100644 --- a/modules/ethereum-contract/builtin/src/lib.rs +++ b/modules/ethereum-contract/builtin/src/lib.rs @@ -17,7 +17,6 @@ use codec::{Encode, Decode}; use bridge_node_runtime::{BlockNumber, Hash, Header as RuntimeHeader}; use sp_blockchain::Error as ClientError; -use sp_finality_grandpa::AuthorityList; /// Builtin errors. #[derive(Debug)] @@ -30,8 +29,6 @@ pub enum Error { FinalityProofDecode(codec::Error), /// Failed to verify justification. JustificationVerify(ClientError), - /// - NoNewHeaders, } /// Substrate header. @@ -61,6 +58,8 @@ pub struct ValidatorsSetSignal { pub enum FinalityProof { /// GRANDPA justification. Justification(Vec), + /// GRANDPA commit. + Commit(Vec), } /// Parse Substrate header. @@ -70,203 +69,18 @@ pub fn parse_substrate_header(raw_header: &[u8]) -> Result { hash: header.hash(), parent_hash: header.parent_hash, number: header.number, - signal: None, // TODO + signal: None, // TODO: parse me }) .map_err(Error::HeaderDecode) } /// Verify GRANDPA finality proof. pub fn verify_substrate_finality_proof( - best_set_id: u64, - raw_best_voters: &[u8], - raw_best_header: &[u8], - raw_headers: &[&[u8]], - raw_finality_proof: &[u8], + _best_set_id: u64, + _raw_best_voters: &[u8], + _raw_best_header: &[u8], + _raw_headers: &[&[u8]], + _raw_finality_proof: &[u8], ) -> Result<(usize, usize), Error> { - let best_voters = AuthorityList::decode(&mut &raw_best_voters[..]) - .map_err(Error::BestVotersDecode)?; - let finality_proof = FinalityProof::decode(&mut &raw_finality_proof[..]) - .map_err(Error::FinalityProofDecode)?; - - let _best_header = RuntimeHeader::decode(&mut &raw_best_header[..]) - .map_err(Error::HeaderDecode)?; - let headers = raw_headers - .iter() - .map(|raw_header| RuntimeHeader::decode(&mut &raw_header[..]) - .map_err(Error::HeaderDecode) - ) - .collect::, _>>()?; - - let finality_target = match headers.last() { - Some(header) => (header.hash(), header.number), - None => return Err(Error::NoNewHeaders), - }; - - match finality_proof { - FinalityProof::Justification(raw_justification) => { - substrate::GrandpaJustification::decode_and_verify_finalizes( - &raw_justification, - finality_target, - best_set_id, - &best_voters.into_iter().collect(), - ).map_err(Error::JustificationVerify)?; - }, - } - - Ok((0, headers.len())) -} - -// =================================================================================================== -// =================================================================================================== -// =================================================================================================== - - -mod substrate { - use std::collections::HashMap; - use codec::{Encode, Decode}; - use bridge_node_runtime::{BlockNumber, Hash, Header as RuntimeHeader}; - use finality_grandpa::{voter_set::VoterSet}; - use sp_blockchain::Error as ClientError; - use sp_finality_grandpa::{AuthorityId, AuthoritySignature}; - - /// A commit message for this chain's block type. - pub type Commit = finality_grandpa::Commit; - - /// GRANDPA justification. - #[derive(Encode, Decode)] - pub struct GrandpaJustification { - pub round: u64, - pub commit: Commit, - pub votes_ancestries: Vec, - } - - impl GrandpaJustification { - /// Decode a GRANDPA justification and validate the commit and the votes' - /// ancestry proofs finalize the given block. - pub(crate) fn decode_and_verify_finalizes( - encoded: &[u8], - finalized_target: (Hash, BlockNumber), - set_id: u64, - voters: &VoterSet, - ) -> Result { - - let justification = GrandpaJustification::decode(&mut &*encoded) - .map_err(|_| ClientError::JustificationDecode)?; - - if (justification.commit.target_hash, justification.commit.target_number) != finalized_target { - let msg = "invalid commit target in grandpa justification".to_string(); - Err(ClientError::BadJustification(msg)) - } else { - justification.verify(set_id, voters).map(|_| justification) - } - } - - /// Validate the commit and the votes' ancestry proofs. - pub(crate) fn verify(&self, _set_id: u64, voters: &VoterSet) -> Result<(), ClientError> { -// use finality_grandpa::Chain; - - let ancestry_chain = AncestryChain::new(&self.votes_ancestries); - - match finality_grandpa::validate_commit( - &self.commit, - voters, - &ancestry_chain, - ) { - Ok(ref result) if result.ghost().is_some() => {}, - _ => { - let msg = "invalid commit in grandpa justification".to_string(); - return Err(ClientError::BadJustification(msg)); - } - } -/* TODO - let mut buf = Vec::new(); - let mut visited_hashes = HashSet::new(); - for signed in self.commit.precommits.iter() { - if let Err(_) = communication::check_message_sig_with_buffer::( - &finality_grandpa::Message::Precommit(signed.precommit.clone()), - &signed.id, - &signed.signature, - self.round, - set_id, - &mut buf, - ) { - return Err(ClientError::BadJustification( - "invalid signature for precommit in grandpa justification".to_string()).into()); - } - - if self.commit.target_hash == signed.precommit.target_hash { - continue; - } - - match ancestry_chain.ancestry(self.commit.target_hash, signed.precommit.target_hash) { - Ok(route) => { - // ancestry starts from parent hash but the precommit target hash has been visited - visited_hashes.insert(signed.precommit.target_hash); - for hash in route { - visited_hashes.insert(hash); - } - }, - _ => { - return Err(ClientError::BadJustification( - "invalid precommit ancestry proof in grandpa justification".to_string()).into()); - }, - } - } - - let ancestry_hashes = self.votes_ancestries - .iter() - .map(|h: &Block::Header| h.hash()) - .collect(); - - if visited_hashes != ancestry_hashes { - return Err(ClientError::BadJustification( - "invalid precommit ancestries in grandpa justification with unused headers".to_string()).into()); - } -*/ - Ok(()) - } - } - - /// A utility trait implementing `finality_grandpa::Chain` using a given set of headers. - /// This is useful when validating commits, using the given set of headers to - /// verify a valid ancestry route to the target commit block. - struct AncestryChain { - ancestry: HashMap, - } - - impl AncestryChain { - fn new(ancestry: &[RuntimeHeader]) -> AncestryChain { - let ancestry: HashMap<_, _> = ancestry - .iter() - .cloned() - .map(|h: RuntimeHeader| (h.hash(), h)) - .collect(); - - AncestryChain { ancestry } - } - } - - impl finality_grandpa::Chain for AncestryChain { - fn ancestry(&self, base: Hash, block: Hash) -> Result, finality_grandpa::Error> { - let mut route = Vec::new(); - let mut current_hash = block; - loop { - if current_hash == base { break; } - match self.ancestry.get(¤t_hash) { - Some(current_header) => { - current_hash = current_header.parent_hash; - route.push(current_hash); - }, - _ => return Err(finality_grandpa::Error::NotDescendent), - } - } - route.pop(); // remove the base - - Ok(route) - } - - fn best_chain_containing(&self, _block: Hash) -> Option<(Hash, BlockNumber)> { - None - } - } + Err(Error::JustificationVerify(ClientError::Msg("Not yet implemented".into()))) // TODO: implement me } diff --git a/modules/ethereum-contract/contracts/substrate-bridge.sol b/modules/ethereum-contract/contracts/substrate-bridge.sol index 452d310101..befd358c70 100644 --- a/modules/ethereum-contract/contracts/substrate-bridge.sol +++ b/modules/ethereum-contract/contracts/substrate-bridge.sol @@ -16,235 +16,306 @@ pragma solidity ^0.6.4; -// TODO: expose interface + switch to external+calldata after https://github.com/ethereum/solidity/issues/7929 - -// TODO: use ABIEncoderV2 to allow passing headers array as bytes[] and structs to constructor -// when ethabi will support it +// for simplicity, this contract works with 32-bit headers hashes and headers +// numbers that can be represented as uint256 (supporting uint256 arithmetics) /// @title Substrate-to-PoA Bridge Contract. contract SubstrateBridge { - /// Voter set as it is stored in the storage. - struct VoterSet { - /// Id of the set. - uint64 id; - /// Raw voter set. - bytes rawVoters; - } - - /// Voter set change signals. - struct VoterSetSignal { - /// keccak256(header.number) of the header that enacts this voter set. - bytes32 headerNumber; - /// Raw voter set. - bytes rawVoters; + /// Parsed header. + struct ParsedHeader { + /// Header hash. + bytes32 hash; + /// Parent header hash. + bytes32 parentHash; + /// Header number. + uint256 number; + /// Validators set change signal delay. + uint256 signalDelay; + /// Validators set change signal. + bytes signal; } /// Header as it is stored in the storage. struct Header { - /// keccak256(header.hash) of the next header, or bytes32(0) if it is the best header. - bytes32 nextHeaderKeccak; - /// Header hash. - bytes hash; + /// Flag to ensure that the header exists :/ + bool isKnown; + + /// Parent header hash. + bytes32 parentHash; /// Header number. - bytes number; + uint256 number; + + /// Validators set change signal. + bytes signal; + + /// ID of validators set that must finalize this header. This equals to same + /// field of the parent + 1 if parent header should enact new set. + uint64 validatorsSetId; + /// Hash of the latest header of this fork that has emitted last validators set + /// change signal. + bytes32 prevSignalHeaderHash; + /// Number of the header where latest signal of this fork must be enacted. + uint256 prevSignalTargetNumber; } /// Initializes bridge contract. - /// @param rawInitialHeader Vec of single element - raw finalized header that will be ancestor of all importing headers. - /// @param initialVotersSetId ID of GRANDPA voter set that must finalize direct children of the initial header. - /// @param initialRawVoters Raw GRANDPA voter set that must finalize direct children of the initial header. + /// @param rawInitialHeader Raw finalized header that will be ancestor of all importing headers. + /// @param initialValidatorsSetId ID of validators set that must finalize direct children of the initial header. + /// @param initialValidatorsSet Raw validators set that must finalize direct children of the initial header. constructor( bytes memory rawInitialHeader, - uint64 initialVotersSetId, - bytes memory initialRawVoters + uint64 initialValidatorsSetId, + bytes memory initialValidatorsSet ) public { - // save initial header - ( - Header memory initialHeader, - VoterSetSignal memory voterSetSignal - ) = parseSubstrateHeader( - 0, - rawInitialHeader - ); - bytes32 headerKeccak = saveBestHeader(initialHeader); - oldestHeaderKeccak = headerKeccak; - // save best voter set - bestVoterSet.id = initialVotersSetId; - bestVoterSet.rawVoters = initialRawVoters; + // parse and save header + ParsedHeader memory header = parseSubstrateHeader(rawInitialHeader); + lastImportedHeaderHash = header.hash; + bestFinalizedHeaderHash = header.hash; + bestFinalizedHeaderNumber = header.number; + headerByHash[header.hash] = Header({ + isKnown: true, + parentHash: header.parentHash, + number: header.number, + signal: header.signal, + validatorsSetId: initialValidatorsSetId, + prevSignalHeaderHash: bytes32(0), + prevSignalTargetNumber: 0 + }); + + // save best validators set + bestFinalizedValidatorsSetId = initialValidatorsSetId; + bestFinalizedValidatorsSet = initialValidatorsSet; } /// Reject direct payments. fallback() external { revert(); } - /// Returns hash of the best known header. - function bestKnownHeader() public view returns (bytes memory, bytes memory) { - Header storage bestHeader = headerByKeccak[bestHeaderKeccak]; - return (bestHeader.number, bestHeader.hash); + /// Returns number and hash of the best known header. Best known header is + /// the last header we have received, no matter hash or number. We can't + /// verify unfinalized header => we are only signalling relay that we are + /// receiving new headers here, so honest relay can continue to submit valid + /// headers and, eventually, finality proofs. + function bestKnownHeader() public view returns (uint256, bytes32) { + Header storage lastImportedHeader = headerByHash[lastImportedHeaderHash]; + return (lastImportedHeader.number, lastImportedHeaderHash); } /// Returns true if header is known to the bridge. /// @param headerHash Hash of the header we want to check. function isKnownHeader( - bytes memory headerHash + bytes32 headerHash ) public view returns (bool) { - return headerByKeccak[keccak256(headerHash)].hash.length != 0; + return headerByHash[headerHash].isKnown; } - /// Import range of headers with finalization data. - /// @param rawHeaders Vec of encoded finalized headers to import. - /// @param rawFinalityProof Data required to finalize rawHeaders. - function importHeaders( - bytes memory rawHeaders, - bytes memory rawFinalityProof + /// Returns true if finality proof is required for this header. + function isFinalityProofRequired( + bytes32 headerHash + ) public view returns (bool) { + Header storage header = headerByHash[headerHash]; + return header.isKnown + && header.number > bestFinalizedHeaderNumber + && header.number == header.prevSignalTargetNumber + && header.validatorsSetId == bestFinalizedValidatorsSetId; + } + + /// Import header. + function importHeader( + bytes memory rawHeader ) public { - // verify finalization data - (uint256 begin, uint256 end) = verifyFinalityProof( - bestVoterSet.id, - bestVoterSet.rawVoters, - headerByKeccak[bestHeaderKeccak].hash, - rawHeaders, - rawFinalityProof + // parse and save header + ParsedHeader memory header = parseSubstrateHeader(rawHeader); + Header storage parentHeader = headerByHash[header.parentHash]; + require( + parentHeader.number == header.number - 1, + "Missing parent header from the storage" ); - // save finalized headers - bool enactedNewSet = false; - for (uint256 i = begin; i < end; ++i) { - // parse header - ( - Header memory header, - VoterSetSignal memory voterSetSignal - ) = parseSubstrateHeader( - i, - rawHeaders + // forbid appending to fork until we'll get finality proof for header that + // requires it + if (parentHeader.prevSignalTargetNumber != 0 && parentHeader.prevSignalTargetNumber == parentHeader.number) { + require( + bestFinalizedHeaderHash == header.parentHash, + "Missing required finality proof for parent header" ); - - // save header to the storage - bytes32 headerNumberKeccak = keccak256(header.number); - saveBestHeader(header); - // save voters set signal (if signalled by the header) - if (voterSetSignal.rawVoters.length != 0) { - saveSignal(voterSetSignal); - } - // check if header enacts new set - bytes memory newRawVoters = voterSetByEnactNumber[headerNumberKeccak]; - if (newRawVoters.length != 0) { - require( - !enactedNewSet, - "Trying to enact several sets using single finality proof" - ); - - enactedNewSet = true; - bestVoterSet.id = bestVoterSet.id + 1; - bestVoterSet.rawVoters = newRawVoters; - } } - // prune oldest headers - if (storedHeadersCount > maxHeadersToStore) { - uint256 headersToPrune = storedHeadersCount - maxHeadersToStore; - for (uint256 i = 0; i < headersToPrune; ++i) { - pruneOldestHeader(); - } + // forbid overlapping signals + uint256 prevSignalTargetNumber = parentHeader.prevSignalTargetNumber; + if (header.signal.length != 0) { + require( + prevSignalTargetNumber < header.number, + "Overlapping signals found" + ); + prevSignalTargetNumber = header.number + header.signalDelay; } - } - /// Save best header to the storage. - /// @return keccak256(header.hash) - function saveBestHeader( - Header memory header - ) private returns (bytes32) { - bytes32 headerKeccak = keccak256(header.hash); - bytes32 previousHeaderKeccak = bestHeaderKeccak; - if (previousHeaderKeccak != bytes32(0)) { - headerByKeccak[previousHeaderKeccak].nextHeaderKeccak = headerKeccak; + // check if parent header has emitted validators set change signal + uint64 validatorsSetId = parentHeader.validatorsSetId; + bytes32 prevSignalHeaderHash = parentHeader.prevSignalHeaderHash; + if (parentHeader.signal.length != 0) { + prevSignalHeaderHash = header.parentHash; + validatorsSetId = validatorsSetId + 1; } - headerByKeccak[headerKeccak] = header; - bestHeaderKeccak = headerKeccak; - storedHeadersCount = storedHeadersCount + 1; - return headerKeccak; - } - /// Prune oldest header. - function pruneOldestHeader() private { - bytes32 headerKeccakToRemove = oldestHeaderKeccak; - Header storage oldestHeader = headerByKeccak[headerKeccakToRemove]; - oldestHeaderKeccak = oldestHeader.nextHeaderKeccak; - delete headerByKeccak[headerKeccakToRemove]; - storedHeadersCount = storedHeadersCount - 1; + // store header in the storage + headerByHash[header.hash] = Header({ + isKnown: true, + parentHash: header.parentHash, + number: header.number, + signal: header.signal, + validatorsSetId: validatorsSetId, + prevSignalHeaderHash: prevSignalHeaderHash, + prevSignalTargetNumber: prevSignalTargetNumber + }); + lastImportedHeaderHash = header.hash; } - /// Save voter set change signal to the storage. - function saveSignal( - VoterSetSignal memory voterSetSignal - ) private { + /// Import finality proof. + function importFinalityProof( + uint256 finalityTargetNumber, + bytes32 finalityTargetHash, + bytes memory rawFinalityProof + ) public { + // check that header that we're going to finalize is already imported require( - voterSetByEnactNumber[voterSetSignal.headerNumber].length == 0, - "Duplicate signal for the same block" + headerByHash[finalityTargetHash].number == finalityTargetNumber, + "Missing finality target header from the storage" + ); + + // verify finality proof + bytes32 oldBestFinalizedHeaderHash = bestFinalizedHeaderHash; + bytes32 newBestFinalizedHeaderHash = verifyFinalityProof( + finalityTargetNumber, + finalityTargetHash, + rawFinalityProof ); - voterSetByEnactNumber[voterSetSignal.headerNumber] = voterSetSignal.rawVoters; + + // remember new best finalized header + Header storage newFinalizedHeader = headerByHash[newBestFinalizedHeaderHash]; + bestFinalizedHeaderHash = newBestFinalizedHeaderHash; + bestFinalizedHeaderNumber = newFinalizedHeader.number; + + // apply validators set change signal if required + while (newBestFinalizedHeaderHash != oldBestFinalizedHeaderHash) { + newFinalizedHeader = headerByHash[newBestFinalizedHeaderHash]; + newBestFinalizedHeaderHash = newFinalizedHeader.parentHash; + // if we are finalizing header that should enact validators set change, do this + // (this only affects latest scheduled change) + if (newFinalizedHeader.number == newFinalizedHeader.prevSignalTargetNumber) { + Header storage signalHeader = headerByHash[newFinalizedHeader.prevSignalHeaderHash]; + bestFinalizedValidatorsSetId += 1; + bestFinalizedValidatorsSet = signalHeader.signal; + break; + } + } } - /// Parse i-th Substrate header from the raw headers vector. - /// @return header.hash, header.number and optional voter set signal. + /// Parse Substrate header. function parseSubstrateHeader( - uint256 headerIndex, - bytes memory rawHeaders - ) private returns (Header memory, VoterSetSignal memory) { - // https://ethereum.stackexchange.com/questions/76346/how-to-call-ecrecover-in-pure-assembly + bytes memory rawHeader + ) private view returns (ParsedHeader memory) { + bytes32 headerHash; + bytes32 headerParentHash; + uint256 headerNumber; + uint256 headerSignalDelay; + uint256 headerSignalSize; + bytes memory headerSignal; + assembly { - let pointer := mload(0x40) - let rawHeadersLength := mload(rawHeaders) - let rawHeadersPointer := add(rawHeaders, 0x20) -/* mstore(pointer, headerIndex) - mstore(add(pointer, 0x20), rawHeaders) - mstore(add(pointer, 0x40), rawHeadersLength)*/ - // ?, builtin_address, in_off, in_size, out_off, out_size - // call parse: staticcall(?, builtinAddress, inPointer, inSize, outPointer, outSize) - if iszero(staticcall(not(0), 0x10, rawHeadersPointer, rawHeadersLength, pointer, 0x00)) { + // inputs + let rawHeaderSize := mload(rawHeader) + let rawHeaderPointer := add(rawHeader, 0x20) + + // output + let headerHashPointer := mload(0x40) + let headerParentHashPointer := add(headerHashPointer, 0x20) + let headerNumberPointer := add(headerParentHashPointer, 0x20) + let headerSignalDelayPointer := add(headerNumberPointer, 0x20) + let headerSignalSizePointer := add(headerSignalDelayPointer, 0x20) + + // parse substrate header + if iszero(staticcall( + not(0), + SUBSTRATE_PARSE_HEADER_BUILTIN_ADDRESS, + rawHeaderPointer, + rawHeaderSize, + headerHashPointer, + 0xA0 + )) { revert(0, 0) } + + // fill basic header fields + headerHash := mload(headerHashPointer) + headerParentHash := mload(headerParentHashPointer) + headerNumber := mload(headerNumberPointer) + headerSignalDelay := mload(headerSignalDelayPointer) + headerSignalSize := mload(headerSignalSizePointer) } + // if validators set change is signalled, read it + if (headerSignalSize != 0) { + headerSignal = new bytes(headerSignalSize); + + assembly { + // inputs + let rawHeadersSize := mload(rawHeader) + let rawHeadersPointer := add(rawHeader, 0x20) - return ( - Header({ - nextHeaderKeccak: bytes32(0), - hash: abi.encodePacked(keccak256(abi.encode(headerIndex, rawHeaders))), - number: abi.encodePacked(headerIndex) - }), - VoterSetSignal({ - headerNumber: bytes32(0), - rawVoters: "" - }) - ); // TODO: replace with builtin call + // output + let headerSignalPointer := add(headerSignal, 0x20) + + // get substrate header valdiators set change signal + if iszero(staticcall( + not(0), + SUBSTRATE_GET_HEADER_SIGNAL_BUILTIN_ADDRESS, + rawHeadersPointer, + rawHeadersSize, + headerSignalPointer, + headerSignalSize + )) { + revert(0, 0) + } + } + } + + return ParsedHeader({ + hash: headerHash, + parentHash: headerParentHash, + number: headerNumber, + signalDelay: headerSignalDelay, + signal: headerSignal + }); } + /// Verify finality proof. - /// @return Range of headers within rawHeaders that are proved to be final. function verifyFinalityProof( - uint64 /*currentSetId*/, - bytes memory /*rawCurrentVoters*/, - bytes memory /*rawBestHeader*/, - bytes memory /*rawHeaders*/, + uint256 /*finalityTargetNumber*/, + bytes32 /*finalityTargetHash*/, bytes memory /*rawFinalityProof*/ - ) private pure returns (uint256, uint256) { - return (0, 0); // TODO: replace with builtin call + ) private view returns (bytes32) { + return bestFinalizedHeaderHash; // TODO: call builtin instead } - /// Maximal number of headers that we store. - uint256 constant maxHeadersToStore = 1024; - - /// Current number of headers that we store. - uint256 storedHeadersCount; - /// keccak256(header.hash) of the oldest header. - bytes32 oldestHeaderKeccak; - /// keccak256(header.hash) of the last finalized block. - bytes32 bestHeaderKeccak; - /// Raw voter set for the last finalized block. - VoterSet bestVoterSet; - /// Map of keccak256(header.hash) => header. - mapping (bytes32 => Header) headerByKeccak; - /// Map of keccak256(header.number) => raw voter set that is enacted when block - /// with given number is finalized. - mapping (bytes32 => bytes) voterSetByEnactNumber; + /// Address of parse_substrate_header builtin. + uint256 constant SUBSTRATE_PARSE_HEADER_BUILTIN_ADDRESS = 0x10; + /// Address of get_substrate_validators_set_signal builtin. + uint256 constant SUBSTRATE_GET_HEADER_SIGNAL_BUILTIN_ADDRESS = 0x11; + + /// Last imported header hash. + bytes32 lastImportedHeaderHash; + + /// Best finalized header number. + uint256 bestFinalizedHeaderNumber; + /// Best finalized header hash. + bytes32 bestFinalizedHeaderHash; + /// Best finalized validators set id. + uint64 bestFinalizedValidatorsSetId; + /// Best finalized validators set. + bytes bestFinalizedValidatorsSet; + + /// Map of headers by their hashes. + mapping (bytes32 => Header) headerByHash; } diff --git a/modules/ethereum-contract/contracts/substrate-bridge2.sol b/modules/ethereum-contract/contracts/substrate-bridge2.sol deleted file mode 100644 index befd358c70..0000000000 --- a/modules/ethereum-contract/contracts/substrate-bridge2.sol +++ /dev/null @@ -1,321 +0,0 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity Bridges Common is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity Bridges Common. If not, see . - -pragma solidity ^0.6.4; - -// for simplicity, this contract works with 32-bit headers hashes and headers -// numbers that can be represented as uint256 (supporting uint256 arithmetics) - -/// @title Substrate-to-PoA Bridge Contract. -contract SubstrateBridge { - /// Parsed header. - struct ParsedHeader { - /// Header hash. - bytes32 hash; - /// Parent header hash. - bytes32 parentHash; - /// Header number. - uint256 number; - /// Validators set change signal delay. - uint256 signalDelay; - /// Validators set change signal. - bytes signal; - } - - /// Header as it is stored in the storage. - struct Header { - /// Flag to ensure that the header exists :/ - bool isKnown; - - /// Parent header hash. - bytes32 parentHash; - /// Header number. - uint256 number; - - /// Validators set change signal. - bytes signal; - - /// ID of validators set that must finalize this header. This equals to same - /// field of the parent + 1 if parent header should enact new set. - uint64 validatorsSetId; - /// Hash of the latest header of this fork that has emitted last validators set - /// change signal. - bytes32 prevSignalHeaderHash; - /// Number of the header where latest signal of this fork must be enacted. - uint256 prevSignalTargetNumber; - } - - /// Initializes bridge contract. - /// @param rawInitialHeader Raw finalized header that will be ancestor of all importing headers. - /// @param initialValidatorsSetId ID of validators set that must finalize direct children of the initial header. - /// @param initialValidatorsSet Raw validators set that must finalize direct children of the initial header. - constructor( - bytes memory rawInitialHeader, - uint64 initialValidatorsSetId, - bytes memory initialValidatorsSet - ) public { - // parse and save header - ParsedHeader memory header = parseSubstrateHeader(rawInitialHeader); - lastImportedHeaderHash = header.hash; - bestFinalizedHeaderHash = header.hash; - bestFinalizedHeaderNumber = header.number; - headerByHash[header.hash] = Header({ - isKnown: true, - parentHash: header.parentHash, - number: header.number, - signal: header.signal, - validatorsSetId: initialValidatorsSetId, - prevSignalHeaderHash: bytes32(0), - prevSignalTargetNumber: 0 - }); - - // save best validators set - bestFinalizedValidatorsSetId = initialValidatorsSetId; - bestFinalizedValidatorsSet = initialValidatorsSet; - } - - /// Reject direct payments. - fallback() external { revert(); } - - /// Returns number and hash of the best known header. Best known header is - /// the last header we have received, no matter hash or number. We can't - /// verify unfinalized header => we are only signalling relay that we are - /// receiving new headers here, so honest relay can continue to submit valid - /// headers and, eventually, finality proofs. - function bestKnownHeader() public view returns (uint256, bytes32) { - Header storage lastImportedHeader = headerByHash[lastImportedHeaderHash]; - return (lastImportedHeader.number, lastImportedHeaderHash); - } - - /// Returns true if header is known to the bridge. - /// @param headerHash Hash of the header we want to check. - function isKnownHeader( - bytes32 headerHash - ) public view returns (bool) { - return headerByHash[headerHash].isKnown; - } - - /// Returns true if finality proof is required for this header. - function isFinalityProofRequired( - bytes32 headerHash - ) public view returns (bool) { - Header storage header = headerByHash[headerHash]; - return header.isKnown - && header.number > bestFinalizedHeaderNumber - && header.number == header.prevSignalTargetNumber - && header.validatorsSetId == bestFinalizedValidatorsSetId; - } - - /// Import header. - function importHeader( - bytes memory rawHeader - ) public { - // parse and save header - ParsedHeader memory header = parseSubstrateHeader(rawHeader); - Header storage parentHeader = headerByHash[header.parentHash]; - require( - parentHeader.number == header.number - 1, - "Missing parent header from the storage" - ); - - // forbid appending to fork until we'll get finality proof for header that - // requires it - if (parentHeader.prevSignalTargetNumber != 0 && parentHeader.prevSignalTargetNumber == parentHeader.number) { - require( - bestFinalizedHeaderHash == header.parentHash, - "Missing required finality proof for parent header" - ); - } - - // forbid overlapping signals - uint256 prevSignalTargetNumber = parentHeader.prevSignalTargetNumber; - if (header.signal.length != 0) { - require( - prevSignalTargetNumber < header.number, - "Overlapping signals found" - ); - prevSignalTargetNumber = header.number + header.signalDelay; - } - - // check if parent header has emitted validators set change signal - uint64 validatorsSetId = parentHeader.validatorsSetId; - bytes32 prevSignalHeaderHash = parentHeader.prevSignalHeaderHash; - if (parentHeader.signal.length != 0) { - prevSignalHeaderHash = header.parentHash; - validatorsSetId = validatorsSetId + 1; - } - - // store header in the storage - headerByHash[header.hash] = Header({ - isKnown: true, - parentHash: header.parentHash, - number: header.number, - signal: header.signal, - validatorsSetId: validatorsSetId, - prevSignalHeaderHash: prevSignalHeaderHash, - prevSignalTargetNumber: prevSignalTargetNumber - }); - lastImportedHeaderHash = header.hash; - } - - /// Import finality proof. - function importFinalityProof( - uint256 finalityTargetNumber, - bytes32 finalityTargetHash, - bytes memory rawFinalityProof - ) public { - // check that header that we're going to finalize is already imported - require( - headerByHash[finalityTargetHash].number == finalityTargetNumber, - "Missing finality target header from the storage" - ); - - // verify finality proof - bytes32 oldBestFinalizedHeaderHash = bestFinalizedHeaderHash; - bytes32 newBestFinalizedHeaderHash = verifyFinalityProof( - finalityTargetNumber, - finalityTargetHash, - rawFinalityProof - ); - - // remember new best finalized header - Header storage newFinalizedHeader = headerByHash[newBestFinalizedHeaderHash]; - bestFinalizedHeaderHash = newBestFinalizedHeaderHash; - bestFinalizedHeaderNumber = newFinalizedHeader.number; - - // apply validators set change signal if required - while (newBestFinalizedHeaderHash != oldBestFinalizedHeaderHash) { - newFinalizedHeader = headerByHash[newBestFinalizedHeaderHash]; - newBestFinalizedHeaderHash = newFinalizedHeader.parentHash; - // if we are finalizing header that should enact validators set change, do this - // (this only affects latest scheduled change) - if (newFinalizedHeader.number == newFinalizedHeader.prevSignalTargetNumber) { - Header storage signalHeader = headerByHash[newFinalizedHeader.prevSignalHeaderHash]; - bestFinalizedValidatorsSetId += 1; - bestFinalizedValidatorsSet = signalHeader.signal; - break; - } - } - } - - /// Parse Substrate header. - function parseSubstrateHeader( - bytes memory rawHeader - ) private view returns (ParsedHeader memory) { - bytes32 headerHash; - bytes32 headerParentHash; - uint256 headerNumber; - uint256 headerSignalDelay; - uint256 headerSignalSize; - bytes memory headerSignal; - - assembly { - // inputs - let rawHeaderSize := mload(rawHeader) - let rawHeaderPointer := add(rawHeader, 0x20) - - // output - let headerHashPointer := mload(0x40) - let headerParentHashPointer := add(headerHashPointer, 0x20) - let headerNumberPointer := add(headerParentHashPointer, 0x20) - let headerSignalDelayPointer := add(headerNumberPointer, 0x20) - let headerSignalSizePointer := add(headerSignalDelayPointer, 0x20) - - // parse substrate header - if iszero(staticcall( - not(0), - SUBSTRATE_PARSE_HEADER_BUILTIN_ADDRESS, - rawHeaderPointer, - rawHeaderSize, - headerHashPointer, - 0xA0 - )) { - revert(0, 0) - } - - // fill basic header fields - headerHash := mload(headerHashPointer) - headerParentHash := mload(headerParentHashPointer) - headerNumber := mload(headerNumberPointer) - headerSignalDelay := mload(headerSignalDelayPointer) - headerSignalSize := mload(headerSignalSizePointer) - } - - // if validators set change is signalled, read it - if (headerSignalSize != 0) { - headerSignal = new bytes(headerSignalSize); - - assembly { - // inputs - let rawHeadersSize := mload(rawHeader) - let rawHeadersPointer := add(rawHeader, 0x20) - - // output - let headerSignalPointer := add(headerSignal, 0x20) - - // get substrate header valdiators set change signal - if iszero(staticcall( - not(0), - SUBSTRATE_GET_HEADER_SIGNAL_BUILTIN_ADDRESS, - rawHeadersPointer, - rawHeadersSize, - headerSignalPointer, - headerSignalSize - )) { - revert(0, 0) - } - } - } - - return ParsedHeader({ - hash: headerHash, - parentHash: headerParentHash, - number: headerNumber, - signalDelay: headerSignalDelay, - signal: headerSignal - }); - } - - - /// Verify finality proof. - function verifyFinalityProof( - uint256 /*finalityTargetNumber*/, - bytes32 /*finalityTargetHash*/, - bytes memory /*rawFinalityProof*/ - ) private view returns (bytes32) { - return bestFinalizedHeaderHash; // TODO: call builtin instead - } - - /// Address of parse_substrate_header builtin. - uint256 constant SUBSTRATE_PARSE_HEADER_BUILTIN_ADDRESS = 0x10; - /// Address of get_substrate_validators_set_signal builtin. - uint256 constant SUBSTRATE_GET_HEADER_SIGNAL_BUILTIN_ADDRESS = 0x11; - - /// Last imported header hash. - bytes32 lastImportedHeaderHash; - - /// Best finalized header number. - uint256 bestFinalizedHeaderNumber; - /// Best finalized header hash. - bytes32 bestFinalizedHeaderHash; - /// Best finalized validators set id. - uint64 bestFinalizedValidatorsSetId; - /// Best finalized validators set. - bytes bestFinalizedValidatorsSet; - - /// Map of headers by their hashes. - mapping (bytes32 => Header) headerByHash; -} diff --git a/relays/ethereum/res/substrate-bridge.json b/relays/ethereum/res/substrate-bridge.json index 58576c29b8..4ff57ab656 100644 --- a/relays/ethereum/res/substrate-bridge.json +++ b/relays/ethereum/res/substrate-bridge.json @@ -116,4 +116,4 @@ "stateMutability": "view", "type": "function" } -] \ No newline at end of file +] From abebf1ac215d9772ce5ab5bc9ce9614e3dd77a3a Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 13 Apr 2020 14:46:44 +0300 Subject: [PATCH 19/92] deal with duplicated params --- relays/ethereum/src/cli.yml | 32 +++++- relays/ethereum/src/ethereum_client.rs | 71 +++++++++--- .../ethereum/src/ethereum_deploy_contract.rs | 62 ++++------- relays/ethereum/src/ethereum_sync_loop.rs | 73 +++++-------- relays/ethereum/src/main.rs | 101 +++++++++++------- relays/ethereum/src/substrate_client.rs | 54 ++++++++-- relays/ethereum/src/substrate_sync_loop.rs | 88 +++++---------- 7 files changed, 267 insertions(+), 214 deletions(-) diff --git a/relays/ethereum/src/cli.yml b/relays/ethereum/src/cli.yml index 31ba127590..07b8ea4ebf 100644 --- a/relays/ethereum/src/cli.yml +++ b/relays/ethereum/src/cli.yml @@ -91,4 +91,34 @@ subcommands: - eth-signer: long: eth-signer value_name: ETH_SIGNER - help: Hex-encoded secret to use when transactions are submitted to the Ethereum node. \ No newline at end of file + help: Hex-encoded secret to use when transactions are submitted to the Ethereum node. + - eth-contract-code: + long: eth-contract-code + value_name: ETH_CONTRACT_CODE + help: Code of bridge contract. + takes_value: true + - sub-host: + long: sub-host + value_name: SUB_HOST + help: Connect to Substrate node at given host. + takes_value: true + - sub-port: + long: sub-port + value_name: SUB_PORT + help: Connect to Substrate node at given port. + takes_value: true + - sub-authorities-set-id: + long: sub-authorities-set-id + value_name: SUB_AUTHORITIES_SET_ID + help: ID of initial GRANDPA authorities set. + takes_value: true + - sub-authorities-set: + long: sub-authorities-set + value_name: SUB_AUTHORITIES_SET + help: Encoded initial GRANDPA authorities set. + takes_value: true + - sub-initial-header: + long: sub-initial-header + value_name: SUB_INITIAL_HEADER + help: Encoded initial Substrate header. + takes_value: true \ No newline at end of file diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index fb80b33cdf..31c3af0f9b 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -22,6 +22,7 @@ use ethabi::FunctionOutputDecoder; use jsonrpsee::common::Params; use jsonrpsee::raw::{RawClient, RawClientError}; use jsonrpsee::transport::http::{HttpTransportClient, RequestError}; +use parity_crypto::publickey::KeyPair; use serde::{Serialize, de::DeserializeOwned}; use serde_json::{from_value, to_value}; @@ -35,6 +36,51 @@ const INT_SERIALIZATION_PROOF: &'static str = "integer serialization never fails /// Proof of bool serialization success. const BOOL_SERIALIZATION_PROOF: &'static str = "bool serialization never fails; qed"; +/// Ethereum connection params. +#[derive(Debug)] +pub struct EthereumConnectionParams { + /// Ethereum RPC host. + pub host: String, + /// Ethereum RPC port. + pub port: u16, +} + +impl Default for EthereumConnectionParams { + fn default() -> Self { + EthereumConnectionParams { + host: "localhost".into(), + port: 8545, + } + } +} + +/// Ethereum signing params. +#[derive(Clone, Debug)] +pub struct EthereumSigningParams { + /// Ethereum chain id. + pub chain_id: u64, + /// Ethereum transactions signer. + pub signer: KeyPair, + /// Gas price we agree to pay. + pub gas_price: U256, +} + +impl Default for EthereumSigningParams { + fn default() -> Self { + EthereumSigningParams { + chain_id: 0x11, // Parity dev chain + // that the account that has a lot of ether when we run instant seal engine + // address: 0x00a329c0648769a73afac7f9381e08fb43dbea72 + // secret: 0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7 + signer: KeyPair::from_secret_slice( + &hex::decode("4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7") + .expect("secret is hardcoded, thus valid; qed"), + ).expect("secret is hardcoded, thus valid; qed"), + gas_price: 8_000_000_000u64.into(), // 8 Gwei + } + } +} + /// Ethereum client type. pub type Client = RawClient; @@ -74,8 +120,9 @@ impl MaybeConnectionError for Error { } /// Returns client that is able to call RPCs on Ethereum node. -pub fn client(uri: &str) -> Client { - let transport = HttpTransportClient::new(uri); +pub fn client(params: EthereumConnectionParams) -> Client { + let uri = format!("http://{}:{}", params.host, params.port); + let transport = HttpTransportClient::new(&uri); RawClient::new(transport) } @@ -238,13 +285,11 @@ pub async fn substrate_header_known( /// Submits Substrate headers to Ethereum contract. pub async fn submit_substrate_headers( client: Client, - signer: parity_crypto::publickey::KeyPair, - chain_id: u64, + params: EthereumSigningParams, contract_address: Address, - gas_price: U256, headers: Vec, ) -> (Client, Result<(Vec, Vec), Error>) { - let (mut client, nonce) = account_nonce(client, signer.address().as_fixed_bytes().into()).await; + let (mut client, nonce) = account_nonce(client, params.signer.address().as_fixed_bytes().into()).await; let mut nonce = match nonce { Ok(nonce) => nonce, Err(error) => return (client, Err(error)), @@ -270,9 +315,9 @@ pub async fn submit_substrate_headers( to: Some(contract_address), value: U256::zero(), gas: gas * 2, - gas_price, + gas_price: params.gas_price, data: encoded_call, - }.sign(&signer.secret().as_fixed_bytes().into(), &chain_id); + }.sign(¶ms.signer.secret().as_fixed_bytes().into(), ¶ms.chain_id); let (ret_client, result) = call_rpc( ret_client, "eth_submitTransaction", @@ -297,9 +342,7 @@ pub async fn submit_substrate_headers( /// Deploy bridge contract. pub async fn deploy_bridge_contract( client: Client, - signer: parity_crypto::publickey::KeyPair, - chain_id: u64, - gas_price: U256, + params: &EthereumSigningParams, contract_code: Vec, initial_header: Vec, initial_set_id: u64, @@ -311,7 +354,7 @@ pub async fn deploy_bridge_contract( initial_set_id, initial_authorities, ); - let (client, nonce) = account_nonce(client, signer.address().as_fixed_bytes().into()).await; + let (client, nonce) = account_nonce(client, params.signer.address().as_fixed_bytes().into()).await; let nonce = match nonce { Ok(nonce) => nonce, Err(error) => return (client, Err(error)), @@ -329,9 +372,9 @@ pub async fn deploy_bridge_contract( to: None, value: U256::zero(), gas, - gas_price, + gas_price: params.gas_price, data: encoded_call, - }.sign(&signer.secret().as_fixed_bytes().into(), &chain_id); + }.sign(¶ms.signer.secret().as_fixed_bytes().into(), ¶ms.chain_id); call_rpc( client, "eth_submitTransaction", diff --git a/relays/ethereum/src/ethereum_deploy_contract.rs b/relays/ethereum/src/ethereum_deploy_contract.rs index 4d82510544..86d30a1110 100644 --- a/relays/ethereum/src/ethereum_deploy_contract.rs +++ b/relays/ethereum/src/ethereum_deploy_contract.rs @@ -14,33 +14,23 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::ethereum_client; -use crate::ethereum_types::U256; -use crate::substrate_client; +use crate::ethereum_client::{EthereumConnectionParams, EthereumSigningParams, self}; +use crate::substrate_client::{SubstrateConnectionParams, self}; use crate::substrate_types::{Hash as SubstrateHash, Header as SubstrateHeader}; use codec::{Decode, Encode}; use num_traits::Zero; -use parity_crypto::publickey::KeyPair; /// Ethereum synchronization parameters. #[derive(Debug)] pub struct EthereumDeployContractParams { - /// Ethereum RPC host. - pub eth_host: String, - /// Ethereum RPC port. - pub eth_port: u16, - /// Ethereum chain id. - pub eth_chain_id: u64, - /// Ethereum transactions signer. - pub eth_signer: KeyPair, - /// Gas price we agree to pay. - pub eth_gas_price: U256, + /// Ethereum connection params. + pub eth: EthereumConnectionParams, + /// Ethereum signing params. + pub eth_sign: EthereumSigningParams, /// Ethereum contract bytecode. pub eth_contract_code: Vec, - /// Substrate RPC host. - pub sub_host: String, - /// Substrate RPC port. - pub sub_port: u16, + /// Substrate connection params. + pub sub: SubstrateConnectionParams, /// Initial authorities set id. pub sub_initial_authorities_set_id: Option, /// Initial authorities set. @@ -52,21 +42,12 @@ pub struct EthereumDeployContractParams { impl Default for EthereumDeployContractParams { fn default() -> Self { EthereumDeployContractParams { - eth_host: "localhost".into(), - eth_port: 8545, - eth_chain_id: 0x11, // Parity dev chain - // that the account that has a lot of ether when we run instant seal engine - // address: 0x00a329c0648769a73afac7f9381e08fb43dbea72 - // secret: 0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7 - eth_signer: KeyPair::from_secret_slice( - &hex::decode("4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7") - .expect("secret is hardcoded, thus valid; qed"), - ).expect("secret is hardcoded, thus valid; qed"), - eth_gas_price: 8_000_000_000u64.into(), // 8 Gwei - eth_contract_code: hex::decode("60806040523480156200001157600080fd5b506040516200109638038062001096833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b838201915060208201858111156200006f57600080fd5b82518660018202830111640100000000821117156200008d57600080fd5b8083526020830192505050908051906020019080838360005b83811015620000c3578082015181840152602081019050620000a6565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b5060405260200180519060200190929190805160405193929190846401000000008211156200011f57600080fd5b838201915060208201858111156200013657600080fd5b82518660018202830111640100000000821117156200015457600080fd5b8083526020830192505050908051906020019080838360005b838110156200018a5780820151818401526020810190506200016d565b50505050905090810190601f168015620001b85780820380516001836020036101000a031916815260200191505b50604052505050620001c962000454565b620001da846200034960201b60201c565b90508060000151600081905550806000015160028190555080604001516001819055506040518060e001604052806001151581526020018260200151815260200182604001518152602001826080015181526020018467ffffffffffffffff1681526020016000801b81526020016000815250600560008360000151815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160010155604082015181600201556060820151816003019080519060200190620002b692919062000489565b5060808201518160040160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060a0820151816005015560c0820151816006015590505082600360006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555081600490805190602001906200033e92919062000489565b505050505062000538565b6200035362000454565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa6200038b57600080fd5b84519c5083519b5082519a508151995080519850505050505050506000821462000420578167ffffffffffffffff81118015620003c757600080fd5b506040519080825280601f01601f191660200182016040528015620003fb5781602001600182028036833780820191505090505b50905087516020890160208301848184846011600019fa6200041c57600080fd5b5050505b6040518060a00160405280878152602001868152602001858152602001848152602001828152509650505050505050919050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620004cc57805160ff1916838001178555620004fd565b82800160010185558215620004fd579182015b82811115620004fc578251825591602001919060010190620004df565b5b5090506200050c919062000510565b5090565b6200053591905b808211156200053157600081600090555060010162000517565b5090565b90565b610b4e80620005486000396000f3fe608060405234801561001057600080fd5b506004361061005b5760003560e01c8063871ebe1814610061578063a98bfaad146100a7578063d96a2deb146100ed578063e7af077914610112578063fae71ae8146101cd5761005c565b5b600080fd5b61008d6004803603602081101561007757600080fd5b810190808035906020019092919050505061029c565b604051808215151515815260200191505060405180910390f35b6100d3600480360360208110156100bd57600080fd5b81019080803590602001909291905050506102c9565b604051808215151515815260200191505060405180910390f35b6100f561036c565b604051808381526020018281526020019250505060405180910390f35b6101cb6004803603602081101561012857600080fd5b810190808035906020019064010000000081111561014557600080fd5b82018360208201111561015757600080fd5b8035906020019184600183028401116401000000008311171561017957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610398565b005b61029a600480360360608110156101e357600080fd5b8101908080359060200190929190803590602001909291908035906020019064010000000081111561021457600080fd5b82018360208201111561022657600080fd5b8035906020019184600183028401116401000000008311171561024857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506106a7565b005b60006005600083815260200190815260200160002060000160009054906101000a900460ff169050919050565b6000806005600084815260200190815260200160002090508060000160009054906101000a900460ff16801561030457506001548160020154115b8015610317575080600601548160020154145b80156103645750600360009054906101000a900467ffffffffffffffff1667ffffffffffffffff168160040160009054906101000a900467ffffffffffffffff1667ffffffffffffffff16145b915050919050565b600080600060056000805481526020019081526020016000209050806002015460005492509250509091565b6103a0610931565b6103a98261081f565b90506000600560008360200151815260200190815260200160002090506001826040015103816002015414610429576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610a936026913960400191505060405180910390fd5b6000816006015414158015610445575080600201548160060154145b156104a9578160200151600254146104a8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180610ae86031913960400191505060405180910390fd5b5b6000816006015490506000836080015151146105465782604001518110610538576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4f7665726c617070696e67207369676e616c7320666f756e640000000000000081525060200191505060405180910390fd5b826060015183604001510190505b60008260040160009054906101000a900467ffffffffffffffff1690506000836005015490506000846003018054600181600116156101000203166002900490501461059a57846020015190506001820191505b6040518060e001604052806001151581526020018660200151815260200186604001518152602001866080015181526020018367ffffffffffffffff16815260200182815260200184815250600560008760000151815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301908051906020019061064d929190610966565b5060808201518160040160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060a0820151816005015560c082015181600601559050508460000151600081905550505050505050565b82600560008481526020019081526020016000206002015414610715576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180610ab9602f913960400191505060405180910390fd5b600060025490506000610729858585610923565b905060006005600083815260200190815260200160002090508160028190555080600201546001819055505b8282146108175760056000838152602001908152602001600020905080600101549150806006015481600201541415610812576000600560008360050154815260200190815260200160002090506001600360008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550806003016004908054600181600116156101000203166002900461080b9291906109e6565b5050610817565b610755565b505050505050565b610827610931565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa61085e57600080fd5b84519c5083519b5082519a50815199508051985050505050505050600082146108ef578167ffffffffffffffff8111801561089857600080fd5b506040519080825280601f01601f1916602001820160405280156108cb5781602001600182028036833780820191505090505b50905087516020890160208301848184846011600019fa6108eb57600080fd5b5050505b6040518060a00160405280878152602001868152602001858152602001848152602001828152509650505050505050919050565b600060025490509392505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106109a757805160ff19168380011785556109d5565b828001600101855582156109d5579182015b828111156109d45782518255916020019190600101906109b9565b5b5090506109e29190610a6d565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610a1f5780548555610a5c565b82800160010185558215610a5c57600052602060002091601f016020900482015b82811115610a5b578254825591600101919060010190610a40565b5b509050610a699190610a6d565b5090565b610a8f91905b80821115610a8b576000816000905550600101610a73565b5090565b9056fe4d697373696e6720706172656e74206865616465722066726f6d207468652073746f726167654d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f726167654d697373696e672072657175697265642066696e616c6974792070726f6f6620666f7220706172656e7420686561646572a26469706673582212207308ab4a5ec1ebd068b9ef3c5008f786849b0907d0b878561bbbd39b2561c84164736f6c63430006060033") + eth: Default::default(), + eth_sign: Default::default(), + // compiler: 0.6.6+commit.6c089d02 + optimization + eth_contract_code: hex::decode("60806040523480156200001157600080fd5b5060405162000dfa38038062000dfa833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b506040818152602083015192018051929491939192846401000000008211156200010f57600080fd5b9083019060208201858111156200012557600080fd5b82516401000000008111828201881017156200014057600080fd5b82525081516020918201929091019080838360005b838110156200016f57818101518382015260200162000155565b50505050905090810190601f1680156200019d5780820380516001836020036101000a031916815260200191505b50604052505050620001ae620003d4565b620001c2846001600160e01b03620002dc16565b805160008181556002918255604080840180516001908155825160e08101845281815260208088015181830190815293518286019081526080808a0151606085019081526001600160401b038e169185019190915260a0840188905260c084018890528951885260058352959096208251815460ff191690151517815593519284019290925593519482019490945590518051949550919390926200026f92600385019291019062000409565b506080820151600482810180546001600160401b03199081166001600160401b039485161790915560a0850151600585015560c09094015160069093019290925560038054909316908616179091558251620002d19190602085019062000409565b5050505050620004ae565b620002e6620003d4565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa6200031e57600080fd5b93519251915190519351929b50909950975090955093505082159050620003a757816001600160401b03811180156200035657600080fd5b506040519080825280601f01601f19166020018201604052801562000382576020820181803683370190505b50905087516020890160208301848184846011600019fa620003a357600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200044c57805160ff19168380011785556200047c565b828001600101855582156200047c579182015b828111156200047c5782518255916020019190600101906200045f565b506200048a9291506200048e565b5090565b620004ab91905b808211156200048a576000815560010162000495565b90565b61093c80620004be6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063871ebe181461005c578063a98bfaad1461008d578063d96a2deb146100aa578063e7af0779146100cb578063fae71ae814610173575b600080fd5b6100796004803603602081101561007257600080fd5b5035610225565b604080519115158252519081900360200190f35b610079600480360360208110156100a357600080fd5b503561023a565b6100b2610297565b6040805192835260208301919091528051918290030190f35b610171600480360360208110156100e157600080fd5b8101906020810181356401000000008111156100fc57600080fd5b82018360208201111561010e57600080fd5b8035906020019184600183028401116401000000008311171561013057600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506102af945050505050565b005b6101716004803603606081101561018957600080fd5b8135916020810135918101906060810160408201356401000000008111156101b057600080fd5b8201836020820111156101c257600080fd5b803590602001918460018302840111640100000000831117156101e457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610521945050505050565b60009081526005602052604090205460ff1690565b6000818152600560205260408120805460ff16801561025e57506001548160020154115b8015610271575080600601548160020154145b80156102905750600354600482015467ffffffffffffffff9081169116145b9392505050565b60008054808252600560205260409091206002015491565b6102b761073b565b6102c08261063f565b905060006005600083602001518152602001908152602001600020905060018260400151038160020154146103265760405162461bcd60e51b81526004018080602001828103825260268152602001806108816026913960400191505060405180910390fd5b600681015415801590610340575080600201548160060154145b15610389578160200151600254146103895760405162461bcd60e51b81526004018080602001828103825260318152602001806108d66031913960400191505060405180910390fd5b6006810154608083015151156103fe57826040015181106103f1576040805162461bcd60e51b815260206004820152601960248201527f4f7665726c617070696e67207369676e616c7320666f756e6400000000000000604482015290519081900360640190fd5b5060608201516040830151015b60048201546005830154600384015467ffffffffffffffff90921691600260001960018316156101000201909116041561043f575060208401516001909101905b6040805160e0810182526001808252602088810151818401908152898501518486019081526080808c01516060870190815267ffffffffffffffff8a169187019190915260a0860188905260c086018a90528b51600090815260058552969096208551815460ff19169015151781559151938201939093559151600283015592518051929391926104d69260038501920190610770565b50608082015160048201805467ffffffffffffffff191667ffffffffffffffff90921691909117905560a0820151600582015560c09091015160069091015550509151600055505050565b60008281526005602052604090206002015483146105705760405162461bcd60e51b815260040180806020018281038252602f8152602001806108a7602f913960400191505060405180910390fd5b6002546000610580858585610731565b600081815260056020526040902060028281558101546001559091505b828214610637575060009081526005602052604090206001810154600682015460028301549192911415610632576005818101546000908152602091909152604090206003805467ffffffffffffffff198116600167ffffffffffffffff9283168101909216178255908201805461062b9260049291600261010092821615929092026000190116046107ee565b5050610637565b61059d565b505050505050565b61064761073b565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa61067e57600080fd5b93519251915190519351929b50909950975090955093505082159050610704578167ffffffffffffffff811180156106b557600080fd5b506040519080825280601f01601f1916602001820160405280156106e0576020820181803683370190505b50905087516020890160208301848184846011600019fa61070057600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6002549392505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106107b157805160ff19168380011785556107de565b828001600101855582156107de579182015b828111156107de5782518255916020019190600101906107c3565b506107ea929150610863565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061082757805485556107de565b828001600101855582156107de57600052602060002091601f016020900482015b828111156107de578254825591600101919060010190610848565b61087d91905b808211156107ea5760008155600101610869565b9056fe4d697373696e6720706172656e74206865616465722066726f6d207468652073746f726167654d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f726167654d697373696e672072657175697265642066696e616c6974792070726f6f6620666f7220706172656e7420686561646572a2646970667358221220920ca01b59940884722a766076b4f1d1d825eba446e530980bd310f776703dad64736f6c63430006060033") .expect("code is hardcoded, thus valid; qed"), - sub_host: "localhost".into(), - sub_port: 9933, + sub: Default::default(), sub_initial_authorities_set_id: None, sub_initial_authorities_set: None, sub_initial_header: None, @@ -79,14 +60,11 @@ pub fn run(params: EthereumDeployContractParams) { let mut local_pool = futures::executor::LocalPool::new(); let result = local_pool.run_until(async move { - let eth_uri = format!("http://{}:{}", params.eth_host, params.eth_port); - let eth_client = ethereum_client::client(ð_uri); - - let sub_uri = format!("http://{}:{}", params.sub_host, params.sub_port); - let sub_client = substrate_client::client(&sub_uri); + let eth_client = ethereum_client::client(params.eth); + let sub_client = substrate_client::client(params.sub); let (sub_client, initial_header) = prepare_initial_header(sub_client, params.sub_initial_header).await; - let (initial_header_hash, raw_initial_header) = initial_header?; + let (initial_header_hash, initial_header) = initial_header?; let initial_set_id = params.sub_initial_authorities_set_id.unwrap_or(0); let (_, initial_set) = prepare_initial_authorities_set( sub_client, @@ -98,18 +76,16 @@ pub fn run(params: EthereumDeployContractParams) { log::info!( target: "bridge", "Deploying Ethereum contract.\r\n\tInitial header: {}\r\n\tInitial authorities set ID: {}\r\n\tInitial authorities set: {}", - hex::encode(&raw_initial_header), + hex::encode(&initial_header), initial_set_id, hex::encode(&initial_set), ); ethereum_client::deploy_bridge_contract( eth_client, - params.eth_signer, - params.eth_chain_id, - params.eth_gas_price, + ¶ms.eth_sign, params.eth_contract_code, - raw_initial_header, + initial_header, initial_set_id, initial_set, ).await.1.map_err(|error| format!("Error deploying contract: {:?}", error)) diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index 3c0fb56472..93f27af113 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -14,9 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::ethereum_client; +use crate::ethereum_client::{EthereumConnectionParams, self}; use crate::ethereum_types::{EthereumHeaderId, EthereumHeadersSyncPipeline, Header, QueuedEthereumHeader, Receipt}; -use crate::substrate_client; +use crate::substrate_client::{SubstrateConnectionParams, SubstrateSigningParams, self}; use crate::sync::{HeadersSyncParams, TargetTransactionMode}; use crate::sync_loop::{SourceClient, TargetClient}; use futures::future::{FutureExt, Ready, ready}; @@ -30,45 +30,27 @@ const SUBSTRATE_TICK_INTERVAL_MS: u64 = 5_000; /// Ethereum synchronization parameters. pub struct EthereumSyncParams { - /// Ethereum RPC host. - pub eth_host: String, - /// Ethereum RPC port. - pub eth_port: u16, - /// Substrate RPC host. - pub sub_host: String, - /// Substrate RPC port. - pub sub_port: u16, - /// Substrate transactions signer. - pub sub_signer: sp_core::sr25519::Pair, + /// Ethereum connection params. + pub eth: EthereumConnectionParams, + /// Substrate connection params. + pub sub: SubstrateConnectionParams, + /// Substrate signing params. + pub sub_sign: SubstrateSigningParams, /// Synchronization parameters. pub sync_params: HeadersSyncParams, } -impl std::fmt::Debug for EthereumSyncParams { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - f.debug_struct("EthereumSyncParams") - .field("eth_host", &self.eth_host) - .field("eth_port", &self.eth_port) - .field("sub_host", &self.sub_port) - .field("sub_port", &self.sub_port) - .field("sync_params", &self.sync_params) - .finish() - } -} - impl Default for EthereumSyncParams { fn default() -> Self { EthereumSyncParams { - eth_host: "localhost".into(), - eth_port: 8545, - sub_host: "localhost".into(), - sub_port: 9933, - sub_signer: sp_keyring::AccountKeyring::Alice.pair(), + eth: Default::default(), + sub: Default::default(), + sub_sign: Default::default(), sync_params: HeadersSyncParams { max_future_headers_to_download: 8, max_headers_in_submitted_status: 4, max_headers_in_single_submit: 4, - max_headers_size_in_single_submit: 8 * 1024 * 1024, // we should never hit it + max_headers_size_in_single_submit: 64 * 1024 * 1024, // something that we should never hit prune_depth: 256, target_tx_mode: TargetTransactionMode::Signed, }, @@ -123,10 +105,10 @@ impl SourceClient for EthereumHeadersSource { struct SubstrateHeadersTarget { /// Substrate node client. client: substrate_client::Client, - /// Substrate transactions signer. - signer: sp_core::sr25519::Pair, /// Whether we want to submit signed (true), or unsigned (false) transactions. sign_transactions: bool, + /// Substrate signing params. + sign_params: SubstrateSigningParams, } impl TargetClient for SubstrateHeadersTarget { @@ -138,14 +120,14 @@ impl TargetClient for SubstrateHeadersTarget { type SubmitHeadersFuture = Pin, Self::Error>)>>>; fn best_header_id(self) -> Self::BestHeaderIdFuture { - let (signer, sign_transactions) = (self.signer, self.sign_transactions); + let (sign_transactions, sign_params) = (self.sign_transactions, self.sign_params); substrate_client::best_ethereum_block(self.client) .map(move |(client, result)| { ( SubstrateHeadersTarget { client, - signer, sign_transactions, + sign_params, }, result, ) @@ -154,14 +136,14 @@ impl TargetClient for SubstrateHeadersTarget { } fn is_known_header(self, id: EthereumHeaderId) -> Self::IsKnownHeaderFuture { - let (signer, sign_transactions) = (self.signer, self.sign_transactions); + let (sign_transactions, sign_params) = (self.sign_transactions, self.sign_params); substrate_client::ethereum_header_known(self.client, id) .map(move |(client, result)| { ( SubstrateHeadersTarget { client, - signer, sign_transactions, + sign_params, }, result, ) @@ -177,14 +159,14 @@ impl TargetClient for SubstrateHeadersTarget { // we can minimize number of receipts_check calls by checking header // logs bloom here, but it may give us false positives (when authorities // source is contract, we never need any logs) - let (signer, sign_transactions) = (self.signer, self.sign_transactions); + let (sign_transactions, sign_params) = (self.sign_transactions, self.sign_params); substrate_client::ethereum_receipts_required(self.client, header.clone()) .map(move |(client, result)| { ( SubstrateHeadersTarget { client, - signer, sign_transactions, + sign_params, }, result, ) @@ -193,14 +175,14 @@ impl TargetClient for SubstrateHeadersTarget { } fn submit_headers(self, headers: Vec) -> Self::SubmitHeadersFuture { - let (signer, sign_transactions) = (self.signer, self.sign_transactions); - substrate_client::submit_ethereum_headers(self.client, signer.clone(), headers, sign_transactions) + let (sign_transactions, sign_params) = (self.sign_transactions, self.sign_params); + substrate_client::submit_ethereum_headers(self.client, sign_params.clone(), headers, sign_transactions) .map(move |(client, result)| { ( SubstrateHeadersTarget { client, - signer, sign_transactions, + sign_params, }, result.map(|(_, submitted_headers)| submitted_headers), ) @@ -211,12 +193,9 @@ impl TargetClient for SubstrateHeadersTarget { /// Run Ethereum headers synchronization. pub fn run(params: EthereumSyncParams) { - let eth_uri = format!("http://{}:{}", params.eth_host, params.eth_port); - let eth_client = ethereum_client::client(ð_uri); + let eth_client = ethereum_client::client(params.eth); + let sub_client = substrate_client::client(params.sub); - let sub_uri = format!("http://{}:{}", params.sub_host, params.sub_port); - let sub_client = substrate_client::client(&sub_uri); - let sub_signer = params.sub_signer; let sign_sub_transactions = match params.sync_params.target_tx_mode { TargetTransactionMode::Signed | TargetTransactionMode::Backup => true, TargetTransactionMode::Unsigned => false, @@ -227,8 +206,8 @@ pub fn run(params: EthereumSyncParams) { ETHEREUM_TICK_INTERVAL_MS, SubstrateHeadersTarget { client: sub_client, - signer: sub_signer, sign_transactions: sign_sub_transactions, + sign_params: params.sub_sign, }, SUBSTRATE_TICK_INTERVAL_MS, params.sync_params, diff --git a/relays/ethereum/src/main.rs b/relays/ethereum/src/main.rs index f2456e1914..129e2b8de1 100644 --- a/relays/ethereum/src/main.rs +++ b/relays/ethereum/src/main.rs @@ -28,9 +28,13 @@ mod sync; mod sync_loop; mod sync_types; -use parity_crypto::publickey::KeyPair; +use parity_crypto::publickey::{KeyPair, Secret}; use sp_core::crypto::Pair; use std::io::Write; +use ethereum_client::{EthereumConnectionParams, EthereumSigningParams}; +use ethereum_sync_loop::EthereumSyncParams; +use substrate_client::{SubstrateConnectionParams, SubstrateSigningParams}; +use substrate_sync_loop::SubstrateSyncParams; fn main() { initialize(); @@ -110,25 +114,62 @@ fn initialize() { builder.init(); } -fn ethereum_sync_params(matches: &clap::ArgMatches) -> Result { - let mut eth_sync_params = ethereum_sync_loop::EthereumSyncParams::default(); +fn ethereum_connection_params(matches: &clap::ArgMatches) -> Result { + let mut params = EthereumConnectionParams::default(); if let Some(eth_host) = matches.value_of("eth-host") { - eth_sync_params.eth_host = eth_host.into(); + params.host = eth_host.into(); } if let Some(eth_port) = matches.value_of("eth-port") { - eth_sync_params.eth_port = eth_port.parse().map_err(|e| format!("{}", e))?; + params.port = eth_port + .parse() + .map_err(|e| format!("Failed to parse eth-port: {}", e))?; } + Ok(params) +} + +fn ethereum_signing_params(matches: &clap::ArgMatches) -> Result { + let mut params = EthereumSigningParams::default(); + if let Some(eth_signer) = matches.value_of("eth-signer") { + params.signer = eth_signer + .parse::() + .map_err(|e| format!("Failed to parse eth-signer: {}", e)) + .and_then(|secret| KeyPair::from_secret(secret) + .map_err(|e| format!("Invalid eth-signer: {}", e)) + )?; + } + Ok(params) +} + +fn substrate_connection_params(matches: &clap::ArgMatches) -> Result { + let mut params = SubstrateConnectionParams::default(); if let Some(sub_host) = matches.value_of("sub-host") { - eth_sync_params.sub_host = sub_host.into(); + params.host = sub_host.into(); } if let Some(sub_port) = matches.value_of("sub-port") { - eth_sync_params.sub_port = sub_port.parse().map_err(|e| format!("{}", e))?; + params.port = sub_port + .parse() + .map_err(|e| format!("Failed to parse sub-port: {}", e))?; } + Ok(params) +} + +fn substrate_signing_params(matches: &clap::ArgMatches) -> Result { + let mut params = SubstrateSigningParams::default(); if let Some(sub_signer) = matches.value_of("sub-signer") { let sub_signer_password = matches.value_of("sub-signer-password"); - eth_sync_params.sub_signer = - sp_core::sr25519::Pair::from_string(sub_signer, sub_signer_password).map_err(|e| format!("{:?}", e))?; + params.signer = + sp_core::sr25519::Pair::from_string(sub_signer, sub_signer_password) + .map_err(|e| format!("Failed to parse sub-signer: {:?}", e))?; } + Ok(params) +} + + +fn ethereum_sync_params(matches: &clap::ArgMatches) -> Result { + let mut eth_sync_params = EthereumSyncParams::default(); + eth_sync_params.eth = ethereum_connection_params(matches)?; + eth_sync_params.sub = substrate_connection_params(matches)?; + eth_sync_params.sub_sign = substrate_signing_params(matches)?; match matches.value_of("sub-tx-mode") { Some("signed") => eth_sync_params.sync_params.target_tx_mode = sync::TargetTransactionMode::Signed, @@ -146,44 +187,28 @@ fn ethereum_sync_params(matches: &clap::ArgMatches) -> Result Result { - let mut sub_sync_params = substrate_sync_loop::SubstrateSyncParams::default(); - if let Some(eth_host) = matches.value_of("eth-host") { - sub_sync_params.eth_host = eth_host.into(); - } - if let Some(eth_port) = matches.value_of("eth-port") { - sub_sync_params.eth_port = eth_port.parse().map_err(|e| format!("{}", e))?; - } +fn substrate_sync_params(matches: &clap::ArgMatches) -> Result { + let mut sub_sync_params = SubstrateSyncParams::default(); + sub_sync_params.eth = ethereum_connection_params(matches)?; + sub_sync_params.eth_sign = ethereum_signing_params(matches)?; + sub_sync_params.sub = substrate_connection_params(matches)?; + if let Some(eth_contract) = matches.value_of("eth-contract") { sub_sync_params.eth_contract_address = eth_contract.parse().map_err(|e| format!("{}", e))?; } - if let Some(eth_signer) = matches.value_of("eth-signer") { - sub_sync_params.eth_signer = KeyPair::from_secret( - eth_signer.parse().map_err(|e| format!("{}", e))? - ).map_err(|e| format!("{}", e))?; - } - if let Some(sub_host) = matches.value_of("sub-host") { - sub_sync_params.sub_host = sub_host.into(); - } - if let Some(sub_port) = matches.value_of("sub-port") { - sub_sync_params.sub_port = sub_port.parse().map_err(|e| format!("{}", e))?; - } Ok(sub_sync_params) } fn ethereum_deploy_contract_params(matches: &clap::ArgMatches) -> Result { let mut eth_deploy_params = ethereum_deploy_contract::EthereumDeployContractParams::default(); - if let Some(eth_host) = matches.value_of("eth-host") { - eth_deploy_params.eth_host = eth_host.into(); - } - if let Some(eth_port) = matches.value_of("eth-port") { - eth_deploy_params.eth_port = eth_port.parse().map_err(|e| format!("{}", e))?; - } - if let Some(eth_signer) = matches.value_of("eth-signer") { - eth_deploy_params.eth_signer = KeyPair::from_secret( - eth_signer.parse().map_err(|e| format!("{}", e))? - ).map_err(|e| format!("{}", e))?; + eth_deploy_params.eth = ethereum_connection_params(matches)?; + eth_deploy_params.eth_sign = ethereum_signing_params(matches)?; + eth_deploy_params.sub = substrate_connection_params(matches)?; + + if let Some(eth_contract_code) = matches.value_of("eth-contract-code") { + eth_deploy_params.eth_contract_code = hex::decode(ð_contract_code) + .map_err(|e| format!("Failed to parse eth-contract-code: {}", e))?; } Ok(eth_deploy_params) diff --git a/relays/ethereum/src/substrate_client.rs b/relays/ethereum/src/substrate_client.rs index 0ef3dbc777..38336c1aa9 100644 --- a/relays/ethereum/src/substrate_client.rs +++ b/relays/ethereum/src/substrate_client.rs @@ -30,6 +30,45 @@ use serde_json::{from_value, to_value}; use sp_core::crypto::Pair; use sp_runtime::traits::IdentifyAccount; +/// Substrate connection params. +#[derive(Debug)] +pub struct SubstrateConnectionParams { + /// Substrate RPC host. + pub host: String, + /// Substrate RPC port. + pub port: u16, +} + +impl Default for SubstrateConnectionParams { + fn default() -> Self { + SubstrateConnectionParams { + host: "localhost".into(), + port: 9933, + } + } +} + +/// Substrate signing params. +#[derive(Clone)] +pub struct SubstrateSigningParams { + /// Substrate transactions signer. + pub signer: sp_core::sr25519::Pair, +} + +impl std::fmt::Debug for SubstrateSigningParams { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.signer.public()) + } +} + +impl Default for SubstrateSigningParams { + fn default() -> Self { + SubstrateSigningParams { + signer: sp_keyring::AccountKeyring::Alice.pair(), + } + } +} + /// Substrate client type. pub struct Client { /// Substrate RPC client. @@ -61,8 +100,9 @@ impl MaybeConnectionError for Error { } /// Returns client that is able to call RPCs on Substrate node. -pub fn client(uri: &str) -> Client { - let transport = HttpTransportClient::new(uri); +pub fn client(params: SubstrateConnectionParams) -> Client { + let uri = format!("http://{}:{}", params.host, params.port); + let transport = HttpTransportClient::new(&uri); Client { rpc_client: RawClient::new(transport), genesis_hash: None, @@ -170,12 +210,12 @@ pub async fn ethereum_header_known( /// Submits Ethereum header to Substrate runtime. pub async fn submit_ethereum_headers( client: Client, - signer: sp_core::sr25519::Pair, + params: SubstrateSigningParams, headers: Vec, sign_transactions: bool, ) -> (Client, Result<(Vec, Vec), Error>) { match sign_transactions { - true => submit_signed_ethereum_headers(client, signer, headers).await, + true => submit_signed_ethereum_headers(client, params, headers).await, false => submit_unsigned_ethereum_headers(client, headers).await, } } @@ -183,7 +223,7 @@ pub async fn submit_ethereum_headers( /// Submits signed Ethereum header to Substrate runtime. pub async fn submit_signed_ethereum_headers( client: Client, - signer: sp_core::sr25519::Pair, + params: SubstrateSigningParams, headers: Vec, ) -> (Client, Result<(Vec, Vec), Error>) { let ids = headers.iter().map(|header| header.id()).collect(); @@ -199,14 +239,14 @@ pub async fn submit_signed_ethereum_headers( (client, genesis_hash) } }; - let account_id = signer.public().as_array_ref().clone().into(); + let account_id = params.signer.public().as_array_ref().clone().into(); let (client, nonce) = next_account_index(client, account_id).await; let nonce = match nonce { Ok(nonce) => nonce, Err(err) => return (client, Err(err)), }; - let transaction = create_signed_submit_transaction(headers, &signer, nonce, genesis_hash); + let transaction = create_signed_submit_transaction(headers, ¶ms.signer, nonce, genesis_hash); let encoded_transaction = transaction.encode(); let (client, transaction_hash) = call_rpc( client, diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index d27b1967ed..6c6d8bacdc 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -14,9 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::ethereum_client; -use crate::ethereum_types::{Address, U256}; -use crate::substrate_client; +use crate::ethereum_client::{EthereumConnectionParams, EthereumSigningParams, self}; +use crate::ethereum_types::Address; +use crate::substrate_client::{SubstrateConnectionParams, self}; use crate::substrate_types::{ Header, Hash, Number, Justification, QueuedSubstrateHeader, SubstrateHeaderId, SubstrateHeadersSyncPipeline, @@ -25,7 +25,6 @@ use crate::sync::{HeadersSyncParams, TargetTransactionMode}; use crate::sync_loop::{SourceClient, TargetClient}; use crate::sync_types::SourceHeader; use futures::future::{FutureExt, Ready, ready}; -use parity_crypto::publickey::KeyPair; use std::{future::Future, pin::Pin}; /// Interval (in ms) at which we check new Substrate headers when we are synced/almost synced. @@ -36,22 +35,14 @@ const ETHEREUM_TICK_INTERVAL_MS: u64 = 5_000; /// Substrate synchronization parameters. #[derive(Debug)] pub struct SubstrateSyncParams { - /// Ethereum RPC host. - pub eth_host: String, - /// Ethereum RPC port. - pub eth_port: u16, - /// Ethereum chain id. - pub eth_chain_id: u64, + /// Ethereum connection params. + pub eth: EthereumConnectionParams, + /// Ethereum signing params. + pub eth_sign: EthereumSigningParams, /// Ethereum bridge contract address. pub eth_contract_address: Address, - /// Ethereum transactions signer. - pub eth_signer: KeyPair, - /// Gas price we agree to pay. - pub eth_gas_price: U256, - /// Substrate RPC host. - pub sub_host: String, - /// Substrate RPC port. - pub sub_port: u16, + /// Substrate connection params. + pub sub: SubstrateConnectionParams, /// Synchronization parameters. pub sync_params: HeadersSyncParams, } @@ -59,24 +50,13 @@ pub struct SubstrateSyncParams { impl Default for SubstrateSyncParams { fn default() -> Self { SubstrateSyncParams { - eth_host: "localhost".into(), - eth_port: 8545, - eth_chain_id: 0x11, // Parity dev chain + eth: Default::default(), + eth_sign: Default::default(), // the address 0x731a10897d267e19b34503ad902d0a29173ba4b1 is the address // of the contract that is deployed by default signer and 0 nonce eth_contract_address: "731a10897d267e19b34503ad902d0a29173ba4b1".parse() .expect("address is hardcoded, thus valid; qed"), - // that the account that has a lot of ether when we run instant seal engine - // address: 0x00a329c0648769a73afac7f9381e08fb43dbea72 - // secret: 0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7 - eth_signer: KeyPair::from_secret_slice( - &[0x4d, 0x5d, 0xb4, 0x10, 0x7d, 0x23, 0x7d, 0xf6, 0xa3, 0xd5, 0x8e, 0xe5, 0xf7, 0x0a, - 0xe6, 0x3d, 0x73, 0xd7, 0x65, 0x8d, 0x40, 0x26, 0xf2, 0xee, 0xfd, 0x2f, 0x20, 0x4c, - 0x81, 0x68, 0x2c, 0xb7] - ).expect("secret is hardcoded, thus valid; qed"), - eth_gas_price: 8_000_000_000u64.into(), // 8 Gwei - sub_host: "localhost".into(), - sub_port: 9933, + sub: Default::default(), sync_params: HeadersSyncParams { max_future_headers_to_download: 128, max_headers_in_submitted_status: 128, @@ -142,14 +122,10 @@ impl SourceClient for SubstrateHeadersSource { struct EthereumHeadersTarget { /// Ethereum node client. client: ethereum_client::Client, - /// Ethereum transactions signer. - signer: parity_crypto::publickey::KeyPair, - /// Ethereum chain id. - chain_id: u64, /// Bridge contract address. contract: Address, - /// Gas price we are paying for transactions. - gas_price: U256, + /// Ethereum signing params. + sign_params: EthereumSigningParams, } impl TargetClient for EthereumHeadersTarget { @@ -161,17 +137,14 @@ impl TargetClient for EthereumHeadersTarget { type SubmitHeadersFuture = Pin, Self::Error>)>>>; fn best_header_id(self) -> Self::BestHeaderIdFuture { - let (signer, chain_id, contract, gas_price) - = (self.signer, self.chain_id, self.contract, self.gas_price); + let (contract, sign_params) = (self.contract, self.sign_params); ethereum_client::best_substrate_block(self.client, contract) .map(move |(client, result)| { ( EthereumHeadersTarget { client, - signer, - chain_id, contract, - gas_price, + sign_params, }, result, ) @@ -180,17 +153,14 @@ impl TargetClient for EthereumHeadersTarget { } fn is_known_header(self, id: SubstrateHeaderId) -> Self::IsKnownHeaderFuture { - let (signer, chain_id, contract, gas_price) - = (self.signer, self.chain_id, self.contract, self.gas_price); + let (contract, sign_params) = (self.contract, self.sign_params); ethereum_client::substrate_header_known(self.client, contract, id) .map(move |(client, result)| { ( EthereumHeadersTarget { client, - signer, - chain_id, contract, - gas_price, + sign_params, }, result, ) @@ -207,23 +177,18 @@ impl TargetClient for EthereumHeadersTarget { } fn submit_headers(self, headers: Vec) -> Self::SubmitHeadersFuture { - let (signer, chain_id, contract, gas_price) - = (self.signer, self.chain_id, self.contract, self.gas_price); + let (contract, sign_params) = (self.contract, self.sign_params); ethereum_client::submit_substrate_headers( self.client, - signer.clone(), - chain_id, + sign_params.clone(), contract, - gas_price, headers, ).map(move |(client, result)| { ( EthereumHeadersTarget { client, - signer, - chain_id, contract, - gas_price, + sign_params, }, result.map(|(_, submitted_headers)| submitted_headers), ) @@ -234,21 +199,16 @@ impl TargetClient for EthereumHeadersTarget { /// Run Substrate headers synchronization. pub fn run(params: SubstrateSyncParams) { - let eth_uri = format!("http://{}:{}", params.eth_host, params.eth_port); - let eth_client = ethereum_client::client(ð_uri); - - let sub_uri = format!("http://{}:{}", params.sub_host, params.sub_port); - let sub_client = substrate_client::client(&sub_uri); + let eth_client = ethereum_client::client(params.eth); + let sub_client = substrate_client::client(params.sub); crate::sync_loop::run( SubstrateHeadersSource { client: sub_client }, SUBSTRATE_TICK_INTERVAL_MS, EthereumHeadersTarget { client: eth_client, - signer: params.eth_signer, - chain_id: params.eth_chain_id, contract: params.eth_contract_address, - gas_price: params.eth_gas_price, + sign_params: params.eth_sign, }, ETHEREUM_TICK_INTERVAL_MS, params.sync_params, From 81682782b388fda9d93bda78eb0969b8042c6bcb Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 13 Apr 2020 15:19:05 +0300 Subject: [PATCH 20/92] removed multiple call_rpc variants --- relays/ethereum/src/substrate_client.rs | 103 +++++++++++------------- 1 file changed, 47 insertions(+), 56 deletions(-) diff --git a/relays/ethereum/src/substrate_client.rs b/relays/ethereum/src/substrate_client.rs index 38336c1aa9..28af91aa84 100644 --- a/relays/ethereum/src/substrate_client.rs +++ b/relays/ethereum/src/substrate_client.rs @@ -26,7 +26,8 @@ use jsonrpsee::common::Params; use jsonrpsee::raw::{RawClient, RawClientError}; use jsonrpsee::transport::http::{HttpTransportClient, RequestError}; use num_traits::Zero; -use serde_json::{from_value, to_value}; +use serde::de::DeserializeOwned; +use serde_json::{Value, from_value, to_value}; use sp_core::crypto::Pair; use sp_runtime::traits::IdentifyAccount; @@ -111,22 +112,24 @@ pub fn client(params: SubstrateConnectionParams) -> Client { /// Returns best Substrate header. pub async fn best_header(client: Client) -> (Client, Result) { - call_rpc_header( + call_rpc( client, "chain_getHeader", Params::None, + rpc_returns_value, ) .await } /// Returns Substrate header by hash. pub async fn header_by_hash(client: Client, hash: Hash) -> (Client, Result) { - call_rpc_header( + call_rpc( client, "chain_getHeader", Params::Array(vec![ to_value(hash).unwrap(), ]), + rpc_returns_value, ) .await } @@ -148,13 +151,14 @@ pub async fn justification(client: Client, _hash: Hash) -> (Client, Result (Client, Result) { - let (client, result) = call_rpc::<(u64, H256)>( + let (client, result) = call_rpc( client, "state_call", Params::Array(vec![ to_value("EthereumHeadersApi_best_block").unwrap(), to_value("0x").unwrap(), ]), + rpc_returns_encoded_value, ) .await; (client, result.map(|(num, hash)| HeaderId(num, hash))) @@ -175,6 +179,7 @@ pub async fn ethereum_receipts_required( to_value("EthereumHeadersApi_is_import_requires_receipts").unwrap(), to_value(Bytes(encoded_header)).unwrap(), ]), + rpc_returns_encoded_value, ) .await; ( @@ -202,6 +207,7 @@ pub async fn ethereum_header_known( to_value("EthereumHeadersApi_is_known_block").unwrap(), to_value(Bytes(encoded_id)).unwrap(), ]), + rpc_returns_encoded_value, ) .await; (client, is_known_block.map(|is_known_block| (id, is_known_block))) @@ -252,6 +258,7 @@ pub async fn submit_signed_ethereum_headers( client, "author_submitExtrinsic", Params::Array(vec![to_value(Bytes(encoded_transaction)).unwrap()]), + rpc_returns_value, ) .await; @@ -276,6 +283,7 @@ pub async fn submit_unsigned_ethereum_headers( client, "author_submitExtrinsic", Params::Array(vec![to_value(Bytes(encoded_transaction)).unwrap()]), + rpc_returns_value, ) .await; @@ -298,6 +306,7 @@ pub async fn grandpa_authorities_set(client: Client, block: Hash) -> (Client, Re to_value("GrandpaApi_grandpa_authorities").unwrap(), to_value(block).unwrap(), ]), + rpc_returns_bytes, ) .await } @@ -308,6 +317,7 @@ async fn block_hash_by_number(client: Client, number: Number) -> (Client, Result client, "chain_getBlockHash", Params::Array(vec![to_value(number).unwrap()]), + rpc_returns_value, ).await } @@ -318,65 +328,29 @@ async fn next_account_index( ) -> (Client, Result) { use sp_core::crypto::Ss58Codec; - let (client, index) = call_rpc_u64( + let (client, index) = call_rpc( client, "system_accountNextIndex", Params::Array(vec![to_value(account.to_ss58check()).unwrap()]), + |v| rpc_returns_value::(v), ) .await; (client, index.map(|index| index as _)) } /// Calls RPC on Substrate node that returns Bytes. -async fn call_rpc(mut client: Client, method: &'static str, params: Params) -> (Client, Result) { - async fn do_call_rpc(client: &mut Client, method: &'static str, params: Params) -> Result { - let request_id = client - .rpc_client - .start_request(method, params) - .await - .map_err(Error::StartRequestFailed)?; - // WARN: if there'll be need for executing >1 request at a time, we should avoid - // calling request_by_id - let response = client - .rpc_client - .request_by_id(request_id) - .ok_or(Error::RequestNotFound)? - .await - .map_err(Error::ResponseRetrievalFailed)?; - let encoded_response: Bytes = from_value(response).map_err(|_| Error::ResponseParseFailed)?; - Decode::decode(&mut &encoded_response.0[..]).map_err(|_| Error::ResponseParseFailed) - } - - let result = do_call_rpc(&mut client, method, params).await; - (client, result) -} - -/// Calls RPC on Substrate node that returns Header. -async fn call_rpc_header(mut client: Client, method: &'static str, params: Params) -> (Client, Result) { - async fn do_call_rpc(client: &mut Client, method: &'static str, params: Params) -> Result { - let request_id = client - .rpc_client - .start_request(method, params) - .await - .map_err(Error::StartRequestFailed)?; - // WARN: if there'll be need for executing >1 request at a time, we should avoid - // calling request_by_id - let response = client - .rpc_client - .request_by_id(request_id) - .ok_or(Error::RequestNotFound)? - .await - .map_err(Error::ResponseRetrievalFailed)?; - from_value(response).map_err(|_| Error::ResponseParseFailed) - } - - let result = do_call_rpc(&mut client, method, params).await; - (client, result) -} - -/// Calls RPC on Substrate node that returns u64. -async fn call_rpc_u64(mut client: Client, method: &'static str, params: Params) -> (Client, Result) { - async fn do_call_rpc(client: &mut Client, method: &'static str, params: Params) -> Result { +async fn call_rpc( + mut client: Client, + method: &'static str, + params: Params, + decode_value: impl Fn(Value) -> Result, +) -> (Client, Result) { + async fn do_call_rpc( + client: &mut Client, + method: &'static str, + params: Params, + decode_value: impl Fn(Value) -> Result, + ) -> Result { let request_id = client .rpc_client .start_request(method, params) @@ -390,10 +364,10 @@ async fn call_rpc_u64(mut client: Client, method: &'static str, params: Params) .ok_or(Error::RequestNotFound)? .await .map_err(Error::ResponseRetrievalFailed)?; - response.as_u64().ok_or(Error::ResponseParseFailed) + decode_value(response) } - let result = do_call_rpc(&mut client, method, params).await; + let result = do_call_rpc(&mut client, method, params, decode_value).await; (client, result) } @@ -458,3 +432,20 @@ fn create_unsigned_submit_transaction(header: QueuedEthereumHeader) -> bridge_no bridge_node_runtime::UncheckedExtrinsic::new_unsigned(function) } + +/// When RPC method returns encoded value. +fn rpc_returns_encoded_value(value: Value) -> Result { + let encoded_response: Bytes = from_value(value).map_err(|_| Error::ResponseParseFailed)?; + Decode::decode(&mut &encoded_response.0[..]).map_err(|_| Error::ResponseParseFailed) +} + +/// When RPC method returns value. +fn rpc_returns_value(value: Value) -> Result { + from_value(value).map_err(|_| Error::ResponseParseFailed) +} + +/// When RPC method returns raw bytes. +fn rpc_returns_bytes(value: Value) -> Result, Error> { + let encoded_response: Bytes = from_value(value).map_err(|_| Error::ResponseParseFailed)?; + Ok(encoded_response.0) +} \ No newline at end of file From fd02e2ff3d4cc1c165793883e5eaf3de8a4a59eb Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 13 Apr 2020 15:51:07 +0300 Subject: [PATCH 21/92] bail_on_error!() --- relays/ethereum/src/cli.yml | 2 +- relays/ethereum/src/ethereum_client.rs | 127 ++++++++++-------------- relays/ethereum/src/main.rs | 1 + relays/ethereum/src/substrate_client.rs | 40 +++----- relays/ethereum/src/utils.rs | 87 ++-------------- 5 files changed, 78 insertions(+), 179 deletions(-) diff --git a/relays/ethereum/src/cli.yml b/relays/ethereum/src/cli.yml index 07b8ea4ebf..a934c1d171 100644 --- a/relays/ethereum/src/cli.yml +++ b/relays/ethereum/src/cli.yml @@ -121,4 +121,4 @@ subcommands: long: sub-initial-header value_name: SUB_INITIAL_HEADER help: Encoded initial Substrate header. - takes_value: true \ No newline at end of file + takes_value: true diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index 31c3af0f9b..273bf95e8d 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -17,6 +17,7 @@ use crate::ethereum_types::{Address, Bytes, EthereumHeaderId, Header, Receipt, H256, U256, U64}; use crate::substrate_types::{SubstrateHeaderId, Hash as SubstrateHash, QueuedSubstrateHeader}; use crate::sync_types::{HeaderId, MaybeConnectionError}; +use crate::bail_on_error; use codec::{Encode, Decode}; use ethabi::FunctionOutputDecoder; use jsonrpsee::common::Params; @@ -184,11 +185,7 @@ pub async fn transactions_receipts( ) -> (Client, Result<(EthereumHeaderId, Vec), Error>) { let mut transactions_receipts = Vec::with_capacity(transacactions.len()); for transacaction in transacactions { - let (next_client, transaction_receipt) = transaction_receipt(client, transacaction).await; - let transaction_receipt = match transaction_receipt { - Ok(transaction_receipt) => transaction_receipt, - Err(error) => return (next_client, Err(error)), - }; + let (next_client, transaction_receipt) = bail_on_error!(transaction_receipt(client, transacaction).await); transactions_receipts.push(transaction_receipt); client = next_client; } @@ -218,21 +215,19 @@ pub async fn best_substrate_block( contract_address: Address, ) -> (Client, Result) { let (encoded_call, call_decoder) = bridge_contract::functions::best_known_header::call(); - let (client, result) = call_rpc::( - client, - "eth_call", - Params::Array(vec![ - to_value(CallRequest { - to: Some(contract_address), - data: Some(encoded_call.into()), - }).unwrap(), - ]), - ) - .await; - let call_result = match result { - Ok(result) => result, - Err(error) => return (client, Err(error)), - }; + let (client, call_result) = bail_on_error!( + call_rpc::( + client, + "eth_call", + Params::Array(vec![ + to_value(CallRequest { + to: Some(contract_address), + data: Some(encoded_call.into()), + }).unwrap(), + ]), + ) + .await + ); let (number, raw_hash) = match call_decoder.decode(&call_result.0) { Ok((raw_number, raw_hash)) => (raw_number, raw_hash), Err(error) => return (client, Err(Error::ResponseParseFailed(format!("{}", error)))), @@ -261,21 +256,19 @@ pub async fn substrate_header_known( // there's a better header => this Orphan will either be marked as synced, or // eventually pruned. let (encoded_call, call_decoder) = bridge_contract::functions::is_known_header::call(id.1); - let (client, result) = call_rpc::( - client, - "eth_call", - Params::Array(vec![ - to_value(CallRequest { - to: Some(contract_address), - data: Some(encoded_call.into()), - }).unwrap(), - ]), - ) - .await; - let call_result = match result { - Ok(result) => result, - Err(error) => return (client, Err(error)), - }; + let (client, call_result) = bail_on_error!( + call_rpc::( + client, + "eth_call", + Params::Array(vec![ + to_value(CallRequest { + to: Some(contract_address), + data: Some(encoded_call.into()), + }).unwrap(), + ]), + ) + .await + ); match call_decoder.decode(&call_result.0) { Ok(is_known_block) => (client, Ok((id, is_known_block))), Err(error) => (client, Err(Error::ResponseParseFailed(format!("{}", error)))), @@ -289,11 +282,9 @@ pub async fn submit_substrate_headers( contract_address: Address, headers: Vec, ) -> (Client, Result<(Vec, Vec), Error>) { - let (mut client, nonce) = account_nonce(client, params.signer.address().as_fixed_bytes().into()).await; - let mut nonce = match nonce { - Ok(nonce) => nonce, - Err(error) => return (client, Err(error)), - }; + let (mut client, mut nonce) = bail_on_error!( + account_nonce(client, params.signer.address().as_fixed_bytes().into()).await + ); let mut tx_hashes = Vec::with_capacity(headers.len()); let ids = headers.iter().map(|header| header.id()).collect(); @@ -302,14 +293,12 @@ pub async fn submit_substrate_headers( let encoded_call = bridge_contract::functions::import_header::encode_input( raw_header, ); - let (ret_client, gas) = estimate_gas(client, CallRequest { - to: Some(contract_address), - data: Some(encoded_call.clone().into()), - }).await; - let gas = match gas { - Ok(gas) => gas, - Err(error) => return (ret_client, Err(error)), - }; + let (ret_client, gas) = bail_on_error!( + estimate_gas(client, CallRequest { + to: Some(contract_address), + data: Some(encoded_call.clone().into()), + }).await + ); let raw_transaction = ethereum_tx_sign::RawTransaction { nonce, to: Some(contract_address), @@ -318,18 +307,16 @@ pub async fn submit_substrate_headers( gas_price: params.gas_price, data: encoded_call, }.sign(¶ms.signer.secret().as_fixed_bytes().into(), ¶ms.chain_id); - let (ret_client, result) = call_rpc( - ret_client, - "eth_submitTransaction", - Params::Array(vec![ - to_value(Bytes(raw_transaction)).unwrap(), - ]), - ) - .await; - let tx_hash = match result { - Ok(tx_hash) => tx_hash, - Err(error) => return (ret_client, Err(error)), - }; + let (ret_client, tx_hash) = bail_on_error!( + call_rpc( + ret_client, + "eth_submitTransaction", + Params::Array(vec![ + to_value(Bytes(raw_transaction)).unwrap(), + ]), + ) + .await + ); tx_hashes.push(tx_hash); nonce += 1.into(); @@ -354,19 +341,13 @@ pub async fn deploy_bridge_contract( initial_set_id, initial_authorities, ); - let (client, nonce) = account_nonce(client, params.signer.address().as_fixed_bytes().into()).await; - let nonce = match nonce { - Ok(nonce) => nonce, - Err(error) => return (client, Err(error)), - }; - let (client, gas) = estimate_gas(client, CallRequest { - data: Some(encoded_call.clone().into()), - ..Default::default() - }).await; - let gas = match gas { - Ok(gas) => gas, - Err(error) => return (client, Err(error)), - }; + let (client, nonce) = bail_on_error!(account_nonce(client, params.signer.address().as_fixed_bytes().into()).await); + let (client, gas) = bail_on_error!( + estimate_gas(client, CallRequest { + data: Some(encoded_call.clone().into()), + ..Default::default() + }).await + ); let raw_transaction = ethereum_tx_sign::RawTransaction { nonce: nonce, to: None, diff --git a/relays/ethereum/src/main.rs b/relays/ethereum/src/main.rs index 129e2b8de1..fc476583ff 100644 --- a/relays/ethereum/src/main.rs +++ b/relays/ethereum/src/main.rs @@ -27,6 +27,7 @@ mod substrate_types; mod sync; mod sync_loop; mod sync_types; +mod utils; use parity_crypto::publickey::{KeyPair, Secret}; use sp_core::crypto::Pair; diff --git a/relays/ethereum/src/substrate_client.rs b/relays/ethereum/src/substrate_client.rs index 28af91aa84..99547c39b4 100644 --- a/relays/ethereum/src/substrate_client.rs +++ b/relays/ethereum/src/substrate_client.rs @@ -21,6 +21,7 @@ use crate::substrate_types::{ TransactionHash, }; use crate::sync_types::{HeaderId, MaybeConnectionError, SourceHeader}; +use crate::bail_on_error; use codec::{Decode, Encode}; use jsonrpsee::common::Params; use jsonrpsee::raw::{RawClient, RawClientError}; @@ -136,11 +137,7 @@ pub async fn header_by_hash(client: Client, hash: Hash) -> (Client, Result (Client, Result) { - let (client, hash) = block_hash_by_number(client, number).await; - let hash = match hash { - Ok(hash) => hash, - Err(error) => return (client, Err(error)), - }; + let (client, hash) = bail_on_error!(block_hash_by_number(client, number).await); header_by_hash(client, hash).await } @@ -236,21 +233,13 @@ pub async fn submit_signed_ethereum_headers( let (client, genesis_hash) = match client.genesis_hash { Some(genesis_hash) => (client, genesis_hash), None => { - let (mut client, genesis_hash) = block_hash_by_number(client, Zero::zero()).await; - let genesis_hash = match genesis_hash { - Ok(genesis_hash) => genesis_hash, - Err(err) => return (client, Err(err)), - }; + let (mut client, genesis_hash) = bail_on_error!(block_hash_by_number(client, Zero::zero()).await); client.genesis_hash = Some(genesis_hash); (client, genesis_hash) } }; let account_id = params.signer.public().as_array_ref().clone().into(); - let (client, nonce) = next_account_index(client, account_id).await; - let nonce = match nonce { - Ok(nonce) => nonce, - Err(err) => return (client, Err(err)), - }; + let (client, nonce) = bail_on_error!(next_account_index(client, account_id).await); let transaction = create_signed_submit_transaction(headers, ¶ms.signer, nonce, genesis_hash); let encoded_transaction = transaction.encode(); @@ -279,19 +268,18 @@ pub async fn submit_unsigned_ethereum_headers( let transaction = create_unsigned_submit_transaction(header); let encoded_transaction = transaction.encode(); - let (used_client, transaction_hash) = call_rpc( - client, - "author_submitExtrinsic", - Params::Array(vec![to_value(Bytes(encoded_transaction)).unwrap()]), - rpc_returns_value, - ) - .await; + let (used_client, transaction_hash) = bail_on_error!( + call_rpc( + client, + "author_submitExtrinsic", + Params::Array(vec![to_value(Bytes(encoded_transaction)).unwrap()]), + rpc_returns_value, + ) + .await + ); client = used_client; - transactions_hashes.push(match transaction_hash { - Ok(transaction_hash) => transaction_hash, - Err(error) => return (client, Err(error)), - }); + transactions_hashes.push(transaction_hash); } (client, Ok((transactions_hashes, ids))) diff --git a/relays/ethereum/src/utils.rs b/relays/ethereum/src/utils.rs index 6245ce01d9..fba18dfa59 100644 --- a/relays/ethereum/src/utils.rs +++ b/relays/ethereum/src/utils.rs @@ -14,84 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::sync_types::HeadersSyncPipeline; -use futures::future::FutureExt; -use num_traits::Saturating; - -/// Error type that can signal connection errors. -pub trait MaybeConnectionError { - /// Returns true if error (maybe) represents connection error. - fn is_connection_error(&self) -> bool; -} - -/// Future that resolves into given value after given timeout. -pub async fn delay(timeout_ms: u64, retval: T) -> T { - async_std::task::sleep(std::time::Duration::from_millis(timeout_ms)).await; - retval -} - -/// Stream that emits item every `timeout_ms` milliseconds. -pub fn interval(timeout_ms: u64) -> impl futures::Stream { - futures::stream::unfold((), move |_| async move { - delay(timeout_ms, ()).await; - Some(((), ())) - }) -} - -/// Process result of the future that may have been caused by connection failure. -pub fn process_future_result( - maybe_client: &mut Option, - client: TClient, - result: Result, - on_success: impl FnOnce(TResult), - go_offline_future: &mut std::pin::Pin<&mut futures::future::Fuse>, - go_offline: impl FnOnce(TClient) -> TGoOfflineFuture, - error_pattern: impl FnOnce() -> String, -) where - TError: std::fmt::Debug + MaybeConnectionError, - TGoOfflineFuture: FutureExt, -{ - match result { - Ok(result) => { - *maybe_client = Some(client); - on_success(result); +/// Macro that returns (client, Err(error)) tuple from function if result is Err(error). +#[macro_export] +macro_rules! bail_on_error { + ($result: expr) => { + match $result { + (client, Ok(result)) => (client, result), + (client, Err(error)) => return (client, Err(error)), } - Err(error) => { - if error.is_connection_error() { - go_offline_future.set(go_offline(client).fuse()); - } else { - *maybe_client = Some(client); - } - - log::error!(target: "bridge", "{}: {:?}", error_pattern(), error); - } - } -} - -/// Print synchronization progress. -pub fn print_sync_progress( - progress_context: (std::time::Instant, Option, Option), - eth_sync: &crate::sync::HeadersSync

, -) -> (std::time::Instant, Option, Option) { - let (prev_time, prev_best_header, prev_target_header) = progress_context; - let now_time = std::time::Instant::now(); - let (now_best_header, now_target_header) = eth_sync.status(); - - let need_update = now_time - prev_time > std::time::Duration::from_secs(10) - || match (prev_best_header, now_best_header) { - (Some(prev_best_header), Some(now_best_header)) => - now_best_header.0.saturating_sub(prev_best_header) > 10.into(), - _ => false, - }; - if !need_update { - return (prev_time, prev_best_header, prev_target_header); - } - - log::info!( - target: "bridge", - "Synced {:?} of {:?} headers", - now_best_header.map(|id| id.0), - now_target_header, - ); - (now_time, now_best_header.clone().map(|id| id.0), *now_target_header) + }; } From e15bd1f5c127aa6327b568d988d12ccd5906f6c3 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 13 Apr 2020 16:04:27 +0300 Subject: [PATCH 22/92] fn submit_ethereum_transaction --- relays/ethereum/src/ethereum_client.rs | 83 ++++++++++++++------------ 1 file changed, 45 insertions(+), 38 deletions(-) diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index 273bf95e8d..3ecd459b60 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -70,7 +70,7 @@ impl Default for EthereumSigningParams { fn default() -> Self { EthereumSigningParams { chain_id: 0x11, // Parity dev chain - // that the account that has a lot of ether when we run instant seal engine + // account that has a lot of ether when we run instant seal engine // address: 0x00a329c0648769a73afac7f9381e08fb43dbea72 // secret: 0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7 signer: KeyPair::from_secret_slice( @@ -289,37 +289,21 @@ pub async fn submit_substrate_headers( let mut tx_hashes = Vec::with_capacity(headers.len()); let ids = headers.iter().map(|header| header.id()).collect(); for header in headers { - let raw_header = header.extract().0.encode(); - let encoded_call = bridge_contract::functions::import_header::encode_input( - raw_header, - ); - let (ret_client, gas) = bail_on_error!( - estimate_gas(client, CallRequest { - to: Some(contract_address), - data: Some(encoded_call.clone().into()), - }).await - ); - let raw_transaction = ethereum_tx_sign::RawTransaction { - nonce, - to: Some(contract_address), - value: U256::zero(), - gas: gas * 2, - gas_price: params.gas_price, - data: encoded_call, - }.sign(¶ms.signer.secret().as_fixed_bytes().into(), ¶ms.chain_id); let (ret_client, tx_hash) = bail_on_error!( - call_rpc( - ret_client, - "eth_submitTransaction", - Params::Array(vec![ - to_value(Bytes(raw_transaction)).unwrap(), - ]), - ) - .await + submit_ethereum_transaction( + client, + ¶ms, + Some(contract_address), + Some(nonce), + true, // we may need slightly more gas because other actors could change contract state + bridge_contract::functions::import_header::encode_input( + header.extract().0.encode(), + ), + ).await ); - tx_hashes.push(tx_hash); nonce += 1.into(); + tx_hashes.push(tx_hash); client = ret_client; } @@ -335,13 +319,36 @@ pub async fn deploy_bridge_contract( initial_set_id: u64, initial_authorities: Vec, ) -> (Client, Result) { - let encoded_call = bridge_contract::constructor( - contract_code, - initial_header, - initial_set_id, - initial_authorities, - ); - let (client, nonce) = bail_on_error!(account_nonce(client, params.signer.address().as_fixed_bytes().into()).await); + submit_ethereum_transaction( + client, + params, + None, + None, + false, + bridge_contract::constructor( + contract_code, + initial_header, + initial_set_id, + initial_authorities, + ), + ).await +} + +/// Submit ethereum transaction. +async fn submit_ethereum_transaction( + client: Client, + params: &EthereumSigningParams, + contract_address: Option

, + nonce: Option, + double_gas: bool, + encoded_call: Vec, +) -> (Client, Result) { + let (client, nonce) = match nonce { + Some(nonce) => (client, nonce), + None => bail_on_error!( + account_nonce(client, params.signer.address().as_fixed_bytes().into()).await + ), + }; let (client, gas) = bail_on_error!( estimate_gas(client, CallRequest { data: Some(encoded_call.clone().into()), @@ -349,10 +356,10 @@ pub async fn deploy_bridge_contract( }).await ); let raw_transaction = ethereum_tx_sign::RawTransaction { - nonce: nonce, - to: None, + nonce, + to: contract_address, value: U256::zero(), - gas, + gas: if double_gas { gas.saturating_sub(2.into()) } else { gas }, gas_price: params.gas_price, data: encoded_call, }.sign(¶ms.signer.secret().as_fixed_bytes().into(), ¶ms.chain_id); From 4fd2cffb0da106c4b23c2634176b6b0bc79057d2 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 13 Apr 2020 16:11:43 +0300 Subject: [PATCH 23/92] more fixes --- relays/ethereum/src/ethereum_client.rs | 14 +++++++------- relays/ethereum/src/substrate_client.rs | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index 3ecd459b60..32aaf4c862 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -109,6 +109,8 @@ pub enum Error { IncompleteHeader, /// We have received receipt with missing gas_used field. IncompleteReceipt, + /// Invalid Substrate block number received from Ethereum node. + InvalidSubstrateBlockNumber, } impl MaybeConnectionError for Error { @@ -237,9 +239,13 @@ pub async fn best_substrate_block( Err(error) => return (client, Err(Error::ResponseParseFailed(format!("{}", error)))), }; + if number != number.low_u32().into() { + return Err(Error::InvalidSubstrateBlockNumber); + } + ( client, - Ok(HeaderId(number.low_u32(), hash)), // TODO: verify that low_u32().into() == self + Ok(HeaderId(number.low_u32(), hash)), ) } @@ -249,12 +255,6 @@ pub async fn substrate_header_known( contract_address: Address, id: SubstrateHeaderId, ) -> (Client, Result<(SubstrateHeaderId, bool), Error>) { - // Ethereum contract could prune old headers. So this fn could return false even - // if header is synced. And we'll mark corresponding Ethereum header as Orphan. - // - // But when we'll read best header from Ethereum next time, we will know that - // there's a better header => this Orphan will either be marked as synced, or - // eventually pruned. let (encoded_call, call_decoder) = bridge_contract::functions::is_known_header::call(id.1); let (client, call_result) = bail_on_error!( call_rpc::( diff --git a/relays/ethereum/src/substrate_client.rs b/relays/ethereum/src/substrate_client.rs index 99547c39b4..661ad4d405 100644 --- a/relays/ethereum/src/substrate_client.rs +++ b/relays/ethereum/src/substrate_client.rs @@ -436,4 +436,4 @@ fn rpc_returns_value(value: Value) -> Result { fn rpc_returns_bytes(value: Value) -> Result, Error> { let encoded_response: Bytes = from_value(value).map_err(|_| Error::ResponseParseFailed)?; Ok(encoded_response.0) -} \ No newline at end of file +} From ea6cc8cc5afa6412cc2b3bfc8eb0ee3bac6c587e Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 13 Apr 2020 16:13:37 +0300 Subject: [PATCH 24/92] cargo fmt --all --- modules/ethereum-contract/builtin/src/lib.rs | 6 +- relays/ethereum/src/ethereum_client.rs | 111 ++++++------ .../ethereum/src/ethereum_deploy_contract.rs | 29 ++- relays/ethereum/src/ethereum_sync_loop.rs | 9 +- relays/ethereum/src/ethereum_types.rs | 2 +- relays/ethereum/src/headers.rs | 168 +++++++----------- relays/ethereum/src/main.rs | 30 ++-- relays/ethereum/src/substrate_client.rs | 24 +-- relays/ethereum/src/substrate_sync_loop.rs | 61 +++---- relays/ethereum/src/substrate_types.rs | 2 +- relays/ethereum/src/sync.rs | 2 +- relays/ethereum/src/sync_loop.rs | 7 +- relays/ethereum/src/utils.rs | 2 +- 13 files changed, 195 insertions(+), 258 deletions(-) diff --git a/modules/ethereum-contract/builtin/src/lib.rs b/modules/ethereum-contract/builtin/src/lib.rs index e59f604b01..fc86d5d7ef 100644 --- a/modules/ethereum-contract/builtin/src/lib.rs +++ b/modules/ethereum-contract/builtin/src/lib.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use codec::{Encode, Decode}; use bridge_node_runtime::{BlockNumber, Hash, Header as RuntimeHeader}; +use codec::{Decode, Encode}; use sp_blockchain::Error as ClientError; /// Builtin errors. @@ -82,5 +82,7 @@ pub fn verify_substrate_finality_proof( _raw_headers: &[&[u8]], _raw_finality_proof: &[u8], ) -> Result<(usize, usize), Error> { - Err(Error::JustificationVerify(ClientError::Msg("Not yet implemented".into()))) // TODO: implement me + Err(Error::JustificationVerify(ClientError::Msg( + "Not yet implemented".into(), + ))) // TODO: implement me } diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index 32aaf4c862..f3295be036 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -14,17 +14,17 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +use crate::bail_on_error; use crate::ethereum_types::{Address, Bytes, EthereumHeaderId, Header, Receipt, H256, U256, U64}; -use crate::substrate_types::{SubstrateHeaderId, Hash as SubstrateHash, QueuedSubstrateHeader}; +use crate::substrate_types::{Hash as SubstrateHash, QueuedSubstrateHeader, SubstrateHeaderId}; use crate::sync_types::{HeaderId, MaybeConnectionError}; -use crate::bail_on_error; -use codec::{Encode, Decode}; +use codec::{Decode, Encode}; use ethabi::FunctionOutputDecoder; use jsonrpsee::common::Params; use jsonrpsee::raw::{RawClient, RawClientError}; use jsonrpsee::transport::http::{HttpTransportClient, RequestError}; use parity_crypto::publickey::KeyPair; -use serde::{Serialize, de::DeserializeOwned}; +use serde::{de::DeserializeOwned, Serialize}; use serde_json::{from_value, to_value}; // to encode/decode contract calls @@ -76,7 +76,8 @@ impl Default for EthereumSigningParams { signer: KeyPair::from_secret_slice( &hex::decode("4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7") .expect("secret is hardcoded, thus valid; qed"), - ).expect("secret is hardcoded, thus valid; qed"), + ) + .expect("secret is hardcoded, thus valid; qed"), gas_price: 8_000_000_000u64.into(), // 8 Gwei } } @@ -221,12 +222,11 @@ pub async fn best_substrate_block( call_rpc::( client, "eth_call", - Params::Array(vec![ - to_value(CallRequest { - to: Some(contract_address), - data: Some(encoded_call.into()), - }).unwrap(), - ]), + Params::Array(vec![to_value(CallRequest { + to: Some(contract_address), + data: Some(encoded_call.into()), + }) + .unwrap(),]), ) .await ); @@ -243,10 +243,7 @@ pub async fn best_substrate_block( return Err(Error::InvalidSubstrateBlockNumber); } - ( - client, - Ok(HeaderId(number.low_u32(), hash)), - ) + (client, Ok(HeaderId(number.low_u32(), hash))) } /// Returns true if Substrate header is known to Ethereum node. @@ -260,12 +257,11 @@ pub async fn substrate_header_known( call_rpc::( client, "eth_call", - Params::Array(vec![ - to_value(CallRequest { - to: Some(contract_address), - data: Some(encoded_call.into()), - }).unwrap(), - ]), + Params::Array(vec![to_value(CallRequest { + to: Some(contract_address), + data: Some(encoded_call.into()), + }) + .unwrap(),]), ) .await ); @@ -282,9 +278,8 @@ pub async fn submit_substrate_headers( contract_address: Address, headers: Vec, ) -> (Client, Result<(Vec, Vec), Error>) { - let (mut client, mut nonce) = bail_on_error!( - account_nonce(client, params.signer.address().as_fixed_bytes().into()).await - ); + let (mut client, mut nonce) = + bail_on_error!(account_nonce(client, params.signer.address().as_fixed_bytes().into()).await); let mut tx_hashes = Vec::with_capacity(headers.len()); let ids = headers.iter().map(|header| header.id()).collect(); @@ -296,10 +291,9 @@ pub async fn submit_substrate_headers( Some(contract_address), Some(nonce), true, // we may need slightly more gas because other actors could change contract state - bridge_contract::functions::import_header::encode_input( - header.extract().0.encode(), - ), - ).await + bridge_contract::functions::import_header::encode_input(header.extract().0.encode(),), + ) + .await ); nonce += 1.into(); @@ -325,13 +319,9 @@ pub async fn deploy_bridge_contract( None, None, false, - bridge_contract::constructor( - contract_code, - initial_header, - initial_set_id, - initial_authorities, - ), - ).await + bridge_contract::constructor(contract_code, initial_header, initial_set_id, initial_authorities), + ) + .await } /// Submit ethereum transaction. @@ -345,15 +335,17 @@ async fn submit_ethereum_transaction( ) -> (Client, Result) { let (client, nonce) = match nonce { Some(nonce) => (client, nonce), - None => bail_on_error!( - account_nonce(client, params.signer.address().as_fixed_bytes().into()).await - ), + None => bail_on_error!(account_nonce(client, params.signer.address().as_fixed_bytes().into()).await), }; let (client, gas) = bail_on_error!( - estimate_gas(client, CallRequest { - data: Some(encoded_call.clone().into()), - ..Default::default() - }).await + estimate_gas( + client, + CallRequest { + data: Some(encoded_call.clone().into()), + ..Default::default() + } + ) + .await ); let raw_transaction = ethereum_tx_sign::RawTransaction { nonce, @@ -362,35 +354,34 @@ async fn submit_ethereum_transaction( gas: if double_gas { gas.saturating_sub(2.into()) } else { gas }, gas_price: params.gas_price, data: encoded_call, - }.sign(¶ms.signer.secret().as_fixed_bytes().into(), ¶ms.chain_id); + } + .sign(¶ms.signer.secret().as_fixed_bytes().into(), ¶ms.chain_id); call_rpc( client, "eth_submitTransaction", - Params::Array(vec![ - to_value(Bytes(raw_transaction)).unwrap(), - ]), + Params::Array(vec![to_value(Bytes(raw_transaction)).unwrap()]), ) .await } /// Get account nonce. -async fn account_nonce( - client: Client, - caller_address: Address, -) -> (Client, Result) { - call_rpc(client, "eth_getTransactionCount", Params::Array(vec![ - to_value(caller_address).unwrap(), - ])).await +async fn account_nonce(client: Client, caller_address: Address) -> (Client, Result) { + call_rpc( + client, + "eth_getTransactionCount", + Params::Array(vec![to_value(caller_address).unwrap()]), + ) + .await } /// Estimate gas usage for call. -async fn estimate_gas( - client: Client, - call_request: CallRequest, -) -> (Client, Result) { - call_rpc(client, "eth_estimateGas", Params::Array(vec![ - to_value(call_request).unwrap(), - ])).await +async fn estimate_gas(client: Client, call_request: CallRequest) -> (Client, Result) { + call_rpc( + client, + "eth_estimateGas", + Params::Array(vec![to_value(call_request).unwrap()]), + ) + .await } /// Calls RPC on Ethereum node. diff --git a/relays/ethereum/src/ethereum_deploy_contract.rs b/relays/ethereum/src/ethereum_deploy_contract.rs index 86d30a1110..935b7c335a 100644 --- a/relays/ethereum/src/ethereum_deploy_contract.rs +++ b/relays/ethereum/src/ethereum_deploy_contract.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::ethereum_client::{EthereumConnectionParams, EthereumSigningParams, self}; -use crate::substrate_client::{SubstrateConnectionParams, self}; +use crate::ethereum_client::{self, EthereumConnectionParams, EthereumSigningParams}; +use crate::substrate_client::{self, SubstrateConnectionParams}; use crate::substrate_types::{Hash as SubstrateHash, Header as SubstrateHeader}; use codec::{Decode, Encode}; use num_traits::Zero; @@ -102,24 +102,19 @@ async fn prepare_initial_header( sub_initial_header: Option>, ) -> (substrate_client::Client, Result<(SubstrateHash, Vec), String>) { match sub_initial_header { - Some(raw_initial_header) => { - match SubstrateHeader::decode(&mut &raw_initial_header[..]) { - Ok(initial_header) => (sub_client, Ok((initial_header.hash(), raw_initial_header))), - Err(error) => (sub_client, Err(format!("Error decoding initial header: {}", error))), - } + Some(raw_initial_header) => match SubstrateHeader::decode(&mut &raw_initial_header[..]) { + Ok(initial_header) => (sub_client, Ok((initial_header.hash(), raw_initial_header))), + Err(error) => (sub_client, Err(format!("Error decoding initial header: {}", error))), }, None => { - let (sub_client, initial_header) = substrate_client::header_by_number( - sub_client, - Zero::zero(), - ).await; + let (sub_client, initial_header) = substrate_client::header_by_number(sub_client, Zero::zero()).await; ( sub_client, initial_header .map(|header| (header.hash(), header.encode())) - .map_err(|error| format!("Error reading Substrate genesis header: {:?}", error)) + .map_err(|error| format!("Error reading Substrate genesis header: {:?}", error)), ) - }, + } } } @@ -131,15 +126,11 @@ async fn prepare_initial_authorities_set( ) -> (substrate_client::Client, Result, String>) { let (sub_client, initial_authorities_set) = match sub_initial_authorities_set { Some(initial_authorities_set) => (sub_client, Ok(initial_authorities_set)), - None => substrate_client::grandpa_authorities_set( - sub_client, - sub_initial_header_hash, - ).await, + None => substrate_client::grandpa_authorities_set(sub_client, sub_initial_header_hash).await, }; ( sub_client, - initial_authorities_set - .map_err(|error| format!("Error reading GRANDPA authorities set: {:?}", error)), + initial_authorities_set.map_err(|error| format!("Error reading GRANDPA authorities set: {:?}", error)), ) } diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index 93f27af113..414c1c21f6 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -14,12 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::ethereum_client::{EthereumConnectionParams, self}; +use crate::ethereum_client::{self, EthereumConnectionParams}; use crate::ethereum_types::{EthereumHeaderId, EthereumHeadersSyncPipeline, Header, QueuedEthereumHeader, Receipt}; -use crate::substrate_client::{SubstrateConnectionParams, SubstrateSigningParams, self}; +use crate::substrate_client::{self, SubstrateConnectionParams, SubstrateSigningParams}; use crate::sync::{HeadersSyncParams, TargetTransactionMode}; use crate::sync_loop::{SourceClient, TargetClient}; -use futures::future::{FutureExt, Ready, ready}; +use futures::future::{ready, FutureExt, Ready}; use std::{future::Future, pin::Pin}; use web3::types::H256; @@ -70,7 +70,8 @@ impl SourceClient for EthereumHeadersSource { type HeaderByHashFuture = Pin)>>>; type HeaderByNumberFuture = Pin)>>>; type HeaderAsyncExtraFuture = Ready<(Self, Result<(EthereumHeaderId, Option<()>), Self::Error>)>; - type HeaderExtraFuture = Pin), Self::Error>)>>>; + type HeaderExtraFuture = + Pin), Self::Error>)>>>; fn best_block_number(self) -> Self::BestBlockNumberFuture { ethereum_client::best_block_number(self.client) diff --git a/relays/ethereum/src/ethereum_types.rs b/relays/ethereum/src/ethereum_types.rs index eccbbd601e..12ae6354dd 100644 --- a/relays/ethereum/src/ethereum_types.rs +++ b/relays/ethereum/src/ethereum_types.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::sync_types::{HeaderId, HeadersSyncPipeline, SourceHeader, QueuedHeader}; use crate::substrate_types::{into_substrate_ethereum_header, into_substrate_ethereum_receipts}; +use crate::sync_types::{HeaderId, HeadersSyncPipeline, QueuedHeader, SourceHeader}; use codec::Encode; pub use web3::types::{Address, Bytes, H256, U128, U256, U64}; diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index 27fc85008a..0e34b9a98f 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -20,20 +20,10 @@ use std::collections::{ btree_map::Entry as BTreeMapEntry, hash_map::Entry as HashMapEntry, BTreeMap, HashMap, HashSet, }; -type HeadersQueue

= BTreeMap< -

::Number, - HashMap< -

::Hash, - QueuedHeader

, - >, ->; -type KnownHeaders

= BTreeMap< -

::Number, - HashMap< -

::Hash, - HeaderStatus, - >, ->; +type HeadersQueue

= + BTreeMap<

::Number, HashMap<

::Hash, QueuedHeader

>>; +type KnownHeaders

= + BTreeMap<

::Number, HashMap<

::Hash, HeaderStatus>>; /// Ethereum headers queue. #[derive(Debug)] @@ -271,7 +261,8 @@ impl QueuedHeaders

{ } // remember that the header is synced - if !id_processed { // to avoid duplicate log message + if !id_processed { + // to avoid duplicate log message log::debug!( target: "bridge", "{} header {:?} is now {:?}", @@ -538,18 +529,12 @@ fn oldest_headers( } /// Forget all headers with number less than given. -fn prune_queue( - queue: &mut HeadersQueue

, - prune_border: P::Number, -) { +fn prune_queue(queue: &mut HeadersQueue

, prune_border: P::Number) { *queue = queue.split_off(&prune_border); } /// Forget all known headers with number less than given. -fn prune_known_headers( - known_headers: &mut KnownHeaders

, - prune_border: P::Number, -) { +fn prune_known_headers(known_headers: &mut KnownHeaders

, prune_border: P::Number) { let new_known_headers = known_headers.split_off(&prune_border); for (pruned_number, pruned_headers) in &*known_headers { for pruned_hash in pruned_headers.keys() { @@ -562,7 +547,7 @@ fn prune_known_headers( #[cfg(test)] pub(crate) mod tests { use super::*; - use crate::ethereum_types::{EthereumHeaderId, EthereumHeadersSyncPipeline, H256, Header}; + use crate::ethereum_types::{EthereumHeaderId, EthereumHeadersSyncPipeline, Header, H256}; use crate::sync_types::{HeaderId, QueuedHeader}; pub(crate) fn header(number: u64) -> QueuedHeader { @@ -586,36 +571,30 @@ pub(crate) mod tests { fn total_headers_works() { // total headers just sums up number of headers in every queue let mut queue = QueuedHeaders::::new(); - queue - .maybe_orphan - .entry(1) - .or_default() - .insert(hash(1), QueuedHeader::::new(Default::default())); - queue - .maybe_orphan - .entry(1) - .or_default() - .insert(hash(2), QueuedHeader::::new(Default::default())); - queue - .maybe_orphan - .entry(2) - .or_default() - .insert(hash(3), QueuedHeader::::new(Default::default())); - queue - .orphan - .entry(3) - .or_default() - .insert(hash(4), QueuedHeader::::new(Default::default())); - queue - .maybe_extra - .entry(4) - .or_default() - .insert(hash(5), QueuedHeader::::new(Default::default())); - queue - .ready - .entry(5) - .or_default() - .insert(hash(6), QueuedHeader::::new(Default::default())); + queue.maybe_orphan.entry(1).or_default().insert( + hash(1), + QueuedHeader::::new(Default::default()), + ); + queue.maybe_orphan.entry(1).or_default().insert( + hash(2), + QueuedHeader::::new(Default::default()), + ); + queue.maybe_orphan.entry(2).or_default().insert( + hash(3), + QueuedHeader::::new(Default::default()), + ); + queue.orphan.entry(3).or_default().insert( + hash(4), + QueuedHeader::::new(Default::default()), + ); + queue.maybe_extra.entry(4).or_default().insert( + hash(5), + QueuedHeader::::new(Default::default()), + ); + queue.ready.entry(5).or_default().insert( + hash(6), + QueuedHeader::::new(Default::default()), + ); assert_eq!(queue.total_headers(), 6); } @@ -623,49 +602,42 @@ pub(crate) mod tests { fn best_queued_number_works() { // initially there are headers in MaybeOrphan queue only let mut queue = QueuedHeaders::::new(); - queue - .maybe_orphan - .entry(1) - .or_default() - .insert(hash(1), QueuedHeader::::new(Default::default())); - queue - .maybe_orphan - .entry(1) - .or_default() - .insert(hash(2), QueuedHeader::::new(Default::default())); - queue - .maybe_orphan - .entry(3) - .or_default() - .insert(hash(3), QueuedHeader::::new(Default::default())); + queue.maybe_orphan.entry(1).or_default().insert( + hash(1), + QueuedHeader::::new(Default::default()), + ); + queue.maybe_orphan.entry(1).or_default().insert( + hash(2), + QueuedHeader::::new(Default::default()), + ); + queue.maybe_orphan.entry(3).or_default().insert( + hash(3), + QueuedHeader::::new(Default::default()), + ); assert_eq!(queue.best_queued_number(), 3); // and then there's better header in Orphan - queue - .orphan - .entry(10) - .or_default() - .insert(hash(10), QueuedHeader::::new(Default::default())); + queue.orphan.entry(10).or_default().insert( + hash(10), + QueuedHeader::::new(Default::default()), + ); assert_eq!(queue.best_queued_number(), 10); // and then there's better header in MaybeExtra - queue - .maybe_extra - .entry(20) - .or_default() - .insert(hash(20), QueuedHeader::::new(Default::default())); + queue.maybe_extra.entry(20).or_default().insert( + hash(20), + QueuedHeader::::new(Default::default()), + ); assert_eq!(queue.best_queued_number(), 20); // and then there's better header in Ready - queue - .ready - .entry(30) - .or_default() - .insert(hash(30), QueuedHeader::::new(Default::default())); + queue.ready.entry(30).or_default().insert( + hash(30), + QueuedHeader::::new(Default::default()), + ); assert_eq!(queue.best_queued_number(), 30); // and then there's better header in MaybeOrphan again - queue - .maybe_orphan - .entry(40) - .or_default() - .insert(hash(40), QueuedHeader::::new(Default::default())); + queue.maybe_orphan.entry(40).or_default().insert( + hash(40), + QueuedHeader::::new(Default::default()), + ); assert_eq!(queue.best_queued_number(), 40); } @@ -965,11 +937,7 @@ pub(crate) mod tests { .entry(100) .or_default() .insert(hash(100), HeaderStatus::MaybeExtra); - queue - .maybe_extra - .entry(100) - .or_default() - .insert(hash(100), header(100)); + queue.maybe_extra.entry(100).or_default().insert(hash(100), header(100)); queue.maybe_extra_response(&id(100), true); assert!(queue.maybe_extra.is_empty()); assert_eq!(queue.extra.len(), 1); @@ -984,11 +952,7 @@ pub(crate) mod tests { .entry(100) .or_default() .insert(hash(100), HeaderStatus::MaybeExtra); - queue - .maybe_extra - .entry(100) - .or_default() - .insert(hash(100), header(100)); + queue.maybe_extra.entry(100).or_default().insert(hash(100), header(100)); queue.maybe_extra_response(&id(100), false); assert!(queue.maybe_extra.is_empty()); assert_eq!(queue.ready.len(), 1); @@ -1048,11 +1012,7 @@ pub(crate) mod tests { .entry(102) .or_default() .insert(hash(102), HeaderStatus::MaybeExtra); - queue - .maybe_extra - .entry(102) - .or_default() - .insert(hash(102), header(102)); + queue.maybe_extra.entry(102).or_default().insert(hash(102), header(102)); queue .known_headers .entry(101) diff --git a/relays/ethereum/src/main.rs b/relays/ethereum/src/main.rs index fc476583ff..ae46468f8f 100644 --- a/relays/ethereum/src/main.rs +++ b/relays/ethereum/src/main.rs @@ -29,11 +29,11 @@ mod sync_loop; mod sync_types; mod utils; +use ethereum_client::{EthereumConnectionParams, EthereumSigningParams}; +use ethereum_sync_loop::EthereumSyncParams; use parity_crypto::publickey::{KeyPair, Secret}; use sp_core::crypto::Pair; use std::io::Write; -use ethereum_client::{EthereumConnectionParams, EthereumSigningParams}; -use ethereum_sync_loop::EthereumSyncParams; use substrate_client::{SubstrateConnectionParams, SubstrateSigningParams}; use substrate_sync_loop::SubstrateSyncParams; @@ -51,7 +51,7 @@ fn main() { return; } }); - }, + } ("sub-to-eth", Some(sub_to_eth_matches)) => { substrate_sync_loop::run(match substrate_sync_params(&sub_to_eth_matches) { Ok(substrate_sync_params) => substrate_sync_params, @@ -60,7 +60,7 @@ fn main() { return; } }); - }, + } ("eth-deploy-contract", Some(eth_deploy_matches)) => { ethereum_deploy_contract::run(match ethereum_deploy_contract_params(ð_deploy_matches) { Ok(ethereum_deploy_matches) => ethereum_deploy_matches, @@ -69,11 +69,11 @@ fn main() { return; } }); - }, + } ("", _) => { log::error!(target: "bridge", "No subcommand specified"); return; - }, + } _ => unreachable!("all possible subcommands are checked above; qed"), } } @@ -134,9 +134,7 @@ fn ethereum_signing_params(matches: &clap::ArgMatches) -> Result() .map_err(|e| format!("Failed to parse eth-signer: {}", e)) - .and_then(|secret| KeyPair::from_secret(secret) - .map_err(|e| format!("Invalid eth-signer: {}", e)) - )?; + .and_then(|secret| KeyPair::from_secret(secret).map_err(|e| format!("Invalid eth-signer: {}", e)))?; } Ok(params) } @@ -158,14 +156,12 @@ fn substrate_signing_params(matches: &clap::ArgMatches) -> Result Result { let mut eth_sync_params = EthereumSyncParams::default(); eth_sync_params.eth = ethereum_connection_params(matches)?; @@ -201,15 +197,17 @@ fn substrate_sync_params(matches: &clap::ArgMatches) -> Result Result { +fn ethereum_deploy_contract_params( + matches: &clap::ArgMatches, +) -> Result { let mut eth_deploy_params = ethereum_deploy_contract::EthereumDeployContractParams::default(); eth_deploy_params.eth = ethereum_connection_params(matches)?; eth_deploy_params.eth_sign = ethereum_signing_params(matches)?; eth_deploy_params.sub = substrate_connection_params(matches)?; if let Some(eth_contract_code) = matches.value_of("eth-contract-code") { - eth_deploy_params.eth_contract_code = hex::decode(ð_contract_code) - .map_err(|e| format!("Failed to parse eth-contract-code: {}", e))?; + eth_deploy_params.eth_contract_code = + hex::decode(ð_contract_code).map_err(|e| format!("Failed to parse eth-contract-code: {}", e))?; } Ok(eth_deploy_params) diff --git a/relays/ethereum/src/substrate_client.rs b/relays/ethereum/src/substrate_client.rs index 661ad4d405..13a55c8a89 100644 --- a/relays/ethereum/src/substrate_client.rs +++ b/relays/ethereum/src/substrate_client.rs @@ -14,21 +14,20 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +use crate::bail_on_error; use crate::ethereum_types::{Bytes, EthereumHeaderId, QueuedEthereumHeader, H256}; use crate::substrate_types::{ - into_substrate_ethereum_header, into_substrate_ethereum_receipts, - Hash, Header as SubstrateHeader, Justification, Number, - TransactionHash, + into_substrate_ethereum_header, into_substrate_ethereum_receipts, Hash, Header as SubstrateHeader, Justification, + Number, TransactionHash, }; use crate::sync_types::{HeaderId, MaybeConnectionError, SourceHeader}; -use crate::bail_on_error; use codec::{Decode, Encode}; use jsonrpsee::common::Params; use jsonrpsee::raw::{RawClient, RawClientError}; use jsonrpsee::transport::http::{HttpTransportClient, RequestError}; use num_traits::Zero; use serde::de::DeserializeOwned; -use serde_json::{Value, from_value, to_value}; +use serde_json::{from_value, to_value, Value}; use sp_core::crypto::Pair; use sp_runtime::traits::IdentifyAccount; @@ -113,13 +112,7 @@ pub fn client(params: SubstrateConnectionParams) -> Client { /// Returns best Substrate header. pub async fn best_header(client: Client) -> (Client, Result) { - call_rpc( - client, - "chain_getHeader", - Params::None, - rpc_returns_value, - ) - .await + call_rpc(client, "chain_getHeader", Params::None, rpc_returns_value).await } /// Returns Substrate header by hash. @@ -127,9 +120,7 @@ pub async fn header_by_hash(client: Client, hash: Hash) -> (Client, Result (Client, Result "chain_getBlockHash", Params::Array(vec![to_value(number).unwrap()]), rpc_returns_value, - ).await + ) + .await } /// Get substrate account nonce. diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index 6c6d8bacdc..7fcbc177b9 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -14,17 +14,16 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::ethereum_client::{EthereumConnectionParams, EthereumSigningParams, self}; +use crate::ethereum_client::{self, EthereumConnectionParams, EthereumSigningParams}; use crate::ethereum_types::Address; -use crate::substrate_client::{SubstrateConnectionParams, self}; +use crate::substrate_client::{self, SubstrateConnectionParams}; use crate::substrate_types::{ - Header, Hash, Number, Justification, QueuedSubstrateHeader, - SubstrateHeaderId, SubstrateHeadersSyncPipeline, + Hash, Header, Justification, Number, QueuedSubstrateHeader, SubstrateHeaderId, SubstrateHeadersSyncPipeline, }; use crate::sync::{HeadersSyncParams, TargetTransactionMode}; use crate::sync_loop::{SourceClient, TargetClient}; use crate::sync_types::SourceHeader; -use futures::future::{FutureExt, Ready, ready}; +use futures::future::{ready, FutureExt, Ready}; use std::{future::Future, pin::Pin}; /// Interval (in ms) at which we check new Substrate headers when we are synced/almost synced. @@ -54,7 +53,8 @@ impl Default for SubstrateSyncParams { eth_sign: Default::default(), // the address 0x731a10897d267e19b34503ad902d0a29173ba4b1 is the address // of the contract that is deployed by default signer and 0 nonce - eth_contract_address: "731a10897d267e19b34503ad902d0a29173ba4b1".parse() + eth_contract_address: "731a10897d267e19b34503ad902d0a29173ba4b1" + .parse() .expect("address is hardcoded, thus valid; qed"), sub: Default::default(), sync_params: HeadersSyncParams { @@ -80,15 +80,13 @@ impl SourceClient for SubstrateHeadersSource { type BestBlockNumberFuture = Pin)>>>; type HeaderByHashFuture = Pin)>>>; type HeaderByNumberFuture = Pin)>>>; - type HeaderAsyncExtraFuture = Pin), Self::Error>)>>>; + type HeaderAsyncExtraFuture = + Pin), Self::Error>)>>>; type HeaderExtraFuture = Ready<(Self, Result<(SubstrateHeaderId, ()), Self::Error>)>; fn best_block_number(self) -> Self::BestBlockNumberFuture { substrate_client::best_header(self.client) - .map(|(client, result)| ( - SubstrateHeadersSource { client }, - result.map(|header| header.number) - )) + .map(|(client, result)| (SubstrateHeadersSource { client }, result.map(|header| header.number))) .boxed() } @@ -106,10 +104,12 @@ impl SourceClient for SubstrateHeadersSource { fn header_async_extra(self, id: SubstrateHeaderId) -> Self::HeaderAsyncExtraFuture { substrate_client::justification(self.client, id.1) - .map(move |(client, result)| ( - SubstrateHeadersSource { client }, - result.map(|justification| (id, justification)), - )) + .map(move |(client, result)| { + ( + SubstrateHeadersSource { client }, + result.map(|justification| (id, justification)), + ) + }) .boxed() } @@ -132,7 +132,8 @@ impl TargetClient for EthereumHeadersTarget { type Error = ethereum_client::Error; type BestHeaderIdFuture = Pin)>>>; type IsKnownHeaderFuture = Pin)>>>; - type RequiresAsyncExtraFuture = Pin)>>>; + type RequiresAsyncExtraFuture = + Pin)>>>; type RequiresExtraFuture = Ready<(Self, Result<(SubstrateHeaderId, bool), Self::Error>)>; type SubmitHeadersFuture = Pin, Self::Error>)>>>; @@ -178,22 +179,18 @@ impl TargetClient for EthereumHeadersTarget { fn submit_headers(self, headers: Vec) -> Self::SubmitHeadersFuture { let (contract, sign_params) = (self.contract, self.sign_params); - ethereum_client::submit_substrate_headers( - self.client, - sign_params.clone(), - contract, - headers, - ).map(move |(client, result)| { - ( - EthereumHeadersTarget { - client, - contract, - sign_params, - }, - result.map(|(_, submitted_headers)| submitted_headers), - ) - }) - .boxed() + ethereum_client::submit_substrate_headers(self.client, sign_params.clone(), contract, headers) + .map(move |(client, result)| { + ( + EthereumHeadersTarget { + client, + contract, + sign_params, + }, + result.map(|(_, submitted_headers)| submitted_headers), + ) + }) + .boxed() } } diff --git a/relays/ethereum/src/substrate_types.rs b/relays/ethereum/src/substrate_types.rs index ed29a2e71d..1cfa7384d6 100644 --- a/relays/ethereum/src/substrate_types.rs +++ b/relays/ethereum/src/substrate_types.rs @@ -14,11 +14,11 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::sync_types::{HeaderId, HeadersSyncPipeline, SourceHeader, QueuedHeader}; use crate::ethereum_types::{ Header as EthereumHeader, Receipt as EthereumReceipt, HEADER_ID_PROOF as ETHEREUM_HEADER_ID_PROOF, RECEIPT_GAS_USED_PROOF as ETHEREUM_RECEIPT_GAS_USED_PROOF, }; +use crate::sync_types::{HeaderId, HeadersSyncPipeline, QueuedHeader, SourceHeader}; pub use sp_bridge_eth_poa::{ Address, Bloom, Bytes, Header as SubstrateEthereumHeader, LogEntry as SubstrateEthereumLogEntry, Receipt as SubstrateEthereumReceipt, TransactionOutcome as SubstrateEthereumTransactionOutcome, H256, U256, diff --git a/relays/ethereum/src/sync.rs b/relays/ethereum/src/sync.rs index df51e2d03e..e1fc372e14 100644 --- a/relays/ethereum/src/sync.rs +++ b/relays/ethereum/src/sync.rs @@ -207,8 +207,8 @@ impl HeadersSync

{ #[cfg(test)] mod tests { use super::*; - use crate::headers::tests::{header, id}; use crate::ethereum_types::{EthereumHeadersSyncPipeline, H256}; + use crate::headers::tests::{header, id}; use crate::sync_types::HeaderStatus; fn side_hash(number: u64) -> H256 { diff --git a/relays/ethereum/src/sync_loop.rs b/relays/ethereum/src/sync_loop.rs index ffad4ff8ff..785e1608c5 100644 --- a/relays/ethereum/src/sync_loop.rs +++ b/relays/ethereum/src/sync_loop.rs @@ -49,7 +49,12 @@ pub trait SourceClient: Sized { /// Future that returns header by number. type HeaderByNumberFuture: Future)>; /// Future that returns async extra data associated with header. - type HeaderAsyncExtraFuture: Future, Option), Self::Error>)>; + type HeaderAsyncExtraFuture: Future< + Output = ( + Self, + Result<(HeaderId, Option), Self::Error>, + ), + >; /// Future that returns extra data associated with header. type HeaderExtraFuture: Future, P::Extra), Self::Error>)>; diff --git a/relays/ethereum/src/utils.rs b/relays/ethereum/src/utils.rs index fba18dfa59..4835465f08 100644 --- a/relays/ethereum/src/utils.rs +++ b/relays/ethereum/src/utils.rs @@ -21,6 +21,6 @@ macro_rules! bail_on_error { match $result { (client, Ok(result)) => (client, result), (client, Err(error)) => return (client, Err(error)), - } + } }; } From dbda454f34ceef81129f7b04765939e3ebb4df82 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 13 Apr 2020 16:43:30 +0300 Subject: [PATCH 25/92] fix --- relays/ethereum/src/ethereum_client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index f3295be036..467dab9962 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -240,7 +240,7 @@ pub async fn best_substrate_block( }; if number != number.low_u32().into() { - return Err(Error::InvalidSubstrateBlockNumber); + return (client, Err(Error::InvalidSubstrateBlockNumber)); } (client, Ok(HeaderId(number.low_u32(), hash))) From 74cd275de73bfa056135a6719d11d6e24944c689 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 13 Apr 2020 17:19:54 +0300 Subject: [PATCH 26/92] bail_on_arg_error!() --- relays/ethereum/src/ethereum_client.rs | 77 ++++++++++++------------- relays/ethereum/src/substrate_client.rs | 70 ++++++++++++---------- relays/ethereum/src/utils.rs | 11 ++++ 3 files changed, 88 insertions(+), 70 deletions(-) diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index 467dab9962..37a4358fd7 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -14,10 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::bail_on_error; use crate::ethereum_types::{Address, Bytes, EthereumHeaderId, Header, Receipt, H256, U256, U64}; use crate::substrate_types::{Hash as SubstrateHash, QueuedSubstrateHeader, SubstrateHeaderId}; use crate::sync_types::{HeaderId, MaybeConnectionError}; +use crate::{bail_on_arg_error, bail_on_error}; use codec::{Decode, Encode}; use ethabi::FunctionOutputDecoder; use jsonrpsee::common::Params; @@ -100,6 +100,8 @@ pub struct CallRequest { pub enum Error { /// Request start failed. StartRequestFailed(RequestError), + /// Error serializing request. + RequestSerialization(serde_json::Error), /// Request not found (should never occur?). RequestNotFound, /// Failed to receive response. @@ -218,18 +220,16 @@ pub async fn best_substrate_block( contract_address: Address, ) -> (Client, Result) { let (encoded_call, call_decoder) = bridge_contract::functions::best_known_header::call(); - let (client, call_result) = bail_on_error!( - call_rpc::( - client, - "eth_call", - Params::Array(vec![to_value(CallRequest { - to: Some(contract_address), - data: Some(encoded_call.into()), - }) - .unwrap(),]), - ) - .await + let call_request = bail_on_arg_error!( + to_value(CallRequest { + to: Some(contract_address), + data: Some(encoded_call.into()), + }) + .map_err(|e| Error::RequestSerialization(e)), + client ); + let (client, call_result) = + bail_on_error!(call_rpc::(client, "eth_call", Params::Array(vec![call_request]),).await); let (number, raw_hash) = match call_decoder.decode(&call_result.0) { Ok((raw_number, raw_hash)) => (raw_number, raw_hash), Err(error) => return (client, Err(Error::ResponseParseFailed(format!("{}", error)))), @@ -253,18 +253,16 @@ pub async fn substrate_header_known( id: SubstrateHeaderId, ) -> (Client, Result<(SubstrateHeaderId, bool), Error>) { let (encoded_call, call_decoder) = bridge_contract::functions::is_known_header::call(id.1); - let (client, call_result) = bail_on_error!( - call_rpc::( - client, - "eth_call", - Params::Array(vec![to_value(CallRequest { - to: Some(contract_address), - data: Some(encoded_call.into()), - }) - .unwrap(),]), - ) - .await + let call_request = bail_on_arg_error!( + to_value(CallRequest { + to: Some(contract_address), + data: Some(encoded_call.into()), + }) + .map_err(|e| Error::RequestSerialization(e)), + client ); + let (client, call_result) = + bail_on_error!(call_rpc::(client, "eth_call", Params::Array(vec![call_request]),).await); match call_decoder.decode(&call_result.0) { Ok(is_known_block) => (client, Ok((id, is_known_block))), Err(error) => (client, Err(Error::ResponseParseFailed(format!("{}", error)))), @@ -356,32 +354,29 @@ async fn submit_ethereum_transaction( data: encoded_call, } .sign(¶ms.signer.secret().as_fixed_bytes().into(), ¶ms.chain_id); - call_rpc( - client, - "eth_submitTransaction", - Params::Array(vec![to_value(Bytes(raw_transaction)).unwrap()]), - ) - .await + let transaction = bail_on_arg_error!( + to_value(Bytes(raw_transaction)).map_err(|e| Error::RequestSerialization(e)), + client + ); + call_rpc(client, "eth_submitTransaction", Params::Array(vec![transaction])).await } /// Get account nonce. async fn account_nonce(client: Client, caller_address: Address) -> (Client, Result) { - call_rpc( - client, - "eth_getTransactionCount", - Params::Array(vec![to_value(caller_address).unwrap()]), - ) - .await + let caller_address = bail_on_arg_error!( + to_value(caller_address).map_err(|e| Error::RequestSerialization(e)), + client + ); + call_rpc(client, "eth_getTransactionCount", Params::Array(vec![caller_address])).await } /// Estimate gas usage for call. async fn estimate_gas(client: Client, call_request: CallRequest) -> (Client, Result) { - call_rpc( - client, - "eth_estimateGas", - Params::Array(vec![to_value(call_request).unwrap()]), - ) - .await + let call_request = bail_on_arg_error!( + to_value(call_request).map_err(|e| Error::RequestSerialization(e)), + client + ); + call_rpc(client, "eth_estimateGas", Params::Array(vec![call_request])).await } /// Calls RPC on Ethereum node. diff --git a/relays/ethereum/src/substrate_client.rs b/relays/ethereum/src/substrate_client.rs index 13a55c8a89..3a7f314410 100644 --- a/relays/ethereum/src/substrate_client.rs +++ b/relays/ethereum/src/substrate_client.rs @@ -14,13 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::bail_on_error; use crate::ethereum_types::{Bytes, EthereumHeaderId, QueuedEthereumHeader, H256}; use crate::substrate_types::{ into_substrate_ethereum_header, into_substrate_ethereum_receipts, Hash, Header as SubstrateHeader, Justification, Number, TransactionHash, }; use crate::sync_types::{HeaderId, MaybeConnectionError, SourceHeader}; +use crate::{bail_on_arg_error, bail_on_error}; use codec::{Decode, Encode}; use jsonrpsee::common::Params; use jsonrpsee::raw::{RawClient, RawClientError}; @@ -83,6 +83,8 @@ pub struct Client { pub enum Error { /// Request start failed. StartRequestFailed(RequestError), + /// Error serializing request. + RequestSerialization(serde_json::Error), /// Request not found (should never occur?). RequestNotFound, /// Failed to receive response. @@ -117,13 +119,8 @@ pub async fn best_header(client: Client) -> (Client, Result (Client, Result) { - call_rpc( - client, - "chain_getHeader", - Params::Array(vec![to_value(hash).unwrap()]), - rpc_returns_value, - ) - .await + let hash = bail_on_arg_error!(to_value(hash).map_err(|e| Error::RequestSerialization(e)), client); + call_rpc(client, "chain_getHeader", Params::Array(vec![hash]), rpc_returns_value).await } /// Returns Substrate header by number. @@ -143,8 +140,8 @@ pub async fn best_ethereum_block(client: Client) -> (Client, Result (Client, Result<(EthereumHeaderId, bool), Error>) { let id = header.header().id(); let header = into_substrate_ethereum_header(header.header()); - let encoded_header = header.encode(); + let encoded_header = bail_on_arg_error!( + to_value(Bytes(header.encode())).map_err(|e| Error::RequestSerialization(e)), + client + ); let (client, receipts_required) = call_rpc( client, "state_call", Params::Array(vec![ - to_value("EthereumHeadersApi_is_import_requires_receipts").unwrap(), - to_value(Bytes(encoded_header)).unwrap(), + serde_json::Value::String("EthereumHeadersApi_is_import_requires_receipts".into()), + encoded_header, ]), rpc_returns_encoded_value, ) @@ -187,13 +187,16 @@ pub async fn ethereum_header_known( // But when we'll read best header from Substrate next time, we will know that // there's a better header => this Orphan will either be marked as synced, or // eventually pruned. - let encoded_id = id.1.encode(); + let encoded_id = bail_on_arg_error!( + to_value(Bytes(id.1.encode())).map_err(|e| Error::RequestSerialization(e)), + client + ); let (client, is_known_block) = call_rpc( client, "state_call", Params::Array(vec![ - to_value("EthereumHeadersApi_is_known_block").unwrap(), - to_value(Bytes(encoded_id)).unwrap(), + serde_json::Value::String("EthereumHeadersApi_is_known_block".into()), + encoded_id, ]), rpc_returns_encoded_value, ) @@ -233,11 +236,14 @@ pub async fn submit_signed_ethereum_headers( let (client, nonce) = bail_on_error!(next_account_index(client, account_id).await); let transaction = create_signed_submit_transaction(headers, ¶ms.signer, nonce, genesis_hash); - let encoded_transaction = transaction.encode(); + let encoded_transaction = bail_on_arg_error!( + to_value(Bytes(transaction.encode())).map_err(|e| Error::RequestSerialization(e)), + client + ); let (client, transaction_hash) = call_rpc( client, "author_submitExtrinsic", - Params::Array(vec![to_value(Bytes(encoded_transaction)).unwrap()]), + Params::Array(vec![encoded_transaction]), rpc_returns_value, ) .await; @@ -258,12 +264,15 @@ pub async fn submit_unsigned_ethereum_headers( for header in headers { let transaction = create_unsigned_submit_transaction(header); - let encoded_transaction = transaction.encode(); + let encoded_transaction = bail_on_arg_error!( + to_value(Bytes(transaction.encode())).map_err(|e| Error::RequestSerialization(e)), + client + ); let (used_client, transaction_hash) = bail_on_error!( call_rpc( client, "author_submitExtrinsic", - Params::Array(vec![to_value(Bytes(encoded_transaction)).unwrap()]), + Params::Array(vec![encoded_transaction]), rpc_returns_value, ) .await @@ -278,12 +287,13 @@ pub async fn submit_unsigned_ethereum_headers( /// Get GRANDPA authorities set at given block. pub async fn grandpa_authorities_set(client: Client, block: Hash) -> (Client, Result, Error>) { + let block = bail_on_arg_error!(to_value(block).map_err(|e| Error::RequestSerialization(e)), client); call_rpc( client, "state_call", Params::Array(vec![ - to_value("GrandpaApi_grandpa_authorities").unwrap(), - to_value(block).unwrap(), + serde_json::Value::String("GrandpaApi_grandpa_authorities".into()), + block, ]), rpc_returns_bytes, ) @@ -292,10 +302,11 @@ pub async fn grandpa_authorities_set(client: Client, block: Hash) -> (Client, Re /// Get Substrate block hash by its number. async fn block_hash_by_number(client: Client, number: Number) -> (Client, Result) { + let number = bail_on_arg_error!(to_value(number).map_err(|e| Error::RequestSerialization(e)), client); call_rpc( client, "chain_getBlockHash", - Params::Array(vec![to_value(number).unwrap()]), + Params::Array(vec![number]), rpc_returns_value, ) .await @@ -308,12 +319,13 @@ async fn next_account_index( ) -> (Client, Result) { use sp_core::crypto::Ss58Codec; - let (client, index) = call_rpc( - client, - "system_accountNextIndex", - Params::Array(vec![to_value(account.to_ss58check()).unwrap()]), - |v| rpc_returns_value::(v), - ) + let account = bail_on_arg_error!( + to_value(account.to_ss58check()).map_err(|e| Error::RequestSerialization(e)), + client + ); + let (client, index) = call_rpc(client, "system_accountNextIndex", Params::Array(vec![account]), |v| { + rpc_returns_value::(v) + }) .await; (client, index.map(|index| index as _)) } diff --git a/relays/ethereum/src/utils.rs b/relays/ethereum/src/utils.rs index 4835465f08..4f022c8047 100644 --- a/relays/ethereum/src/utils.rs +++ b/relays/ethereum/src/utils.rs @@ -24,3 +24,14 @@ macro_rules! bail_on_error { } }; } + +/// Macro that returns (client, Err(error)) tuple from function if result is Err(error). +#[macro_export] +macro_rules! bail_on_arg_error { + ($result: expr, $client: ident) => { + match $result { + Ok(result) => result, + Err(error) => return ($client, Err(error)), + } + }; +} From 84443a163c6bfd30d20dedeffe8a9af9a0ae12e8 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 13 Apr 2020 17:36:35 +0300 Subject: [PATCH 27/92] fix --- relays/ethereum/src/ethereum_client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index 37a4358fd7..dffbb52715 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -349,7 +349,7 @@ async fn submit_ethereum_transaction( nonce, to: contract_address, value: U256::zero(), - gas: if double_gas { gas.saturating_sub(2.into()) } else { gas }, + gas: if double_gas { gas.saturating_mul(2.into()) } else { gas }, gas_price: params.gas_price, data: encoded_call, } From 8118db6a9b22a3e175fbc8b65485f3a244bd64e1 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 13 Apr 2020 18:03:19 +0300 Subject: [PATCH 28/92] fix --- relays/ethereum/src/ethereum_client.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index dffbb52715..8bf17e41e8 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -339,6 +339,7 @@ async fn submit_ethereum_transaction( estimate_gas( client, CallRequest { + to: contract_address, data: Some(encoded_call.clone().into()), ..Default::default() } From c434b64d0af3ec5b93961ee8e02dd06cea1cb246 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 15 Apr 2020 14:40:30 +0300 Subject: [PATCH 29/92] remove async_extra stuff --- relays/ethereum/src/ethereum_sync_loop.rs | 12 +----------- relays/ethereum/src/ethereum_types.rs | 1 - relays/ethereum/src/substrate_client.rs | 9 ++------- relays/ethereum/src/substrate_sync_loop.rs | 21 +-------------------- relays/ethereum/src/substrate_types.rs | 4 ---- relays/ethereum/src/sync_loop.rs | 13 ------------- relays/ethereum/src/sync_types.rs | 2 -- 7 files changed, 4 insertions(+), 58 deletions(-) diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index 414c1c21f6..072a0ade92 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -19,7 +19,7 @@ use crate::ethereum_types::{EthereumHeaderId, EthereumHeadersSyncPipeline, Heade use crate::substrate_client::{self, SubstrateConnectionParams, SubstrateSigningParams}; use crate::sync::{HeadersSyncParams, TargetTransactionMode}; use crate::sync_loop::{SourceClient, TargetClient}; -use futures::future::{ready, FutureExt, Ready}; +use futures::future::FutureExt; use std::{future::Future, pin::Pin}; use web3::types::H256; @@ -69,7 +69,6 @@ impl SourceClient for EthereumHeadersSource { type BestBlockNumberFuture = Pin)>>>; type HeaderByHashFuture = Pin)>>>; type HeaderByNumberFuture = Pin)>>>; - type HeaderAsyncExtraFuture = Ready<(Self, Result<(EthereumHeaderId, Option<()>), Self::Error>)>; type HeaderExtraFuture = Pin), Self::Error>)>>>; @@ -91,10 +90,6 @@ impl SourceClient for EthereumHeadersSource { .boxed() } - fn header_async_extra(self, id: EthereumHeaderId) -> Self::HeaderAsyncExtraFuture { - ready((self, Ok((id, Some(()))))) - } - fn header_extra(self, id: EthereumHeaderId, header: &Header) -> Self::HeaderExtraFuture { ethereum_client::transactions_receipts(self.client, id, header.transactions.clone()) .map(|(client, result)| (EthereumHeadersSource { client }, result)) @@ -116,7 +111,6 @@ impl TargetClient for SubstrateHeadersTarget { type Error = substrate_client::Error; type BestHeaderIdFuture = Pin)>>>; type IsKnownHeaderFuture = Pin)>>>; - type RequiresAsyncExtraFuture = Ready<(Self, Result<(EthereumHeaderId, bool), Self::Error>)>; type RequiresExtraFuture = Pin)>>>; type SubmitHeadersFuture = Pin, Self::Error>)>>>; @@ -152,10 +146,6 @@ impl TargetClient for SubstrateHeadersTarget { .boxed() } - fn requires_async_extra(self, id: EthereumHeaderId) -> Self::RequiresAsyncExtraFuture { - ready((self, Ok((id, false)))) - } - fn requires_extra(self, header: &QueuedEthereumHeader) -> Self::RequiresExtraFuture { // we can minimize number of receipts_check calls by checking header // logs bloom here, but it may give us false positives (when authorities diff --git a/relays/ethereum/src/ethereum_types.rs b/relays/ethereum/src/ethereum_types.rs index 12ae6354dd..dc61db2deb 100644 --- a/relays/ethereum/src/ethereum_types.rs +++ b/relays/ethereum/src/ethereum_types.rs @@ -52,7 +52,6 @@ impl HeadersSyncPipeline for EthereumHeadersSyncPipeline { type Hash = H256; type Number = u64; type Header = Header; - type AsyncExtra = (); type Extra = Vec; fn estimate_size(source: &QueuedHeader) -> usize { diff --git a/relays/ethereum/src/substrate_client.rs b/relays/ethereum/src/substrate_client.rs index 3a7f314410..beb2d2f196 100644 --- a/relays/ethereum/src/substrate_client.rs +++ b/relays/ethereum/src/substrate_client.rs @@ -16,8 +16,8 @@ use crate::ethereum_types::{Bytes, EthereumHeaderId, QueuedEthereumHeader, H256}; use crate::substrate_types::{ - into_substrate_ethereum_header, into_substrate_ethereum_receipts, Hash, Header as SubstrateHeader, Justification, - Number, TransactionHash, + into_substrate_ethereum_header, into_substrate_ethereum_receipts, Hash, Header as SubstrateHeader, Number, + TransactionHash, }; use crate::sync_types::{HeaderId, MaybeConnectionError, SourceHeader}; use crate::{bail_on_arg_error, bail_on_error}; @@ -129,11 +129,6 @@ pub async fn header_by_number(client: Client, number: Number) -> (Client, Result header_by_hash(client, hash).await } -/// Returns justification for Substrate header. -pub async fn justification(client: Client, _hash: Hash) -> (Client, Result, Error>) { - (client, Ok(Some(vec![42]))) // TODO: implement me -} - /// Returns best Ethereum block that Substrate runtime knows of. pub async fn best_ethereum_block(client: Client) -> (Client, Result) { let (client, result) = call_rpc( diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index 7fcbc177b9..539b9f8e59 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -18,7 +18,7 @@ use crate::ethereum_client::{self, EthereumConnectionParams, EthereumSigningPara use crate::ethereum_types::Address; use crate::substrate_client::{self, SubstrateConnectionParams}; use crate::substrate_types::{ - Hash, Header, Justification, Number, QueuedSubstrateHeader, SubstrateHeaderId, SubstrateHeadersSyncPipeline, + Hash, Header, Number, QueuedSubstrateHeader, SubstrateHeaderId, SubstrateHeadersSyncPipeline, }; use crate::sync::{HeadersSyncParams, TargetTransactionMode}; use crate::sync_loop::{SourceClient, TargetClient}; @@ -80,8 +80,6 @@ impl SourceClient for SubstrateHeadersSource { type BestBlockNumberFuture = Pin)>>>; type HeaderByHashFuture = Pin)>>>; type HeaderByNumberFuture = Pin)>>>; - type HeaderAsyncExtraFuture = - Pin), Self::Error>)>>>; type HeaderExtraFuture = Ready<(Self, Result<(SubstrateHeaderId, ()), Self::Error>)>; fn best_block_number(self) -> Self::BestBlockNumberFuture { @@ -102,17 +100,6 @@ impl SourceClient for SubstrateHeadersSource { .boxed() } - fn header_async_extra(self, id: SubstrateHeaderId) -> Self::HeaderAsyncExtraFuture { - substrate_client::justification(self.client, id.1) - .map(move |(client, result)| { - ( - SubstrateHeadersSource { client }, - result.map(|justification| (id, justification)), - ) - }) - .boxed() - } - fn header_extra(self, id: SubstrateHeaderId, _header: &Header) -> Self::HeaderExtraFuture { ready((self, Ok((id, ())))) } @@ -132,8 +119,6 @@ impl TargetClient for EthereumHeadersTarget { type Error = ethereum_client::Error; type BestHeaderIdFuture = Pin)>>>; type IsKnownHeaderFuture = Pin)>>>; - type RequiresAsyncExtraFuture = - Pin)>>>; type RequiresExtraFuture = Ready<(Self, Result<(SubstrateHeaderId, bool), Self::Error>)>; type SubmitHeadersFuture = Pin, Self::Error>)>>>; @@ -169,10 +154,6 @@ impl TargetClient for EthereumHeadersTarget { .boxed() } - fn requires_async_extra(self, id: SubstrateHeaderId) -> Self::RequiresAsyncExtraFuture { - ready((self, Ok((id, false)))).boxed() // TODO: actual impl - } - fn requires_extra(self, header: &QueuedSubstrateHeader) -> Self::RequiresExtraFuture { ready((self, Ok((header.header().id(), false)))) } diff --git a/relays/ethereum/src/substrate_types.rs b/relays/ethereum/src/substrate_types.rs index 1cfa7384d6..268bf48a5d 100644 --- a/relays/ethereum/src/substrate_types.rs +++ b/relays/ethereum/src/substrate_types.rs @@ -36,9 +36,6 @@ pub type Number = bridge_node_runtime::BlockNumber; /// Substrate header type. pub type Header = bridge_node_runtime::Header; -/// Substrate justification type. -pub type Justification = Vec; - /// Substrate header ID. pub type SubstrateHeaderId = HeaderId; @@ -57,7 +54,6 @@ impl HeadersSyncPipeline for SubstrateHeadersSyncPipeline { type Hash = bridge_node_runtime::Hash; type Number = bridge_node_runtime::BlockNumber; type Header = Header; - type AsyncExtra = Justification; type Extra = (); fn estimate_size(_source: &QueuedHeader) -> usize { diff --git a/relays/ethereum/src/sync_loop.rs b/relays/ethereum/src/sync_loop.rs index 785e1608c5..b2e97c9794 100644 --- a/relays/ethereum/src/sync_loop.rs +++ b/relays/ethereum/src/sync_loop.rs @@ -48,13 +48,6 @@ pub trait SourceClient: Sized { type HeaderByHashFuture: Future)>; /// Future that returns header by number. type HeaderByNumberFuture: Future)>; - /// Future that returns async extra data associated with header. - type HeaderAsyncExtraFuture: Future< - Output = ( - Self, - Result<(HeaderId, Option), Self::Error>, - ), - >; /// Future that returns extra data associated with header. type HeaderExtraFuture: Future, P::Extra), Self::Error>)>; @@ -64,8 +57,6 @@ pub trait SourceClient: Sized { fn header_by_hash(self, hash: P::Hash) -> Self::HeaderByHashFuture; /// Get canonical header by number. fn header_by_number(self, number: P::Number) -> Self::HeaderByNumberFuture; - /// Get async extra data by header hash. - fn header_async_extra(self, id: HeaderId) -> Self::HeaderAsyncExtraFuture; /// Get extra data by header hash. fn header_extra(self, id: HeaderId, header: &P::Header) -> Self::HeaderExtraFuture; } @@ -78,8 +69,6 @@ pub trait TargetClient: Sized { type BestHeaderIdFuture: Future, Self::Error>)>; /// Future that returns known header check result. type IsKnownHeaderFuture: Future, bool), Self::Error>)>; - /// Future that returns async extra check result. - type RequiresAsyncExtraFuture: Future, bool), Self::Error>)>; /// Future that returns extra check result. type RequiresExtraFuture: Future, bool), Self::Error>)>; /// Future that returns header submission result. @@ -89,8 +78,6 @@ pub trait TargetClient: Sized { fn best_header_id(self) -> Self::BestHeaderIdFuture; /// Returns true if header is known to the target node. fn is_known_header(self, id: HeaderId) -> Self::IsKnownHeaderFuture; - /// Returns true if header requires async extra data to be submitted. - fn requires_async_extra(self, id: HeaderId) -> Self::RequiresAsyncExtraFuture; /// Returns true if header requires extra data to be submitted. fn requires_extra(self, header: &QueuedHeader

) -> Self::RequiresExtraFuture; /// Submit headers. diff --git a/relays/ethereum/src/sync_types.rs b/relays/ethereum/src/sync_types.rs index 28b7646b85..9b9712c739 100644 --- a/relays/ethereum/src/sync_types.rs +++ b/relays/ethereum/src/sync_types.rs @@ -70,8 +70,6 @@ pub trait HeadersSyncPipeline: Clone + Copy { type Header: Clone + std::fmt::Debug + SourceHeader; /// Type of extra data for the header that we're receiving from the source node. type Extra: Clone + std::fmt::Debug; - /// Type of extra data that we're sending separately from the header itself. - type AsyncExtra: Clone + std::fmt::Debug; /// Function used to convert from queued header to target header. fn estimate_size(source: &QueuedHeader) -> usize; From 0bc574307135be9e42c1607bce228c8e42175af9 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 15 Apr 2020 14:09:26 +0300 Subject: [PATCH 30/92] start work on finality builtin remove async_extra stuff continue continue local testnet (Alice + Bob) for node --- Cargo.lock | 1098 +++++------------ bin/node/node/src/chain_spec.rs | 65 +- bin/node/runtime/Cargo.toml | 12 + bin/node/runtime/src/lib.rs | 50 +- modules/ethereum-contract/builtin/Cargo.toml | 22 +- modules/ethereum-contract/builtin/src/lib.rs | 212 +++- .../contracts/substrate-bridge.sol | 121 +- relays/ethereum/res/substrate-bridge.json | 19 +- relays/ethereum/src/ethereum_client.rs | 63 +- .../ethereum/src/ethereum_deploy_contract.rs | 2 +- relays/ethereum/src/ethereum_sync_loop.rs | 31 +- relays/ethereum/src/ethereum_types.rs | 2 +- relays/ethereum/src/headers.rs | 404 ++++-- relays/ethereum/src/substrate_client.rs | 22 +- relays/ethereum/src/substrate_sync_loop.rs | 67 +- relays/ethereum/src/substrate_types.rs | 9 +- relays/ethereum/src/sync_loop.rs | 103 +- relays/ethereum/src/sync_types.rs | 11 +- 18 files changed, 1329 insertions(+), 984 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4466e35ceb..ca368968ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -460,12 +460,12 @@ dependencies = [ "sc-service", "sc-transaction-pool", "sp-bridge-eth-poa", - "sp-consensus 0.8.0-alpha.2", + "sp-consensus", "sp-consensus-aura", - "sp-core 2.0.0-alpha.2", - "sp-finality-grandpa 2.0.0-alpha.2", - "sp-inherents 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", + "sp-core", + "sp-finality-grandpa", + "sp-inherents", + "sp-runtime", "sp-transaction-pool", "structopt", "substrate-build-script-utils", @@ -486,24 +486,26 @@ dependencies = [ "pallet-bridge-eth-poa", "pallet-grandpa", "pallet-randomness-collective-flip", + "pallet-session", "pallet-sudo", "pallet-timestamp", "pallet-transaction-payment", "parity-scale-codec", "serde", - "sp-api 2.0.0-alpha.2", - "sp-block-builder 2.0.0-alpha.2", + "sp-api", + "sp-block-builder", "sp-bridge-eth-poa", "sp-consensus-aura", - "sp-core 2.0.0-alpha.2", - "sp-inherents 2.0.0-alpha.2", - "sp-io 2.0.0-alpha.2", + "sp-core", + "sp-inherents", + "sp-io", "sp-offchain", - "sp-runtime 2.0.0-alpha.2", + "sp-runtime", "sp-session", - "sp-std 2.0.0-alpha.2", + "sp-staking", + "sp-std", "sp-transaction-pool", - "sp-version 2.0.0-alpha.2", + "sp-version", "substrate-wasm-builder-runner", ] @@ -1071,11 +1073,12 @@ name = "ethereum-contract-builtin" version = "0.1.0" dependencies = [ "bridge-node-runtime", + "ethereum-types 0.8.0", "finality-grandpa", "parity-scale-codec", - "sp-blockchain 2.0.0-alpha.5", - "sp-finality-grandpa 2.0.0-alpha.5", - "sp-runtime 2.0.0-alpha.5", + "sp-blockchain", + "sp-finality-grandpa", + "sp-runtime", ] [[package]] @@ -1108,9 +1111,9 @@ dependencies = [ "serde", "serde_json", "sp-bridge-eth-poa", - "sp-core 2.0.0-alpha.2", + "sp-core", "sp-keyring", - "sp-runtime 2.0.0-alpha.2", + "sp-runtime", "time 0.2.9", "web3", ] @@ -1326,10 +1329,10 @@ version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "parity-scale-codec", - "sp-api 2.0.0-alpha.2", - "sp-io 2.0.0-alpha.2", - "sp-runtime-interface 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-api", + "sp-io", + "sp-runtime-interface", + "sp-std", ] [[package]] @@ -1341,9 +1344,9 @@ dependencies = [ "frame-system", "parity-scale-codec", "serde", - "sp-io 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -1353,8 +1356,8 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "parity-scale-codec", "serde", - "sp-core 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-core", + "sp-std", ] [[package]] @@ -1371,13 +1374,13 @@ dependencies = [ "parity-scale-codec", "paste", "serde", - "sp-arithmetic 2.0.0-alpha.2", - "sp-core 2.0.0-alpha.2", - "sp-inherents 2.0.0-alpha.2", - "sp-io 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-state-machine 0.8.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-arithmetic", + "sp-core", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-state-machine", + "sp-std", "tracing", ] @@ -1423,11 +1426,11 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "serde", - "sp-core 2.0.0-alpha.2", - "sp-io 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", - "sp-version 2.0.0-alpha.2", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-version", ] [[package]] @@ -1436,7 +1439,7 @@ version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "parity-scale-codec", - "sp-api 2.0.0-alpha.2", + "sp-api", ] [[package]] @@ -2336,7 +2339,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03080afe6f42cd996da9f568d6add5d7fb5ee2ea7fb7802d2d2cbd836958fd87" dependencies = [ "parity-bytes", - "parity-util-mem 0.5.2", + "parity-util-mem", "smallvec 1.2.0", ] @@ -2347,7 +2350,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9355274e5a9e0a7e8ef43916950eae3949024de2a8dffe4d5a6c13974a37c8e" dependencies = [ "kvdb", - "parity-util-mem 0.5.2", + "parity-util-mem", "parking_lot 0.10.2", ] @@ -2363,7 +2366,7 @@ dependencies = [ "log 0.4.8", "num_cpus", "owning_ref", - "parity-util-mem 0.5.2", + "parity-util-mem", "parking_lot 0.10.2", "regex", "rocksdb", @@ -2944,19 +2947,7 @@ dependencies = [ "ahash 0.2.18", "hash-db", "hashbrown 0.6.3", - "parity-util-mem 0.5.2", -] - -[[package]] -name = "memory-db" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f58381b20ebe2c578e75dececd9da411414903415349548ccc46aac3209cdfbc" -dependencies = [ - "ahash 0.2.18", - "hash-db", - "hashbrown 0.6.3", - "parity-util-mem 0.6.0", + "parity-util-mem", ] [[package]] @@ -2977,18 +2968,6 @@ dependencies = [ "zeroize 1.1.0", ] -[[package]] -name = "merlin" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6feca46f4fa3443a01769d768727f10c10a20fdb65e52dc16a81f0c8269bb78" -dependencies = [ - "byteorder 1.3.4", - "keccak", - "rand_core 0.5.1", - "zeroize 1.1.0", -] - [[package]] name = "mime" version = "0.2.6" @@ -3137,8 +3116,8 @@ name = "node-primitives" version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ - "sp-core 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", + "sp-core", + "sp-runtime", ] [[package]] @@ -3293,13 +3272,13 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "serde", - "sp-application-crypto 2.0.0-alpha.2", + "sp-application-crypto", "sp-consensus-aura", - "sp-core 2.0.0-alpha.2", - "sp-inherents 2.0.0-alpha.2", - "sp-io 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-core", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-std", "sp-timestamp", ] @@ -3313,9 +3292,9 @@ dependencies = [ "frame-system", "parity-scale-codec", "serde", - "sp-io 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -3328,12 +3307,12 @@ dependencies = [ "pallet-session", "parity-scale-codec", "serde", - "sp-core 2.0.0-alpha.2", - "sp-finality-grandpa 2.0.0-alpha.2", - "sp-io 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-state-machine 0.8.0-alpha.2", - "sp-trie 2.0.0-alpha.2", + "sp-core", + "sp-finality-grandpa", + "sp-io", + "sp-runtime", + "sp-state-machine", + "sp-trie", ] [[package]] @@ -3346,9 +3325,9 @@ dependencies = [ "parity-scale-codec", "serde", "sp-bridge-eth-poa", - "sp-io 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -3362,9 +3341,9 @@ dependencies = [ "parity-scale-codec", "serde", "sp-finality-tracker", - "sp-inherents 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-inherents", + "sp-runtime", + "sp-std", ] [[package]] @@ -3378,11 +3357,11 @@ dependencies = [ "pallet-session", "parity-scale-codec", "serde", - "sp-core 2.0.0-alpha.2", - "sp-finality-grandpa 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", + "sp-core", + "sp-finality-grandpa", + "sp-runtime", "sp-staking", - "sp-std 2.0.0-alpha.2", + "sp-std", ] [[package]] @@ -3394,8 +3373,8 @@ dependencies = [ "frame-system", "parity-scale-codec", "safe-mix", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-runtime", + "sp-std", ] [[package]] @@ -3409,11 +3388,11 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "serde", - "sp-io 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", + "sp-io", + "sp-runtime", "sp-staking", - "sp-std 2.0.0-alpha.2", - "sp-trie 2.0.0-alpha.2", + "sp-std", + "sp-trie", ] [[package]] @@ -3425,9 +3404,9 @@ dependencies = [ "frame-system", "parity-scale-codec", "serde", - "sp-io 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -3441,10 +3420,10 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "serde", - "sp-inherents 2.0.0-alpha.2", - "sp-io 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-std", "sp-timestamp", ] @@ -3457,8 +3436,8 @@ dependencies = [ "frame-system", "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-runtime", + "sp-std", ] [[package]] @@ -3469,9 +3448,9 @@ dependencies = [ "frame-support", "parity-scale-codec", "serde", - "sp-api 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-api", + "sp-runtime", + "sp-std", ] [[package]] @@ -3639,20 +3618,6 @@ dependencies = [ "winapi 0.3.8", ] -[[package]] -name = "parity-util-mem" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e42755f26e5ea21a6a819d9e63cbd70713e9867a2b767ec2cc65ca7659532c5" -dependencies = [ - "cfg-if", - "impl-trait-for-tuples", - "parity-util-mem-derive", - "parking_lot 0.10.2", - "primitive-types 0.7.0", - "winapi 0.3.8", -] - [[package]] name = "parity-util-mem-derive" version = "0.1.0" @@ -4486,12 +4451,12 @@ dependencies = [ "sc-client", "sc-client-api", "sc-telemetry", - "sp-api 2.0.0-alpha.2", - "sp-blockchain 2.0.0-alpha.2", - "sp-consensus 0.8.0-alpha.2", - "sp-core 2.0.0-alpha.2", - "sp-inherents 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-inherents", + "sp-runtime", "sp-transaction-pool", "tokio-executor 0.2.0-alpha.6", ] @@ -4503,13 +4468,13 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "parity-scale-codec", "sc-client-api", - "sp-api 2.0.0-alpha.2", - "sp-block-builder 2.0.0-alpha.2", - "sp-blockchain 2.0.0-alpha.2", - "sp-consensus 0.8.0-alpha.2", - "sp-core 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-state-machine 0.8.0-alpha.2", + "sp-api", + "sp-block-builder", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-runtime", + "sp-state-machine", ] [[package]] @@ -4523,8 +4488,8 @@ dependencies = [ "sc-telemetry", "serde", "serde_json", - "sp-core 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", + "sp-core", + "sp-runtime", ] [[package]] @@ -4555,7 +4520,7 @@ dependencies = [ "lazy_static", "log 0.4.8", "names", - "parity-util-mem 0.5.2", + "parity-util-mem", "prometheus-exporter", "regex", "rpassword", @@ -4566,12 +4531,12 @@ dependencies = [ "sc-telemetry", "sc-tracing", "serde_json", - "sp-blockchain 2.0.0-alpha.2", - "sp-core 2.0.0-alpha.2", + "sp-blockchain", + "sp-core", "sp-keyring", - "sp-panic-handler 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-state-machine 0.8.0-alpha.2", + "sp-panic-handler", + "sp-runtime", + "sp-state-machine", "structopt", "time 0.1.42", "tokio 0.2.16", @@ -4595,18 +4560,18 @@ dependencies = [ "sc-client-api", "sc-executor", "sc-telemetry", - "sp-api 2.0.0-alpha.2", - "sp-blockchain 2.0.0-alpha.2", - "sp-consensus 0.8.0-alpha.2", - "sp-core 2.0.0-alpha.2", - "sp-externalities 0.8.0-alpha.2", - "sp-inherents 2.0.0-alpha.2", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-externalities", + "sp-inherents", "sp-keyring", - "sp-runtime 2.0.0-alpha.2", - "sp-state-machine 0.8.0-alpha.2", - "sp-std 2.0.0-alpha.2", - "sp-trie 2.0.0-alpha.2", - "sp-version 2.0.0-alpha.2", + "sp-runtime", + "sp-state-machine", + "sp-std", + "sp-trie", + "sp-version", "tracing", ] @@ -4626,19 +4591,19 @@ dependencies = [ "parking_lot 0.10.2", "sc-executor", "sc-telemetry", - "sp-api 2.0.0-alpha.2", - "sp-blockchain 2.0.0-alpha.2", - "sp-consensus 0.8.0-alpha.2", - "sp-core 2.0.0-alpha.2", - "sp-externalities 0.8.0-alpha.2", - "sp-inherents 2.0.0-alpha.2", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-externalities", + "sp-inherents", "sp-keyring", - "sp-runtime 2.0.0-alpha.2", - "sp-state-machine 0.8.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-runtime", + "sp-state-machine", + "sp-std", "sp-transaction-pool", - "sp-trie 2.0.0-alpha.2", - "sp-version 2.0.0-alpha.2", + "sp-trie", + "sp-version", ] [[package]] @@ -4653,19 +4618,19 @@ dependencies = [ "linked-hash-map", "log 0.4.8", "parity-scale-codec", - "parity-util-mem 0.5.2", + "parity-util-mem", "parking_lot 0.10.2", "rand 0.7.3", "sc-client", "sc-client-api", "sc-executor", "sc-state-db", - "sp-blockchain 2.0.0-alpha.2", - "sp-consensus 0.8.0-alpha.2", - "sp-core 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-state-machine 0.8.0-alpha.2", - "sp-trie 2.0.0-alpha.2", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-runtime", + "sp-state-machine", + "sp-trie", ] [[package]] @@ -4684,18 +4649,18 @@ dependencies = [ "sc-consensus-slots", "sc-keystore", "sc-telemetry", - "sp-api 2.0.0-alpha.2", - "sp-application-crypto 2.0.0-alpha.2", - "sp-block-builder 2.0.0-alpha.2", - "sp-blockchain 2.0.0-alpha.2", - "sp-consensus 0.8.0-alpha.2", + "sp-api", + "sp-application-crypto", + "sp-block-builder", + "sp-blockchain", + "sp-consensus", "sp-consensus-aura", - "sp-core 2.0.0-alpha.2", - "sp-inherents 2.0.0-alpha.2", - "sp-io 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", + "sp-core", + "sp-inherents", + "sp-io", + "sp-runtime", "sp-timestamp", - "sp-version 2.0.0-alpha.2", + "sp-version", ] [[package]] @@ -4710,13 +4675,13 @@ dependencies = [ "parking_lot 0.10.2", "sc-client-api", "sc-telemetry", - "sp-api 2.0.0-alpha.2", - "sp-blockchain 2.0.0-alpha.2", - "sp-consensus 0.8.0-alpha.2", - "sp-core 2.0.0-alpha.2", - "sp-inherents 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-state-machine 0.8.0-alpha.2", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-state-machine", ] [[package]] @@ -4733,15 +4698,15 @@ dependencies = [ "parking_lot 0.10.2", "sc-executor-common", "sc-executor-wasmi", - "sp-core 2.0.0-alpha.2", - "sp-externalities 0.8.0-alpha.2", - "sp-io 2.0.0-alpha.2", - "sp-panic-handler 2.0.0-alpha.2", - "sp-runtime-interface 2.0.0-alpha.2", + "sp-core", + "sp-externalities", + "sp-io", + "sp-panic-handler", + "sp-runtime-interface", "sp-serializer", - "sp-trie 2.0.0-alpha.2", - "sp-version 2.0.0-alpha.2", - "sp-wasm-interface 2.0.0-alpha.2", + "sp-trie", + "sp-version", + "sp-wasm-interface", "wasmi", ] @@ -4754,10 +4719,10 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "sp-allocator", - "sp-core 2.0.0-alpha.2", - "sp-runtime-interface 2.0.0-alpha.2", + "sp-core", + "sp-runtime-interface", "sp-serializer", - "sp-wasm-interface 2.0.0-alpha.2", + "sp-wasm-interface", "wasmi", ] @@ -4771,9 +4736,9 @@ dependencies = [ "parity-wasm", "sc-executor-common", "sp-allocator", - "sp-core 2.0.0-alpha.2", - "sp-runtime-interface 2.0.0-alpha.2", - "sp-wasm-interface 2.0.0-alpha.2", + "sp-core", + "sp-runtime-interface", + "sp-wasm-interface", "wasmi", ] @@ -4799,14 +4764,14 @@ dependencies = [ "sc-network-gossip", "sc-telemetry", "serde_json", - "sp-arithmetic 2.0.0-alpha.2", - "sp-blockchain 2.0.0-alpha.2", - "sp-consensus 0.8.0-alpha.2", - "sp-core 2.0.0-alpha.2", - "sp-finality-grandpa 2.0.0-alpha.2", + "sp-arithmetic", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-finality-grandpa", "sp-finality-tracker", - "sp-inherents 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", + "sp-inherents", + "sp-runtime", ] [[package]] @@ -4817,12 +4782,12 @@ dependencies = [ "ansi_term 0.12.1", "futures 0.3.4", "log 0.4.8", - "parity-util-mem 0.5.2", + "parity-util-mem", "sc-client-api", "sc-network", "sc-service", - "sp-blockchain 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", + "sp-blockchain", + "sp-runtime", "wasm-timer", ] @@ -4836,8 +4801,8 @@ dependencies = [ "parking_lot 0.10.2", "rand 0.7.3", "serde_json", - "sp-application-crypto 2.0.0-alpha.2", - "sp-core 2.0.0-alpha.2", + "sp-application-crypto", + "sp-core", "subtle 2.2.2", ] @@ -4878,12 +4843,12 @@ dependencies = [ "slog", "slog_derive", "smallvec 0.6.13", - "sp-arithmetic 2.0.0-alpha.2", - "sp-blockchain 2.0.0-alpha.2", - "sp-consensus 0.8.0-alpha.2", + "sp-arithmetic", + "sp-blockchain", + "sp-consensus", "sp-consensus-babe", - "sp-core 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", + "sp-core", + "sp-runtime", "thiserror", "unsigned-varint 0.3.2", "void", @@ -4903,7 +4868,7 @@ dependencies = [ "lru", "parking_lot 0.10.2", "sc-network", - "sp-runtime 2.0.0-alpha.2", + "sp-runtime", "wasm-timer", ] @@ -4926,10 +4891,10 @@ dependencies = [ "sc-client-api", "sc-keystore", "sc-network", - "sp-api 2.0.0-alpha.2", - "sp-core 2.0.0-alpha.2", + "sp-api", + "sp-core", "sp-offchain", - "sp-runtime 2.0.0-alpha.2", + "sp-runtime", "threadpool", ] @@ -4963,16 +4928,16 @@ dependencies = [ "sc-keystore", "sc-rpc-api", "serde_json", - "sp-api 2.0.0-alpha.2", - "sp-blockchain 2.0.0-alpha.2", - "sp-core 2.0.0-alpha.2", + "sp-api", + "sp-blockchain", + "sp-core", "sp-offchain", "sp-rpc", - "sp-runtime 2.0.0-alpha.2", + "sp-runtime", "sp-session", - "sp-state-machine 0.8.0-alpha.2", + "sp-state-machine", "sp-transaction-pool", - "sp-version 2.0.0-alpha.2", + "sp-version", ] [[package]] @@ -4991,11 +4956,11 @@ dependencies = [ "parking_lot 0.10.2", "serde", "serde_json", - "sp-core 2.0.0-alpha.2", + "sp-core", "sp-rpc", - "sp-runtime 2.0.0-alpha.2", + "sp-runtime", "sp-transaction-pool", - "sp-version 2.0.0-alpha.2", + "sp-version", ] [[package]] @@ -5010,7 +4975,7 @@ dependencies = [ "log 0.4.8", "serde", "serde_json", - "sp-runtime 2.0.0-alpha.2", + "sp-runtime", ] [[package]] @@ -5028,7 +4993,7 @@ dependencies = [ "log 0.4.8", "parity-multiaddr 0.5.0", "parity-scale-codec", - "parity-util-mem 0.5.2", + "parity-util-mem", "parking_lot 0.10.2", "prometheus-exporter", "sc-chain-spec", @@ -5047,13 +5012,13 @@ dependencies = [ "serde", "serde_json", "slog", - "sp-api 2.0.0-alpha.2", - "sp-application-crypto 2.0.0-alpha.2", - "sp-blockchain 2.0.0-alpha.2", - "sp-consensus 0.8.0-alpha.2", - "sp-core 2.0.0-alpha.2", - "sp-io 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", + "sp-api", + "sp-application-crypto", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-io", + "sp-runtime", "sp-session", "sp-transaction-pool", "sysinfo", @@ -5070,7 +5035,7 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.2", - "sp-core 2.0.0-alpha.2", + "sp-core", ] [[package]] @@ -5119,12 +5084,12 @@ dependencies = [ "futures 0.3.4", "linked-hash-map", "log 0.4.8", - "parity-util-mem 0.5.2", + "parity-util-mem", "parking_lot 0.10.2", "serde", - "sp-blockchain 2.0.0-alpha.2", - "sp-core 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", + "sp-blockchain", + "sp-core", + "sp-runtime", "sp-transaction-pool", "wasm-timer", ] @@ -5140,14 +5105,14 @@ dependencies = [ "futures-timer 2.0.2", "log 0.4.8", "parity-scale-codec", - "parity-util-mem 0.5.2", + "parity-util-mem", "parking_lot 0.10.2", "sc-client-api", "sc-transaction-graph", - "sp-api 2.0.0-alpha.2", - "sp-blockchain 2.0.0-alpha.2", - "sp-core 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-runtime", "sp-transaction-pool", "wasm-timer", ] @@ -5170,7 +5135,7 @@ checksum = "eacd8381b3c37840c9c9f40472af529e49975bdcbc24f83c31059fd6539023d3" dependencies = [ "curve25519-dalek 1.2.3", "failure", - "merlin 1.3.0", + "merlin", "rand 0.6.5", "rand_core 0.4.2", "rand_os", @@ -5179,24 +5144,6 @@ dependencies = [ "zeroize 0.9.3", ] -[[package]] -name = "schnorrkel" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862" -dependencies = [ - "arrayref", - "arrayvec 0.5.1", - "curve25519-dalek 2.0.0", - "getrandom", - "merlin 2.0.0", - "rand 0.7.3", - "rand_core 0.5.1", - "sha2", - "subtle 2.2.2", - "zeroize 1.1.0", -] - [[package]] name = "scoped-tls" version = "0.1.2" @@ -5552,9 +5499,9 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "derive_more", "log 0.4.8", - "sp-core 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", - "sp-wasm-interface 2.0.0-alpha.2", + "sp-core", + "sp-std", + "sp-wasm-interface", ] [[package]] @@ -5564,28 +5511,12 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "hash-db", "parity-scale-codec", - "sp-api-proc-macro 2.0.0-alpha.2", - "sp-core 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-state-machine 0.8.0-alpha.2", - "sp-std 2.0.0-alpha.2", - "sp-version 2.0.0-alpha.2", -] - -[[package]] -name = "sp-api" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4312c5081652e14f9c87fe6f8c765bbe63ac0ae69daeba48c2e5f7e7b7b25b" -dependencies = [ - "hash-db", - "parity-scale-codec", - "sp-api-proc-macro 2.0.0-alpha.5", - "sp-core 2.0.0-alpha.5", - "sp-runtime 2.0.0-alpha.5", - "sp-state-machine 0.8.0-alpha.5", - "sp-std 2.0.0-alpha.5", - "sp-version 2.0.0-alpha.5", + "sp-api-proc-macro", + "sp-core", + "sp-runtime", + "sp-state-machine", + "sp-std", + "sp-version", ] [[package]] @@ -5600,19 +5531,6 @@ dependencies = [ "syn 1.0.17", ] -[[package]] -name = "sp-api-proc-macro" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73a94ac1f228f99fb5279d7983f6bcde83bf1fe5824f9a56e5f7a81cc8a7069c" -dependencies = [ - "blake2-rfc", - "proc-macro-crate", - "proc-macro2 1.0.10", - "quote 1.0.3", - "syn 1.0.17", -] - [[package]] name = "sp-application-crypto" version = "2.0.0-alpha.2" @@ -5620,22 +5538,9 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "parity-scale-codec", "serde", - "sp-core 2.0.0-alpha.2", - "sp-io 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", -] - -[[package]] -name = "sp-application-crypto" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed68f0c283a01b5a8c768965b160fb4aa0a637a7e1b5e0d1168cba2f2310b348" -dependencies = [ - "parity-scale-codec", - "serde", - "sp-core 2.0.0-alpha.5", - "sp-io 2.0.0-alpha.5", - "sp-std 2.0.0-alpha.5", + "sp-core", + "sp-io", + "sp-std", ] [[package]] @@ -5647,22 +5552,8 @@ dependencies = [ "num-traits", "parity-scale-codec", "serde", - "sp-debug-derive 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", -] - -[[package]] -name = "sp-arithmetic" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d1e32dfcd4c87069d6e48d7d4a873221a8c27161a0ef5ad6ff683b591e6f97" -dependencies = [ - "integer-sqrt", - "num-traits", - "parity-scale-codec", - "serde", - "sp-debug-derive 2.0.0-alpha.5", - "sp-std 2.0.0-alpha.5", + "sp-debug-derive", + "sp-std", ] [[package]] @@ -5671,23 +5562,10 @@ version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "parity-scale-codec", - "sp-api 2.0.0-alpha.2", - "sp-inherents 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", -] - -[[package]] -name = "sp-block-builder" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb168416f8724c89877bfea4fece91087855760b6fc2957d982de5c168575b5" -dependencies = [ - "parity-scale-codec", - "sp-api 2.0.0-alpha.5", - "sp-inherents 2.0.0-alpha.5", - "sp-runtime 2.0.0-alpha.5", - "sp-std 2.0.0-alpha.5", + "sp-api", + "sp-inherents", + "sp-runtime", + "sp-std", ] [[package]] @@ -5700,27 +5578,10 @@ dependencies = [ "lru", "parity-scale-codec", "parking_lot 0.10.2", - "sp-block-builder 2.0.0-alpha.2", - "sp-consensus 0.8.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-state-machine 0.8.0-alpha.2", -] - -[[package]] -name = "sp-blockchain" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "789cf456c266dfb7d26a08f590b6e4d7644121e0d7fc3a2cd01636e1d3cef512" -dependencies = [ - "derive_more", - "log 0.4.8", - "lru", - "parity-scale-codec", - "parking_lot 0.10.2", - "sp-block-builder 2.0.0-alpha.5", - "sp-consensus 0.8.0-alpha.5", - "sp-runtime 2.0.0-alpha.5", - "sp-state-machine 0.8.0-alpha.5", + "sp-block-builder", + "sp-consensus", + "sp-runtime", + "sp-state-machine", ] [[package]] @@ -5739,10 +5600,10 @@ dependencies = [ "rlp", "serde", "serde-big-array", - "sp-api 2.0.0-alpha.2", - "sp-io 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-api", + "sp-io", + "sp-runtime", + "sp-std", "triehash", ] @@ -5760,35 +5621,12 @@ dependencies = [ "parity-scale-codec", "parking_lot 0.10.2", "serde", - "sp-core 2.0.0-alpha.2", - "sp-inherents 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-state-machine 0.8.0-alpha.2", - "sp-std 2.0.0-alpha.2", - "sp-version 2.0.0-alpha.2", -] - -[[package]] -name = "sp-consensus" -version = "0.8.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ece2291dcf8ee851df66ea0096a5301e18921e8208782ccf484694d4e50aae98" -dependencies = [ - "derive_more", - "futures 0.3.4", - "futures-diagnose", - "futures-timer 3.0.2", - "libp2p", - "log 0.4.8", - "parity-scale-codec", - "parking_lot 0.10.2", - "serde", - "sp-core 2.0.0-alpha.5", - "sp-inherents 2.0.0-alpha.5", - "sp-runtime 2.0.0-alpha.5", - "sp-state-machine 0.8.0-alpha.5", - "sp-std 2.0.0-alpha.5", - "sp-version 2.0.0-alpha.5", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-state-machine", + "sp-std", + "sp-version", ] [[package]] @@ -5797,11 +5635,11 @@ version = "0.8.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "parity-scale-codec", - "sp-api 2.0.0-alpha.2", - "sp-application-crypto 2.0.0-alpha.2", - "sp-inherents 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-api", + "sp-application-crypto", + "sp-inherents", + "sp-runtime", + "sp-std", "sp-timestamp", ] @@ -5811,13 +5649,13 @@ version = "0.8.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "parity-scale-codec", - "schnorrkel 0.8.5", - "sp-api 2.0.0-alpha.2", - "sp-application-crypto 2.0.0-alpha.2", - "sp-consensus 0.8.0-alpha.2", - "sp-inherents 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "schnorrkel", + "sp-api", + "sp-application-crypto", + "sp-consensus", + "sp-inherents", + "sp-runtime", + "sp-std", "sp-timestamp", ] @@ -5839,63 +5677,21 @@ dependencies = [ "log 0.4.8", "num-traits", "parity-scale-codec", - "parity-util-mem 0.5.2", + "parity-util-mem", "parking_lot 0.10.2", "primitive-types 0.6.2", "rand 0.7.3", "regex", "rustc-hex", - "schnorrkel 0.8.5", + "schnorrkel", "serde", "sha2", - "sp-debug-derive 2.0.0-alpha.2", - "sp-externalities 0.8.0-alpha.2", - "sp-runtime-interface 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", - "sp-storage 2.0.0-alpha.2", - "substrate-bip39 0.3.1", - "tiny-bip39", - "tiny-keccak 2.0.2", - "twox-hash", - "wasmi", - "zeroize 1.1.0", -] - -[[package]] -name = "sp-core" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7a2938aefa827fbf6dbf5c3e8eea5cc6dedafe97a28bbfb733258ee99c82c67" -dependencies = [ - "base58", - "blake2-rfc", - "byteorder 1.3.4", - "ed25519-dalek", - "futures 0.3.4", - "hash-db", - "hash256-std-hasher", - "hex", - "impl-serde 0.3.0", - "lazy_static", - "libsecp256k1", - "log 0.4.8", - "num-traits", - "parity-scale-codec", - "parity-util-mem 0.6.0", - "parking_lot 0.10.2", - "primitive-types 0.7.0", - "rand 0.7.3", - "regex", - "rustc-hex", - "schnorrkel 0.9.1", - "serde", - "sha2", - "sp-debug-derive 2.0.0-alpha.5", - "sp-externalities 0.8.0-alpha.5", - "sp-runtime-interface 2.0.0-alpha.5", - "sp-std 2.0.0-alpha.5", - "sp-storage 2.0.0-alpha.5", - "substrate-bip39 0.4.1", + "sp-debug-derive", + "sp-externalities", + "sp-runtime-interface", + "sp-std", + "sp-storage", + "substrate-bip39", "tiny-bip39", "tiny-keccak 2.0.2", "twox-hash", @@ -5913,36 +5709,14 @@ dependencies = [ "syn 1.0.17", ] -[[package]] -name = "sp-debug-derive" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "124f3ffa2d897139864715cc624811ca997ca92be8880229143c6dee801b5ab2" -dependencies = [ - "proc-macro2 1.0.10", - "quote 1.0.3", - "syn 1.0.17", -] - [[package]] name = "sp-externalities" version = "0.8.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "environmental", - "sp-std 2.0.0-alpha.2", - "sp-storage 2.0.0-alpha.2", -] - -[[package]] -name = "sp-externalities" -version = "0.8.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b3aa6665b2a1a9df50a5514597e96a7d08d69e0e7ff90d238380fb266e14622" -dependencies = [ - "environmental", - "sp-std 2.0.0-alpha.5", - "sp-storage 2.0.0-alpha.5", + "sp-std", + "sp-storage", ] [[package]] @@ -5952,24 +5726,10 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "parity-scale-codec", "serde", - "sp-api 2.0.0-alpha.2", - "sp-application-crypto 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", -] - -[[package]] -name = "sp-finality-grandpa" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9b4d96f0aa94da01d3110a20b54d8c35c419b193df6e9fa9127b2aa912afecb" -dependencies = [ - "parity-scale-codec", - "serde", - "sp-api 2.0.0-alpha.5", - "sp-application-crypto 2.0.0-alpha.5", - "sp-runtime 2.0.0-alpha.5", - "sp-std 2.0.0-alpha.5", + "sp-api", + "sp-application-crypto", + "sp-runtime", + "sp-std", ] [[package]] @@ -5978,8 +5738,8 @@ version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "parity-scale-codec", - "sp-inherents 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-inherents", + "sp-std", ] [[package]] @@ -5990,21 +5750,8 @@ dependencies = [ "derive_more", "parity-scale-codec", "parking_lot 0.10.2", - "sp-core 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", -] - -[[package]] -name = "sp-inherents" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d5ea2312969d929d617f852f9728644b98591b503a641106ee444acea4394fc" -dependencies = [ - "derive_more", - "parity-scale-codec", - "parking_lot 0.10.2", - "sp-core 2.0.0-alpha.5", - "sp-std 2.0.0-alpha.5", + "sp-core", + "sp-std", ] [[package]] @@ -6016,32 +5763,13 @@ dependencies = [ "libsecp256k1", "log 0.4.8", "parity-scale-codec", - "sp-core 2.0.0-alpha.2", - "sp-externalities 0.8.0-alpha.2", - "sp-runtime-interface 2.0.0-alpha.2", - "sp-state-machine 0.8.0-alpha.2", - "sp-std 2.0.0-alpha.2", - "sp-trie 2.0.0-alpha.2", - "sp-wasm-interface 2.0.0-alpha.2", -] - -[[package]] -name = "sp-io" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ed12cd1b0eddf5250703fff43da9e76be6cce32c492b2e2a71b4f6d9a12f49" -dependencies = [ - "hash-db", - "libsecp256k1", - "log 0.4.8", - "parity-scale-codec", - "sp-core 2.0.0-alpha.5", - "sp-externalities 0.8.0-alpha.5", - "sp-runtime-interface 2.0.0-alpha.5", - "sp-state-machine 0.8.0-alpha.5", - "sp-std 2.0.0-alpha.5", - "sp-trie 2.0.0-alpha.5", - "sp-wasm-interface 2.0.0-alpha.5", + "sp-core", + "sp-externalities", + "sp-runtime-interface", + "sp-state-machine", + "sp-std", + "sp-trie", + "sp-wasm-interface", ] [[package]] @@ -6050,8 +5778,8 @@ version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "lazy_static", - "sp-core 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", + "sp-core", + "sp-runtime", "strum", ] @@ -6060,8 +5788,8 @@ name = "sp-offchain" version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ - "sp-api 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", + "sp-api", + "sp-runtime", ] [[package]] @@ -6073,23 +5801,13 @@ dependencies = [ "log 0.4.8", ] -[[package]] -name = "sp-panic-handler" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643ae9f2dc119551342422394cdfa8bfe0a230d1adc9891fcb08cf15fdf0f703" -dependencies = [ - "backtrace", - "log 0.4.8", -] - [[package]] name = "sp-rpc" version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "serde", - "sp-core 2.0.0-alpha.2", + "sp-core", ] [[package]] @@ -6100,38 +5818,16 @@ dependencies = [ "impl-trait-for-tuples", "log 0.4.8", "parity-scale-codec", - "parity-util-mem 0.5.2", - "paste", - "rand 0.7.3", - "serde", - "sp-application-crypto 2.0.0-alpha.2", - "sp-arithmetic 2.0.0-alpha.2", - "sp-core 2.0.0-alpha.2", - "sp-inherents 2.0.0-alpha.2", - "sp-io 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", -] - -[[package]] -name = "sp-runtime" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2eb5d07f847c7420070d9dc28d810d405dc6316cd58f58548a41f0aeeca84e8" -dependencies = [ - "hash256-std-hasher", - "impl-trait-for-tuples", - "log 0.4.8", - "parity-scale-codec", - "parity-util-mem 0.6.0", + "parity-util-mem", "paste", "rand 0.7.3", "serde", - "sp-application-crypto 2.0.0-alpha.5", - "sp-arithmetic 2.0.0-alpha.5", - "sp-core 2.0.0-alpha.5", - "sp-inherents 2.0.0-alpha.5", - "sp-io 2.0.0-alpha.5", - "sp-std 2.0.0-alpha.5", + "sp-application-crypto", + "sp-arithmetic", + "sp-core", + "sp-inherents", + "sp-io", + "sp-std", ] [[package]] @@ -6141,25 +5837,10 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "parity-scale-codec", "primitive-types 0.6.2", - "sp-externalities 0.8.0-alpha.2", - "sp-runtime-interface-proc-macro 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", - "sp-wasm-interface 2.0.0-alpha.2", - "static_assertions", -] - -[[package]] -name = "sp-runtime-interface" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d25229ba01740b13368f743e866d8ee155826932c9f2c4390e4ceb7730df214" -dependencies = [ - "parity-scale-codec", - "primitive-types 0.7.0", - "sp-externalities 0.8.0-alpha.5", - "sp-runtime-interface-proc-macro 2.0.0-alpha.5", - "sp-std 2.0.0-alpha.5", - "sp-wasm-interface 2.0.0-alpha.5", + "sp-externalities", + "sp-runtime-interface-proc-macro", + "sp-std", + "sp-wasm-interface", "static_assertions", ] @@ -6175,19 +5856,6 @@ dependencies = [ "syn 1.0.17", ] -[[package]] -name = "sp-runtime-interface-proc-macro" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f1d9e32fa5db2f3dd89affbd3c97959432272c9e52e4e2610dad32dd4705784" -dependencies = [ - "Inflector", - "proc-macro-crate", - "proc-macro2 1.0.10", - "quote 1.0.3", - "syn 1.0.17", -] - [[package]] name = "sp-serializer" version = "2.0.0-alpha.2" @@ -6202,10 +5870,10 @@ name = "sp-session" version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ - "sp-api 2.0.0-alpha.2", - "sp-core 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-api", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] @@ -6214,8 +5882,8 @@ version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "parity-scale-codec", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-runtime", + "sp-std", ] [[package]] @@ -6229,30 +5897,10 @@ dependencies = [ "parity-scale-codec", "parking_lot 0.10.2", "rand 0.7.3", - "sp-core 2.0.0-alpha.2", - "sp-externalities 0.8.0-alpha.2", - "sp-panic-handler 2.0.0-alpha.2", - "sp-trie 2.0.0-alpha.2", - "trie-db", - "trie-root", -] - -[[package]] -name = "sp-state-machine" -version = "0.8.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e52a17e293be8e7a518ac6aebfc7fdafbe531b6c808a83a754e4a8730f139521" -dependencies = [ - "hash-db", - "log 0.4.8", - "num-traits", - "parity-scale-codec", - "parking_lot 0.10.2", - "rand 0.7.3", - "sp-core 2.0.0-alpha.5", - "sp-externalities 0.8.0-alpha.5", - "sp-panic-handler 2.0.0-alpha.5", - "sp-trie 2.0.0-alpha.5", + "sp-core", + "sp-externalities", + "sp-panic-handler", + "sp-trie", "trie-db", "trie-root", ] @@ -6262,12 +5910,6 @@ name = "sp-std" version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" -[[package]] -name = "sp-std" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "752e038359704226bb5737531fb91df2e4ab33214e0be6eb6f32ad688a71b411" - [[package]] name = "sp-storage" version = "2.0.0-alpha.2" @@ -6275,20 +5917,8 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "impl-serde 0.2.3", "serde", - "sp-debug-derive 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", -] - -[[package]] -name = "sp-storage" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c389a75ddd45ba771b20c4caed1011d23004069e436b73eca058d2f894585069" -dependencies = [ - "impl-serde 0.2.3", - "serde", - "sp-debug-derive 2.0.0-alpha.5", - "sp-std 2.0.0-alpha.5", + "sp-debug-derive", + "sp-std", ] [[package]] @@ -6298,10 +5928,10 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", - "sp-api 2.0.0-alpha.2", - "sp-inherents 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", + "sp-api", + "sp-inherents", + "sp-runtime", + "sp-std", "wasm-timer", ] @@ -6315,8 +5945,8 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "serde", - "sp-api 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", + "sp-api", + "sp-runtime", ] [[package]] @@ -6325,25 +5955,10 @@ version = "2.0.0-alpha.2" source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" dependencies = [ "hash-db", - "memory-db 0.19.0", + "memory-db", "parity-scale-codec", - "sp-core 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", - "trie-db", - "trie-root", -] - -[[package]] -name = "sp-trie" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f417a60d0d1222f92733deef4dffc73b21180b0cf44ec335ac73fc871198721" -dependencies = [ - "hash-db", - "memory-db 0.20.0", - "parity-scale-codec", - "sp-core 2.0.0-alpha.5", - "sp-std 2.0.0-alpha.5", + "sp-core", + "sp-std", "trie-db", "trie-root", ] @@ -6356,21 +5971,8 @@ dependencies = [ "impl-serde 0.2.3", "parity-scale-codec", "serde", - "sp-runtime 2.0.0-alpha.2", - "sp-std 2.0.0-alpha.2", -] - -[[package]] -name = "sp-version" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f7ded62b3fd6346dc7e96dcfc55f8137653809e09cfa3f0da8052efd35c875" -dependencies = [ - "impl-serde 0.2.3", - "parity-scale-codec", - "serde", - "sp-runtime 2.0.0-alpha.5", - "sp-std 2.0.0-alpha.5", + "sp-runtime", + "sp-std", ] [[package]] @@ -6380,19 +5982,7 @@ source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6ed dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", - "sp-std 2.0.0-alpha.2", - "wasmi", -] - -[[package]] -name = "sp-wasm-interface" -version = "2.0.0-alpha.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9dec817ad8e5eed83a3579da8638703d7559be5da5342312c8effee6a70aa" -dependencies = [ - "impl-trait-for-tuples", - "parity-scale-codec", - "sp-std 2.0.0-alpha.5", + "sp-std", "wasmi", ] @@ -6546,19 +6136,7 @@ checksum = "3be511be555a3633e71739a79e4ddff6a6aaa6579fa6114182a51d72c3eb93c5" dependencies = [ "hmac", "pbkdf2", - "schnorrkel 0.8.5", - "sha2", -] - -[[package]] -name = "substrate-bip39" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c004e8166d6e0aa3a9d5fa673e5b7098ff25f930de1013a21341988151e681bb" -dependencies = [ - "hmac", - "pbkdf2", - "schnorrkel 0.9.1", + "schnorrkel", "sha2", ] @@ -6576,7 +6154,7 @@ dependencies = [ "log 0.4.8", "node-primitives", "serde_json", - "sp-core 2.0.0-alpha.2", + "sp-core", "sp-rpc", "url 2.1.1", ] @@ -6600,10 +6178,10 @@ dependencies = [ "parity-scale-codec", "sc-client", "serde", - "sp-api 2.0.0-alpha.2", - "sp-blockchain 2.0.0-alpha.2", - "sp-core 2.0.0-alpha.2", - "sp-runtime 2.0.0-alpha.2", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-runtime", "sp-transaction-pool", ] diff --git a/bin/node/node/src/chain_spec.rs b/bin/node/node/src/chain_spec.rs index 0e81f7f167..c237474e34 100644 --- a/bin/node/node/src/chain_spec.rs +++ b/bin/node/node/src/chain_spec.rs @@ -16,7 +16,7 @@ use bridge_node_runtime::{ AccountId, AuraConfig, BalancesConfig, BridgeEthPoAConfig, GenesisConfig, GrandpaConfig, Signature, SudoConfig, - SystemConfig, WASM_BINARY, + SystemConfig, SessionConfig, SessionKeys, WASM_BINARY, }; use grandpa_primitives::AuthorityId as GrandpaId; use sc_service; @@ -34,6 +34,8 @@ pub type ChainSpec = sc_service::ChainSpec; pub enum Alternative { /// Whatever the current runtime is, with just Alice as an auth. Development, + /// Whatever the current runtime is, with simple Alice/Bob auths. + LocalTestnet, } /// Helper function to generate a crypto pair from seed @@ -54,8 +56,12 @@ where } /// Helper function to generate an authority key for Aura -pub fn get_authority_keys_from_seed(s: &str) -> (AuraId, GrandpaId) { - (get_from_seed::(s), get_from_seed::(s)) +pub fn get_authority_keys_from_seed(s: &str) -> (AccountId, AuraId, GrandpaId) { + ( + get_account_id_from_seed::(s), + get_from_seed::(s), + get_from_seed::(s), + ) } impl Alternative { @@ -84,19 +90,58 @@ impl Alternative { None, None, ), + Alternative::LocalTestnet => ChainSpec::from_genesis( + "Local Testnet", + "local_testnet", + || testnet_genesis( + vec![ + get_authority_keys_from_seed("Alice"), + get_authority_keys_from_seed("Bob"), + ], + get_account_id_from_seed::("Alice"), + vec![ + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Charlie"), + get_account_id_from_seed::("Dave"), + get_account_id_from_seed::("Eve"), + get_account_id_from_seed::("Ferdie"), + get_account_id_from_seed::("Alice//stash"), + get_account_id_from_seed::("Bob//stash"), + get_account_id_from_seed::("Charlie//stash"), + get_account_id_from_seed::("Dave//stash"), + get_account_id_from_seed::("Eve//stash"), + get_account_id_from_seed::("Ferdie//stash"), + ], + true, + ), + vec![], + None, + None, + None, + None + ), }) } pub(crate) fn from(s: &str) -> Option { match s { "" | "dev" => Some(Alternative::Development), + "local" => Some(Alternative::LocalTestnet), _ => None, } } } +fn session_keys( + aura: AuraId, + grandpa: GrandpaId, +) -> SessionKeys { + SessionKeys { aura, grandpa } +} + fn testnet_genesis( - initial_authorities: Vec<(AuraId, GrandpaId)>, + initial_authorities: Vec<(AccountId, AuraId, GrandpaId)>, root_key: AccountId, endowed_accounts: Vec, _enable_println: bool, @@ -110,13 +155,21 @@ fn testnet_genesis( balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(), }), pallet_aura: Some(AuraConfig { - authorities: initial_authorities.iter().map(|x| (x.0.clone())).collect(), + authorities: Vec::new(), }), pallet_bridge_eth_poa: load_kovan_config(), pallet_grandpa: Some(GrandpaConfig { - authorities: initial_authorities.iter().map(|x| (x.1.clone(), 1)).collect(), + authorities: Vec::new(), }), pallet_sudo: Some(SudoConfig { key: root_key }), + pallet_session: Some(SessionConfig { + keys: initial_authorities.iter().map(|x| { + (x.0.clone(), x.0.clone(), session_keys( + x.1.clone(), + x.2.clone(), + )) + }).collect::>(), + }), } } diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 06c8d93070..394db75e17 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -59,6 +59,12 @@ default-features = false rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" git = "https://github.com/paritytech/substrate/" +[dependencies.pallet-session] +version = "2.0.0-alpha.2" +default-features = false +rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +git = "https://github.com/paritytech/substrate/" + [dependencies.frame-system] version = "2.0.0-alpha.2" default-features = false @@ -149,6 +155,12 @@ default-features = false rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" git = "https://github.com/paritytech/substrate/" +[dependencies.sp-staking] +version = "2.0.0-alpha.2" +default-features = false +rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +git = "https://github.com/paritytech/substrate/" + [dependencies.sp-std] version = "2.0.0-alpha.2" default-features = false diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 1ec47fde80..028e7c935e 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -29,7 +29,7 @@ use pallet_grandpa::AuthorityList as GrandpaAuthorityList; use sp_api::impl_runtime_apis; use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_core::OpaqueMetadata; -use sp_runtime::traits::{BlakeTwo256, Block as BlockT, ConvertInto, IdentifyAccount, IdentityLookup, Verify}; +use sp_runtime::traits::{BlakeTwo256, Block as BlockT, ConvertInto, IdentifyAccount, IdentityLookup, Verify, OpaqueKeys}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, transaction_validity::TransactionValidity, ApplyExtrinsicResult, MultiSignature, @@ -89,12 +89,12 @@ pub mod opaque { pub type Block = generic::Block; /// Opaque block identifier type. pub type BlockId = generic::BlockId; +} - impl_opaque_keys! { - pub struct SessionKeys { - pub aura: Aura, - pub grandpa: Grandpa, - } +impl_opaque_keys! { + pub struct SessionKeys { + pub aura: Aura, + pub grandpa: Grandpa, } } @@ -233,6 +233,39 @@ impl pallet_sudo::Trait for Runtime { type Call = Call; } +parameter_types! { + pub const Period: BlockNumber = 8; + pub const Offset: BlockNumber = 0; +} + +impl pallet_session::Trait for Runtime { + type Event = Event; + type ValidatorId = ::AccountId; + type ValidatorIdOf = (); + type ShouldEndSession = pallet_session::PeriodicSessions; + type SessionManager = ShiftSessionManager; + type SessionHandler = ::KeyTypeIdProviders; + type Keys = SessionKeys; + type DisabledValidatorsThreshold = (); +} + +pub struct ShiftSessionManager; +impl pallet_session::SessionManager for ShiftSessionManager { + fn end_session(_: sp_staking::SessionIndex) {} +// fn start_session(_: sp_staking::SessionIndex) {} + fn new_session(session_index: sp_staking::SessionIndex) -> Option> { + if session_index == 0 || session_index == 1 { + return None; + } + + let mut current_validators = >::validators(); + if session_index % 2 != 0 { + current_validators.reverse(); + } + Some(current_validators) + } +} + construct_runtime!( pub enum Runtime where Block = Block, @@ -247,6 +280,7 @@ construct_runtime!( Balances: pallet_balances::{Module, Call, Storage, Config, Event}, TransactionPayment: pallet_transaction_payment::{Module, Storage}, Sudo: pallet_sudo::{Module, Call, Config, Storage, Event}, + Session: pallet_session::{Module, Call, Storage, Event, Config}, BridgeEthPoA: pallet_bridge_eth_poa::{Module, Call, Config, Storage, ValidateUnsigned}, } ); @@ -374,13 +408,13 @@ impl_runtime_apis! { impl sp_session::SessionKeys for Runtime { fn generate_session_keys(seed: Option>) -> Vec { - opaque::SessionKeys::generate(seed) + SessionKeys::generate(seed) } fn decode_session_keys( encoded: Vec, ) -> Option, sp_core::crypto::KeyTypeId)>> { - opaque::SessionKeys::decode_into_raw_public_keys(&encoded) + SessionKeys::decode_into_raw_public_keys(&encoded) } } diff --git a/modules/ethereum-contract/builtin/Cargo.toml b/modules/ethereum-contract/builtin/Cargo.toml index be2b1c7f68..07f3d2b971 100644 --- a/modules/ethereum-contract/builtin/Cargo.toml +++ b/modules/ethereum-contract/builtin/Cargo.toml @@ -10,11 +10,27 @@ edition = "2018" # General dependencies codec = { package = "parity-scale-codec", version = "1.0.0" } +ethereum-types = "0.8.0" finality-grandpa = { version = "0.11.2", features = ["derive-codec"] } -sp-blockchain = "2.0.0-alpha.5" -sp-finality-grandpa = "2.0.0-alpha.5" -sp-runtime = "2.0.0-alpha.5" +#sp-blockchain = "2.0.0-alpha.2" +#sp-finality-grandpa = "2.0.0-alpha.2" +#sp-runtime = "2.0.0-alpha.2" # Runtime/chain specific dependencies bridge-node-runtime = { path = "../../../bin/node/runtime" } + +[dependencies.sp-blockchain] +version = "2.0.0-alpha.2" +rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +git = "https://github.com/paritytech/substrate/" + +[dependencies.sp-finality-grandpa] +version = "2.0.0-alpha.2" +rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +git = "https://github.com/paritytech/substrate/" + +[dependencies.sp-runtime] +version = "2.0.0-alpha.2" +rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +git = "https://github.com/paritytech/substrate/" \ No newline at end of file diff --git a/modules/ethereum-contract/builtin/src/lib.rs b/modules/ethereum-contract/builtin/src/lib.rs index fc86d5d7ef..76e39e6d10 100644 --- a/modules/ethereum-contract/builtin/src/lib.rs +++ b/modules/ethereum-contract/builtin/src/lib.rs @@ -16,15 +16,19 @@ use bridge_node_runtime::{BlockNumber, Hash, Header as RuntimeHeader}; use codec::{Decode, Encode}; +use ethereum_types::U256; use sp_blockchain::Error as ClientError; +use sp_finality_grandpa::{AuthorityList, ConsensusLog, GRANDPA_ENGINE_ID}; /// Builtin errors. #[derive(Debug)] pub enum Error { + /// Failed to decode block number. + BlockNumberDecode, /// Failed to decode Substrate header. HeaderDecode(codec::Error), /// Failed to decode best voters set. - BestVotersDecode(codec::Error), + BestSetDecode(codec::Error), /// Failed to decode finality proof. FinalityProofDecode(codec::Error), /// Failed to verify justification. @@ -53,13 +57,17 @@ pub struct ValidatorsSetSignal { pub validators: Vec, } -/// All types of finality proofs. -#[derive(Decode, Encode)] -pub enum FinalityProof { - /// GRANDPA justification. - Justification(Vec), - /// GRANDPA commit. - Commit(Vec), +/// Convert from U256 to BlockNumber. +pub fn to_substrate_block_number(number: U256) -> Result { + match number == number.low_u32().into() { + true => Ok(number.low_u32()), + false => Err(Error::BlockNumberDecode), + } +} + +/// Convert from BlockNumber to U256. +pub fn from_substrate_block_number(number: BlockNumber) -> Result { + Ok(U256::from(number as u64)) } /// Parse Substrate header. @@ -69,20 +77,188 @@ pub fn parse_substrate_header(raw_header: &[u8]) -> Result { hash: header.hash(), parent_hash: header.parent_hash, number: header.number, - signal: None, // TODO: parse me + signal: sp_runtime::traits::Header::digest(&header) + .log(|log| { + log.as_consensus().and_then(|(engine_id, log)| { + if engine_id == GRANDPA_ENGINE_ID { + Some(log) + } else { + None + } + }) + }) + .and_then(|log| ConsensusLog::decode(&mut &log[..]).ok()) + .and_then(|log| match log { + ConsensusLog::ScheduledChange(scheduled_change) => Some(ValidatorsSetSignal { + delay: scheduled_change.delay, + validators: scheduled_change.next_authorities.encode(), + }), + _ => None, + }), }) .map_err(Error::HeaderDecode) } /// Verify GRANDPA finality proof. pub fn verify_substrate_finality_proof( - _best_set_id: u64, - _raw_best_voters: &[u8], - _raw_best_header: &[u8], - _raw_headers: &[&[u8]], - _raw_finality_proof: &[u8], -) -> Result<(usize, usize), Error> { - Err(Error::JustificationVerify(ClientError::Msg( - "Not yet implemented".into(), - ))) // TODO: implement me + finality_target_number: BlockNumber, + finality_target_hash: Hash, + best_set_id: u64, + raw_best_set: &[u8], + raw_finality_proof: &[u8], +) -> Result<(), Error> { + // TODO: accept other types of finality proof (Commit) + let best_set = AuthorityList::decode(&mut &raw_best_set[..]).map_err(Error::BestSetDecode)?; + + substrate::GrandpaJustification::decode_and_verify_finalizes( + &raw_finality_proof, + (finality_target_hash, finality_target_number), + best_set_id, + &best_set.into_iter().collect(), + ) + .map_err(Error::JustificationVerify) + .map(|_| ()) +} + +/// ================================================================================================================== +/// === Everything below should be (?) exposed by Substrate ========================================================== +/// ================================================================================================================== + +mod substrate { + use bridge_node_runtime::{BlockNumber, Hash, Header as RuntimeHeader}; + use codec::{Decode, Encode}; + use finality_grandpa::voter_set::VoterSet; + use sp_blockchain::Error as ClientError; + use sp_finality_grandpa::{AuthorityId, AuthoritySignature}; + use std::collections::HashMap; + + /// A commit message for this chain's block type. + pub type Commit = finality_grandpa::Commit; + + /// GRANDPA justification. + #[derive(Encode, Decode)] + pub struct GrandpaJustification { + pub round: u64, + pub commit: Commit, + pub votes_ancestries: Vec, + } + + impl GrandpaJustification { + /// Decode a GRANDPA justification and validate the commit and the votes' + /// ancestry proofs finalize the given block. + pub(crate) fn decode_and_verify_finalizes( + encoded: &[u8], + finalized_target: (Hash, BlockNumber), + set_id: u64, + voters: &VoterSet, + ) -> Result { + let justification = + GrandpaJustification::decode(&mut &*encoded).map_err(|_| ClientError::JustificationDecode)?; + + if (justification.commit.target_hash, justification.commit.target_number) != finalized_target { + let msg = format!("invalid commit target in grandpa justification: {:?} != {:?}", (justification.commit.target_hash, justification.commit.target_number), finalized_target); + Err(ClientError::BadJustification(msg)) + } else { + justification.verify(set_id, voters).map(|_| justification) + } + } + + /// Validate the commit and the votes' ancestry proofs. + pub(crate) fn verify(&self, _set_id: u64, voters: &VoterSet) -> Result<(), ClientError> { + // use finality_grandpa::Chain; + + let ancestry_chain = AncestryChain::new(&self.votes_ancestries); + + match finality_grandpa::validate_commit(&self.commit, voters, &ancestry_chain) { + Ok(ref result) if result.ghost().is_some() => {} + _ => { + let msg = "invalid commit in grandpa justification".to_string(); + return Err(ClientError::BadJustification(msg)); + } + } + /* TODO + let mut buf = Vec::new(); + let mut visited_hashes = HashSet::new(); + for signed in self.commit.precommits.iter() { + if let Err(_) = communication::check_message_sig_with_buffer::( + &finality_grandpa::Message::Precommit(signed.precommit.clone()), + &signed.id, + &signed.signature, + self.round, + set_id, + &mut buf, + ) { + return Err(ClientError::BadJustification( + "invalid signature for precommit in grandpa justification".to_string()).into()); + } + if self.commit.target_hash == signed.precommit.target_hash { + continue; + } + match ancestry_chain.ancestry(self.commit.target_hash, signed.precommit.target_hash) { + Ok(route) => { + // ancestry starts from parent hash but the precommit target hash has been visited + visited_hashes.insert(signed.precommit.target_hash); + for hash in route { + visited_hashes.insert(hash); + } + }, + _ => { + return Err(ClientError::BadJustification( + "invalid precommit ancestry proof in grandpa justification".to_string()).into()); + }, + } + } + let ancestry_hashes = self.votes_ancestries + .iter() + .map(|h: &Block::Header| h.hash()) + .collect(); + if visited_hashes != ancestry_hashes { + return Err(ClientError::BadJustification( + "invalid precommit ancestries in grandpa justification with unused headers".to_string()).into()); + } + */ + Ok(()) + } + } + + /// A utility trait implementing `finality_grandpa::Chain` using a given set of headers. + /// This is useful when validating commits, using the given set of headers to + /// verify a valid ancestry route to the target commit block. + struct AncestryChain { + ancestry: HashMap, + } + + impl AncestryChain { + fn new(ancestry: &[RuntimeHeader]) -> AncestryChain { + let ancestry: HashMap<_, _> = ancestry.iter().cloned().map(|h: RuntimeHeader| (h.hash(), h)).collect(); + + AncestryChain { ancestry } + } + } + + impl finality_grandpa::Chain for AncestryChain { + fn ancestry(&self, base: Hash, block: Hash) -> Result, finality_grandpa::Error> { + let mut route = Vec::new(); + let mut current_hash = block; + loop { + if current_hash == base { + break; + } + match self.ancestry.get(¤t_hash) { + Some(current_header) => { + current_hash = current_header.parent_hash; + route.push(current_hash); + } + _ => return Err(finality_grandpa::Error::NotDescendent), + } + } + route.pop(); // remove the base + + Ok(route) + } + + fn best_chain_containing(&self, _block: Hash) -> Option<(Hash, BlockNumber)> { + None + } + } } diff --git a/modules/ethereum-contract/contracts/substrate-bridge.sol b/modules/ethereum-contract/contracts/substrate-bridge.sol index befd358c70..1f6b7e8fe4 100644 --- a/modules/ethereum-contract/contracts/substrate-bridge.sol +++ b/modules/ethereum-contract/contracts/substrate-bridge.sol @@ -108,15 +108,14 @@ contract SubstrateBridge { return headerByHash[headerHash].isKnown; } - /// Returns true if finality proof is required for this header. - function isFinalityProofRequired( - bytes32 headerHash - ) public view returns (bool) { - Header storage header = headerByHash[headerHash]; - return header.isKnown - && header.number > bestFinalizedHeaderNumber - && header.number == header.prevSignalTargetNumber - && header.validatorsSetId == bestFinalizedValidatorsSetId; + /// Returns numbers of headers that require finality proofs. + function incompleteHeaders() public view returns (uint256[] memory, bytes32[] memory) { + uint256 incompleteHeadersCount = incompleteHeadersHashes.length; + uint256[] memory incompleteHeadersNumbers = new uint256[](incompleteHeadersCount); + for (uint256 i = 0; i < incompleteHeadersCount; ++i) { + incompleteHeadersNumbers[i] = headerByHash[incompleteHeadersHashes[i]].number; + } + return (incompleteHeadersNumbers, incompleteHeadersHashes); } /// Import header. @@ -127,7 +126,7 @@ contract SubstrateBridge { ParsedHeader memory header = parseSubstrateHeader(rawHeader); Header storage parentHeader = headerByHash[header.parentHash]; require( - parentHeader.number == header.number - 1, + parentHeader.isKnown && parentHeader.number == header.number - 1, "Missing parent header from the storage" ); @@ -158,6 +157,27 @@ contract SubstrateBridge { validatorsSetId = validatorsSetId + 1; } + // remember if we need finality proof for this header + if (prevSignalTargetNumber == header.number) { + // TODO: + // + // In current implementation any submitter may submit any (invalid) block B that signals validators + // set change in N blocks. This would require relay to ask Substrate node for finality proof and + // submit it here, if it exists. So by spamming contract with signal headers, malicious submitter + // can significantly slow down sync just because actual block that will need finality proof will + // be waiting in the relay queue to be processed + incompleteHeadersNumbers may grow without any + // limits. + // + // One solution would be to have reputation system - initially you may submit only one block-with-signal + // (or you may submit it only once every N blocks). When your block-with-signal is finalized, your + // reputation is increased and you may submit multiple blocks-with-signals (and they got priority in + // the queue), but with every submitted block-with-signal, it decreases. This should cause honest + // competition for block-with-signal 'slots' even if malicious submitters are present. + uint256 incompleteHeaderHashIndex = incompleteHeadersHashes.length; + incompleteHeadersHashes.push(header.hash); + incompleteHeadersIndices[header.hash] = incompleteHeaderHashIndex + 1; + } + // store header in the storage headerByHash[header.hash] = Header({ isKnown: true, @@ -188,6 +208,8 @@ contract SubstrateBridge { bytes32 newBestFinalizedHeaderHash = verifyFinalityProof( finalityTargetNumber, finalityTargetHash, + bestFinalizedValidatorsSetId, + bestFinalizedValidatorsSet, rawFinalityProof ); @@ -198,8 +220,29 @@ contract SubstrateBridge { // apply validators set change signal if required while (newBestFinalizedHeaderHash != oldBestFinalizedHeaderHash) { - newFinalizedHeader = headerByHash[newBestFinalizedHeaderHash]; + bytes32 finalizingHeader = newBestFinalizedHeaderHash; + newFinalizedHeader = headerByHash[finalizingHeader]; newBestFinalizedHeaderHash = newFinalizedHeader.parentHash; + + // swap_remove from incomplete headers, if required + uint256 incompleteHeaderIndex = incompleteHeadersIndices[finalizingHeader]; + if (incompleteHeaderIndex != 0) { + // shift by -1 to get actual array index + incompleteHeaderIndex = incompleteHeaderIndex - 1; + + // if it isn't the last element, swap with last element + uint256 incompleteHeadersCount = incompleteHeadersHashes.length; + if (incompleteHeaderIndex != incompleteHeadersCount - 1) { + bytes32 lastIncompleHeaderHash = incompleteHeadersHashes[incompleteHeadersCount - 1]; + incompleteHeadersHashes[incompleteHeaderIndex] = lastIncompleHeaderHash; + incompleteHeadersIndices[lastIncompleHeaderHash] = incompleteHeaderIndex; + } + + // remove last element from array and index from mapping + incompleteHeadersHashes.pop(); + delete incompleteHeadersIndices[finalizingHeader]; + } + // if we are finalizing header that should enact validators set change, do this // (this only affects latest scheduled change) if (newFinalizedHeader.number == newFinalizedHeader.prevSignalTargetNumber) { @@ -220,7 +263,6 @@ contract SubstrateBridge { uint256 headerNumber; uint256 headerSignalDelay; uint256 headerSignalSize; - bytes memory headerSignal; assembly { // inputs @@ -255,13 +297,12 @@ contract SubstrateBridge { } // if validators set change is signalled, read it + bytes memory headerSignal = new bytes(headerSignalSize); if (headerSignalSize != 0) { - headerSignal = new bytes(headerSignalSize); - assembly { // inputs - let rawHeadersSize := mload(rawHeader) - let rawHeadersPointer := add(rawHeader, 0x20) + let rawHeaderSize := mload(rawHeader) + let rawHeaderPointer := add(rawHeader, 0x20) // output let headerSignalPointer := add(headerSignal, 0x20) @@ -270,8 +311,8 @@ contract SubstrateBridge { if iszero(staticcall( not(0), SUBSTRATE_GET_HEADER_SIGNAL_BUILTIN_ADDRESS, - rawHeadersPointer, - rawHeadersSize, + rawHeaderPointer, + rawHeaderSize, headerSignalPointer, headerSignalSize )) { @@ -291,18 +332,49 @@ contract SubstrateBridge { /// Verify finality proof. + /// @return Hash of the new best finalized header. function verifyFinalityProof( - uint256 /*finalityTargetNumber*/, - bytes32 /*finalityTargetHash*/, - bytes memory /*rawFinalityProof*/ + uint256 finalityTargetNumber, + bytes32 finalityTargetHash, + uint64 bestSetId, + bytes memory rawBestSet, + bytes memory rawFinalityProof ) private view returns (bytes32) { - return bestFinalizedHeaderHash; // TODO: call builtin instead + bytes memory encodedArgs = abi.encode( + finalityTargetNumber, + finalityTargetHash, + bestSetId, + rawBestSet, + rawFinalityProof + ); + + assembly { + // inputs + let encodedArgsSize := mload(encodedArgs) + let encodedArgsPointer := add(encodedArgs, 0x20) + + // verify finality proof + if iszero(staticcall( + not(0), + SUBSTRATE_VERIFY_FINALITY_PROOF_BUILTIN_ADDRESS, + encodedArgsPointer, + encodedArgsSize, + 0x00, + 0x00 + )) { + revert(0, 0) + } + } + + return finalityTargetHash; } /// Address of parse_substrate_header builtin. uint256 constant SUBSTRATE_PARSE_HEADER_BUILTIN_ADDRESS = 0x10; /// Address of get_substrate_validators_set_signal builtin. uint256 constant SUBSTRATE_GET_HEADER_SIGNAL_BUILTIN_ADDRESS = 0x11; + /// Address of verify_substrate_finality_proof builtin. + uint256 constant SUBSTRATE_VERIFY_FINALITY_PROOF_BUILTIN_ADDRESS = 0x12; /// Last imported header hash. bytes32 lastImportedHeaderHash; @@ -316,6 +388,11 @@ contract SubstrateBridge { /// Best finalized validators set. bytes bestFinalizedValidatorsSet; + /// Hashes of headers that require finality proof. + bytes32[] incompleteHeadersHashes; + /// Map of the incomplete header hash => index+1 within incompleteHeadersHashes. + mapping (bytes32 => uint256) incompleteHeadersIndices; + /// Map of headers by their hashes. mapping (bytes32 => Header) headerByHash; } diff --git a/relays/ethereum/res/substrate-bridge.json b/relays/ethereum/res/substrate-bridge.json index 4ff57ab656..bd65f6b792 100644 --- a/relays/ethereum/res/substrate-bridge.json +++ b/relays/ethereum/res/substrate-bridge.json @@ -79,19 +79,18 @@ "type": "function" }, { - "inputs": [ - { - "internalType": "bytes32", - "name": "headerHash", - "type": "bytes32" - } - ], - "name": "isFinalityProofRequired", + "inputs": [], + "name": "incompleteHeaders", "outputs": [ { - "internalType": "bool", + "internalType": "uint256[]", "name": "", - "type": "bool" + "type": "uint256[]" + }, + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" } ], "stateMutability": "view", diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index 8bf17e41e8..17daf3a2bf 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -15,7 +15,7 @@ // along with Parity Bridges Common. If not, see . use crate::ethereum_types::{Address, Bytes, EthereumHeaderId, Header, Receipt, H256, U256, U64}; -use crate::substrate_types::{Hash as SubstrateHash, QueuedSubstrateHeader, SubstrateHeaderId}; +use crate::substrate_types::{Hash as SubstrateHash, QueuedSubstrateHeader, SubstrateHeaderId, GrandpaJustification}; use crate::sync_types::{HeaderId, MaybeConnectionError}; use crate::{bail_on_arg_error, bail_on_error}; use codec::{Decode, Encode}; @@ -26,6 +26,7 @@ use jsonrpsee::transport::http::{HttpTransportClient, RequestError}; use parity_crypto::publickey::KeyPair; use serde::{de::DeserializeOwned, Serialize}; use serde_json::{from_value, to_value}; +use std::collections::HashSet; // to encode/decode contract calls ethabi_contract::use_contract!(bridge_contract, "res/substrate-bridge.json"); @@ -302,6 +303,66 @@ pub async fn submit_substrate_headers( (client, Ok((tx_hashes, ids))) } +/// Returns ids of incomplete Substrate headers. +pub async fn incomplete_substrate_headers( + client: Client, + contract_address: Address, +) -> (Client, Result, Error>) { + let (encoded_call, call_decoder) = bridge_contract::functions::incomplete_headers::call(); + let call_request = bail_on_arg_error!( + to_value(CallRequest { + to: Some(contract_address), + data: Some(encoded_call.into()), + }) + .map_err(|e| Error::RequestSerialization(e)), + client + ); + let (client, call_result) = + bail_on_error!(call_rpc::(client, "eth_call", Params::Array(vec![call_request]),).await); + match call_decoder.decode(&call_result.0) { + Ok((incomplete_headers_numbers, incomplete_headers_hashes)) => (client, Ok( + incomplete_headers_numbers.into_iter() + .zip(incomplete_headers_hashes) + .filter_map(|(number, hash)| { + if number != number.low_u32().into() { + return None; + } + + Some(HeaderId(number.low_u32(), hash)) + }) + .collect(), + )), + Err(error) => (client, Err(Error::ResponseParseFailed(format!("{}", error)))), + } +} + +/// Complete Substrate header. +pub async fn complete_substrate_header( + client: Client, + params: EthereumSigningParams, + contract_address: Address, + id: SubstrateHeaderId, + justification: GrandpaJustification, +) -> (Client, Result<(H256, SubstrateHeaderId), Error>) { + let (client, tx_hash) = bail_on_error!( + submit_ethereum_transaction( + client, + ¶ms, + Some(contract_address), + None, + false, + bridge_contract::functions::import_finality_proof::encode_input( + id.0, + id.1, + justification, + ), + ) + .await + ); + + (client, Ok((tx_hash, id))) +} + /// Deploy bridge contract. pub async fn deploy_bridge_contract( client: Client, diff --git a/relays/ethereum/src/ethereum_deploy_contract.rs b/relays/ethereum/src/ethereum_deploy_contract.rs index 935b7c335a..6215d9feac 100644 --- a/relays/ethereum/src/ethereum_deploy_contract.rs +++ b/relays/ethereum/src/ethereum_deploy_contract.rs @@ -45,7 +45,7 @@ impl Default for EthereumDeployContractParams { eth: Default::default(), eth_sign: Default::default(), // compiler: 0.6.6+commit.6c089d02 + optimization - eth_contract_code: hex::decode("60806040523480156200001157600080fd5b5060405162000dfa38038062000dfa833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b506040818152602083015192018051929491939192846401000000008211156200010f57600080fd5b9083019060208201858111156200012557600080fd5b82516401000000008111828201881017156200014057600080fd5b82525081516020918201929091019080838360005b838110156200016f57818101518382015260200162000155565b50505050905090810190601f1680156200019d5780820380516001836020036101000a031916815260200191505b50604052505050620001ae620003d4565b620001c2846001600160e01b03620002dc16565b805160008181556002918255604080840180516001908155825160e08101845281815260208088015181830190815293518286019081526080808a0151606085019081526001600160401b038e169185019190915260a0840188905260c084018890528951885260058352959096208251815460ff191690151517815593519284019290925593519482019490945590518051949550919390926200026f92600385019291019062000409565b506080820151600482810180546001600160401b03199081166001600160401b039485161790915560a0850151600585015560c09094015160069093019290925560038054909316908616179091558251620002d19190602085019062000409565b5050505050620004ae565b620002e6620003d4565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa6200031e57600080fd5b93519251915190519351929b50909950975090955093505082159050620003a757816001600160401b03811180156200035657600080fd5b506040519080825280601f01601f19166020018201604052801562000382576020820181803683370190505b50905087516020890160208301848184846011600019fa620003a357600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200044c57805160ff19168380011785556200047c565b828001600101855582156200047c579182015b828111156200047c5782518255916020019190600101906200045f565b506200048a9291506200048e565b5090565b620004ab91905b808211156200048a576000815560010162000495565b90565b61093c80620004be6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063871ebe181461005c578063a98bfaad1461008d578063d96a2deb146100aa578063e7af0779146100cb578063fae71ae814610173575b600080fd5b6100796004803603602081101561007257600080fd5b5035610225565b604080519115158252519081900360200190f35b610079600480360360208110156100a357600080fd5b503561023a565b6100b2610297565b6040805192835260208301919091528051918290030190f35b610171600480360360208110156100e157600080fd5b8101906020810181356401000000008111156100fc57600080fd5b82018360208201111561010e57600080fd5b8035906020019184600183028401116401000000008311171561013057600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506102af945050505050565b005b6101716004803603606081101561018957600080fd5b8135916020810135918101906060810160408201356401000000008111156101b057600080fd5b8201836020820111156101c257600080fd5b803590602001918460018302840111640100000000831117156101e457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610521945050505050565b60009081526005602052604090205460ff1690565b6000818152600560205260408120805460ff16801561025e57506001548160020154115b8015610271575080600601548160020154145b80156102905750600354600482015467ffffffffffffffff9081169116145b9392505050565b60008054808252600560205260409091206002015491565b6102b761073b565b6102c08261063f565b905060006005600083602001518152602001908152602001600020905060018260400151038160020154146103265760405162461bcd60e51b81526004018080602001828103825260268152602001806108816026913960400191505060405180910390fd5b600681015415801590610340575080600201548160060154145b15610389578160200151600254146103895760405162461bcd60e51b81526004018080602001828103825260318152602001806108d66031913960400191505060405180910390fd5b6006810154608083015151156103fe57826040015181106103f1576040805162461bcd60e51b815260206004820152601960248201527f4f7665726c617070696e67207369676e616c7320666f756e6400000000000000604482015290519081900360640190fd5b5060608201516040830151015b60048201546005830154600384015467ffffffffffffffff90921691600260001960018316156101000201909116041561043f575060208401516001909101905b6040805160e0810182526001808252602088810151818401908152898501518486019081526080808c01516060870190815267ffffffffffffffff8a169187019190915260a0860188905260c086018a90528b51600090815260058552969096208551815460ff19169015151781559151938201939093559151600283015592518051929391926104d69260038501920190610770565b50608082015160048201805467ffffffffffffffff191667ffffffffffffffff90921691909117905560a0820151600582015560c09091015160069091015550509151600055505050565b60008281526005602052604090206002015483146105705760405162461bcd60e51b815260040180806020018281038252602f8152602001806108a7602f913960400191505060405180910390fd5b6002546000610580858585610731565b600081815260056020526040902060028281558101546001559091505b828214610637575060009081526005602052604090206001810154600682015460028301549192911415610632576005818101546000908152602091909152604090206003805467ffffffffffffffff198116600167ffffffffffffffff9283168101909216178255908201805461062b9260049291600261010092821615929092026000190116046107ee565b5050610637565b61059d565b505050505050565b61064761073b565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa61067e57600080fd5b93519251915190519351929b50909950975090955093505082159050610704578167ffffffffffffffff811180156106b557600080fd5b506040519080825280601f01601f1916602001820160405280156106e0576020820181803683370190505b50905087516020890160208301848184846011600019fa61070057600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6002549392505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106107b157805160ff19168380011785556107de565b828001600101855582156107de579182015b828111156107de5782518255916020019190600101906107c3565b506107ea929150610863565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061082757805485556107de565b828001600101855582156107de57600052602060002091601f016020900482015b828111156107de578254825591600101919060010190610848565b61087d91905b808211156107ea5760008155600101610869565b9056fe4d697373696e6720706172656e74206865616465722066726f6d207468652073746f726167654d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f726167654d697373696e672072657175697265642066696e616c6974792070726f6f6620666f7220706172656e7420686561646572a2646970667358221220920ca01b59940884722a766076b4f1d1d825eba446e530980bd310f776703dad64736f6c63430006060033") + eth_contract_code: hex::decode("60806040523480156200001157600080fd5b506040516200120238038062001202833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b506040818152602083015192018051929491939192846401000000008211156200010f57600080fd5b9083019060208201858111156200012557600080fd5b82516401000000008111828201881017156200014057600080fd5b82525081516020918201929091019080838360005b838110156200016f57818101518382015260200162000155565b50505050905090810190601f1680156200019d5780820380516001836020036101000a031916815260200191505b50604052505050620001ae620003d5565b620001c2846001600160e01b03620002dc16565b805160008181556002918255604080840180516001908155825160e08101845281815260208088015181830190815293518286019081526080808a0151606085019081526001600160401b038e169185019190915260a0840188905260c084018890528951885260078352959096208251815460ff191690151517815593519284019290925593519482019490945590518051949550919390926200026f9260038501929101906200040a565b506080820151600482810180546001600160401b03199081166001600160401b039485161790915560a0850151600585015560c09094015160069093019290925560038054909316908616179091558251620002d1919060208501906200040a565b5050505050620004af565b620002e6620003d5565b60008060008060008651602088016040516020810160208101602081016020810160a08588886010600019fa6200031c57600080fd5b84519b5083519a50825199508151985080519750505050505050506060816001600160401b03811180156200035057600080fd5b506040519080825280601f01601f1916602001820160405280156200037c576020820181803683370190505b5090508115620003a85787516020890160208301848184846011600019fa620003a457600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200044d57805160ff19168380011785556200047d565b828001600101855582156200047d579182015b828111156200047d57825182559160200191906001019062000460565b506200048b9291506200048f565b5090565b620004ac91905b808211156200048b576000815560010162000496565b90565b610d4380620004bf6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063374c2c261461005c578063871ebe18146100fd578063d96a2deb1461012e578063e7af07791461014f578063fae71ae8146101f7575b600080fd5b6100646102a9565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156100a8578181015183820152602001610090565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156100e75781810151838201526020016100cf565b5050505090500194505050505060405180910390f35b61011a6004803603602081101561011357600080fd5b50356103ae565b604080519115158252519081900360200190f35b6101366103c3565b6040805192835260208301919091528051918290030190f35b6101f56004803603602081101561016557600080fd5b81019060208101813564010000000081111561018057600080fd5b82018360208201111561019257600080fd5b803590602001918460018302840111640100000000831117156101b457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506103db945050505050565b005b6101f56004803603606081101561020d57600080fd5b81359160208101359181019060608101604082013564010000000081111561023457600080fd5b82018360208201111561024657600080fd5b8035906020019184600183028401116401000000008311171561026857600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506106a8945050505050565b6005546060908190818167ffffffffffffffff811180156102c957600080fd5b506040519080825280602002602001820160405280156102f3578160200160208202803683370190505b50905060005b8281101561034e57600760006005838154811061031257fe5b906000526020600020015481526020019081526020016000206002015482828151811061033b57fe5b60209081029190910101526001016102f9565b508060058080548060200260200160405190810160405280929190818152602001828054801561039d57602002820191906000526020600020905b815481526020019060010190808311610389575b505050505090509350935050509091565b60009081526007602052604090205460ff1690565b60008054808252600760205260409091206002015491565b6103e3610b42565b6103ec8261090d565b602080820151600090815260079091526040902080549192509060ff16801561041f575060018260400151038160020154145b61045a5760405162461bcd60e51b8152600401808060200182810382526026815260200180610c886026913960400191505060405180910390fd5b600681015415801590610474575080600201548160060154145b156104bd578160200151600254146104bd5760405162461bcd60e51b8152600401808060200182810382526031815260200180610cdd6031913960400191505060405180910390fd5b6006810154608083015151156105325782604001518110610525576040805162461bcd60e51b815260206004820152601960248201527f4f7665726c617070696e67207369676e616c7320666f756e6400000000000000604482015290519081900360640190fd5b5060608201516040830151015b60048201546005830154600384015467ffffffffffffffff909216916002600019600183161561010002019091160415610573575060208401516001909101905b84604001518314156105c6576005805486516001820180845560009384527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0909201558651825260066020526040909120555b6040805160e0810182526001808252602088810151818401908152898501518486019081526080808c01516060870190815267ffffffffffffffff8a169187019190915260a0860188905260c086018a90528b51600090815260078552969096208551815460ff191690151517815591519382019390935591516002830155925180519293919261065d9260038501920190610b77565b50608082015160048201805467ffffffffffffffff191667ffffffffffffffff90921691909117905560a0820151600582015560c09091015160069091015550509151600055505050565b60008281526007602052604090206002015483146106f75760405162461bcd60e51b815260040180806020018281038252602f815260200180610cae602f913960400191505060405180910390fd5b60028054600354600480546040805160206101006001851615026000190190931696909604601f810183900483028701830190915280865293946000946107a8948a948a9467ffffffffffffffff9092169392909183018282801561079d5780601f106107725761010080835404028352916020019161079d565b820191906000526020600020905b81548152906001019060200180831161078057829003601f168201915b505050505087610a00565b600081815260076020526040902060028281558101546001559091505b828214610905575060008181526007602090815260408083206001810154600690935292205490929080156108875760055460001991820191810182146108535760006005600183038154811061081857fe5b90600052602060002001549050806005848154811061083357fe5b600091825260208083209091019290925591825260069052604090208290555b600580548061085e57fe5b600082815260208082208301600019908101839055909201909255848252600690526040812055505b8260060154836002015414156108fe57600583015460009081526007602052604090206003805467ffffffffffffffff198116600167ffffffffffffffff928316810190921617825590820180546108f5926004929160026101009282161592909202600019011604610bf5565b50505050610905565b50506107c5565b505050505050565b610915610b42565b60008060008060008651602088016040516020810160208101602081016020810160a08588886010600019fa61094a57600080fd5b84519b5083519a508251995081519850805197505050505050505060608167ffffffffffffffff8111801561097e57600080fd5b506040519080825280601f01601f1916602001820160405280156109a9576020820181803683370190505b50905081156109d35787516020890160208301848184846011600019fa6109cf57600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b600060608686868686604051602001808681526020018581526020018467ffffffffffffffff1667ffffffffffffffff1681526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015610a73578181015183820152602001610a5b565b50505050905090810190601f168015610aa05780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015610ad3578181015183820152602001610abb565b50505050905090810190601f168015610b005780820380516001836020036101000a031916815260200191505b50975050505050505050604051602081830303815290604052905080516020820160008083836012600019fa610b3557600080fd5b5095979650505050505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610bb857805160ff1916838001178555610be5565b82800160010185558215610be5579182015b82811115610be5578251825591602001919060010190610bca565b50610bf1929150610c6a565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610c2e5780548555610be5565b82800160010185558215610be557600052602060002091601f016020900482015b82811115610be5578254825591600101919060010190610c4f565b610c8491905b80821115610bf15760008155600101610c70565b9056fe4d697373696e6720706172656e74206865616465722066726f6d207468652073746f726167654d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f726167654d697373696e672072657175697265642066696e616c6974792070726f6f6620666f7220706172656e7420686561646572a264697066735822122034edec1aca7ff06bb5846092314f1aea2738d1856546c4fea9ede700d0ae364864736f6c63430006060033") .expect("code is hardcoded, thus valid; qed"), sub: Default::default(), sub_initial_authorities_set_id: None, diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index 414c1c21f6..a74163b405 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -14,13 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +//! Ethereum PoA -> Substrate synchronization. + use crate::ethereum_client::{self, EthereumConnectionParams}; use crate::ethereum_types::{EthereumHeaderId, EthereumHeadersSyncPipeline, Header, QueuedEthereumHeader, Receipt}; use crate::substrate_client::{self, SubstrateConnectionParams, SubstrateSigningParams}; use crate::sync::{HeadersSyncParams, TargetTransactionMode}; use crate::sync_loop::{SourceClient, TargetClient}; -use futures::future::{ready, FutureExt, Ready}; -use std::{future::Future, pin::Pin}; +use futures::future::{FutureExt, Ready, ready}; +use std::{collections::HashSet, future::Future, pin::Pin}; use web3::types::H256; /// Interval (in ms) at which we check new Ethereum headers when we are synced/almost synced. @@ -69,9 +71,9 @@ impl SourceClient for EthereumHeadersSource { type BestBlockNumberFuture = Pin)>>>; type HeaderByHashFuture = Pin)>>>; type HeaderByNumberFuture = Pin)>>>; - type HeaderAsyncExtraFuture = Ready<(Self, Result<(EthereumHeaderId, Option<()>), Self::Error>)>; type HeaderExtraFuture = Pin), Self::Error>)>>>; + type HeaderCompletionFuture = Ready<(Self, Result<(EthereumHeaderId, Option<()>), Self::Error>)>; fn best_block_number(self) -> Self::BestBlockNumberFuture { ethereum_client::best_block_number(self.client) @@ -91,15 +93,15 @@ impl SourceClient for EthereumHeadersSource { .boxed() } - fn header_async_extra(self, id: EthereumHeaderId) -> Self::HeaderAsyncExtraFuture { - ready((self, Ok((id, Some(()))))) - } - fn header_extra(self, id: EthereumHeaderId, header: &Header) -> Self::HeaderExtraFuture { ethereum_client::transactions_receipts(self.client, id, header.transactions.clone()) .map(|(client, result)| (EthereumHeadersSource { client }, result)) .boxed() } + + fn header_completion(self, id: EthereumHeaderId) -> Self::HeaderCompletionFuture { + ready((self, Ok((id, None)))) + } } /// Substrate client as Ethereum headers target. @@ -116,9 +118,10 @@ impl TargetClient for SubstrateHeadersTarget { type Error = substrate_client::Error; type BestHeaderIdFuture = Pin)>>>; type IsKnownHeaderFuture = Pin)>>>; - type RequiresAsyncExtraFuture = Ready<(Self, Result<(EthereumHeaderId, bool), Self::Error>)>; type RequiresExtraFuture = Pin)>>>; type SubmitHeadersFuture = Pin, Self::Error>)>>>; + type IncompleteHeadersFuture = Ready<(Self, Result, Self::Error>)>; + type CompleteHeadersFuture = Ready<(Self, Result)>; fn best_header_id(self) -> Self::BestHeaderIdFuture { let (sign_transactions, sign_params) = (self.sign_transactions, self.sign_params); @@ -152,10 +155,6 @@ impl TargetClient for SubstrateHeadersTarget { .boxed() } - fn requires_async_extra(self, id: EthereumHeaderId) -> Self::RequiresAsyncExtraFuture { - ready((self, Ok((id, false)))) - } - fn requires_extra(self, header: &QueuedEthereumHeader) -> Self::RequiresExtraFuture { // we can minimize number of receipts_check calls by checking header // logs bloom here, but it may give us false positives (when authorities @@ -190,6 +189,14 @@ impl TargetClient for SubstrateHeadersTarget { }) .boxed() } + + fn incomplete_headers_ids(self) -> Self::IncompleteHeadersFuture { + ready((self, Ok(HashSet::new()))) + } + + fn complete_header(self, id: EthereumHeaderId, _completion: ()) -> Self::CompleteHeadersFuture { + ready((self, Ok(id))) + } } /// Run Ethereum headers synchronization. diff --git a/relays/ethereum/src/ethereum_types.rs b/relays/ethereum/src/ethereum_types.rs index 12ae6354dd..4079921e4d 100644 --- a/relays/ethereum/src/ethereum_types.rs +++ b/relays/ethereum/src/ethereum_types.rs @@ -52,8 +52,8 @@ impl HeadersSyncPipeline for EthereumHeadersSyncPipeline { type Hash = H256; type Number = u64; type Header = Header; - type AsyncExtra = (); type Extra = Vec; + type Completion = (); fn estimate_size(source: &QueuedHeader) -> usize { into_substrate_ethereum_header(source.header()).encode().len() diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index 0e34b9a98f..37559a1abd 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -15,9 +15,13 @@ // along with Parity Bridges Common. If not, see . use crate::sync_types::{HeaderId, HeaderStatus, HeadersSyncPipeline, QueuedHeader, SourceHeader}; +use linked_hash_map::LinkedHashMap; use num_traits::{One, Zero}; -use std::collections::{ - btree_map::Entry as BTreeMapEntry, hash_map::Entry as HashMapEntry, BTreeMap, HashMap, HashSet, +use std::{ + collections::{ + btree_map::Entry as BTreeMapEntry, hash_map::Entry as HashMapEntry, BTreeMap, HashMap, HashSet, + }, + time::{Duration, Instant}, }; type HeadersQueue

= @@ -25,6 +29,11 @@ type HeadersQueue

= type KnownHeaders

= BTreeMap<

::Number, HashMap<

::Hash, HeaderStatus>>; +/// TODO +const RETRY_FETCH_COMPLETION_INTERVAL: Duration = Duration::from_millis(60_000); +/// TODO +const RETRY_COMPLETION_INTERVAL: Duration = Duration::from_millis(60_000); + /// Ethereum headers queue. #[derive(Debug)] pub struct QueuedHeaders { @@ -43,16 +52,34 @@ pub struct QueuedHeaders { extra: HeadersQueue

, /// Headers that are ready to be submitted to target node. ready: HeadersQueue

, + /// Headers that are ready to be submitted to target node, but their ancestor is incomplete. + /// Thus we're waiting for these ancestors to be completed first. + /// Note that the incomplete header itself is synced and it isn't in this queue. + incomplete: HeadersQueue

, /// Headers that are (we believe) currently submitted to target node by our, /// not-yet mined transactions. submitted: HeadersQueue

, /// Pointers to all headers that we ever seen and we believe we can touch in the future. known_headers: KnownHeaders

, + /// Headers that are waiting for completion data from source node. Mapped (and auto-sorted + /// by) to the last fetch time. + incomplete_headers: LinkedHashMap, Option>, + /// Headers that are waiting to be completed at target node. Auto-sorted by last upload time. + completion_data: LinkedHashMap, HeaderCompletion>, /// Pruned blocks border. We do not store or accept any blocks with number less than /// this number. prune_border: P::Number, } +/// Header completion data. +#[derive(Debug)] +struct HeaderCompletion { + /// Last time when we tried to upload completion data to target node, if ever. + pub last_upload_time: Option, + /// Completion data. + pub completion: Completion, +} + impl QueuedHeaders

{ /// Returns new QueuedHeaders. pub fn new() -> Self { @@ -62,8 +89,11 @@ impl QueuedHeaders

{ maybe_extra: HeadersQueue::new(), extra: HeadersQueue::new(), ready: HeadersQueue::new(), + incomplete: HeadersQueue::new(), submitted: HeadersQueue::new(), known_headers: KnownHeaders::

::new(), + incomplete_headers: LinkedHashMap::new(), + completion_data: LinkedHashMap::new(), prune_border: Zero::zero(), } } @@ -89,6 +119,7 @@ impl QueuedHeaders

{ .fold(0, |total, headers| total + headers.len()), HeaderStatus::Extra => self.extra.values().fold(0, |total, headers| total + headers.len()), HeaderStatus::Ready => self.ready.values().fold(0, |total, headers| total + headers.len()), + HeaderStatus::Incomplete => self.incomplete.values().fold(0, |total, headers| total + headers.len()), HeaderStatus::Submitted => self.submitted.values().fold(0, |total, headers| total + headers.len()), } } @@ -105,10 +136,12 @@ impl QueuedHeaders

{ .fold(0, |total, headers| total + headers.len()) + self.extra.values().fold(0, |total, headers| total + headers.len()) + self.ready.values().fold(0, |total, headers| total + headers.len()) + + self.incomplete.values().fold(0, |total, headers| total + headers.len()) } /// Returns number of best block in the queue. pub fn best_queued_number(&self) -> P::Number { + // TODO: move submitted headers back to ready/incomplete periodically std::cmp::max( self.maybe_orphan.keys().next_back().cloned().unwrap_or_else(Zero::zero), std::cmp::max( @@ -119,7 +152,10 @@ impl QueuedHeaders

{ self.extra.keys().next_back().cloned().unwrap_or_else(Zero::zero), std::cmp::max( self.ready.keys().next_back().cloned().unwrap_or_else(Zero::zero), - self.submitted.keys().next_back().cloned().unwrap_or_else(Zero::zero), + std::cmp::max( + self.incomplete.keys().next_back().cloned().unwrap_or_else(Zero::zero), + self.submitted.keys().next_back().cloned().unwrap_or_else(Zero::zero), + ), ), ), ), @@ -145,6 +181,7 @@ impl QueuedHeaders

{ HeaderStatus::MaybeExtra => oldest_header(&self.maybe_extra), HeaderStatus::Extra => oldest_header(&self.extra), HeaderStatus::Ready => oldest_header(&self.ready), + HeaderStatus::Incomplete => oldest_header(&self.incomplete), HeaderStatus::Submitted => oldest_header(&self.submitted), } } @@ -162,6 +199,7 @@ impl QueuedHeaders

{ HeaderStatus::MaybeExtra => oldest_headers(&self.maybe_extra, f), HeaderStatus::Extra => oldest_headers(&self.extra, f), HeaderStatus::Ready => oldest_headers(&self.ready, f), + HeaderStatus::Incomplete => oldest_headers(&self.incomplete, f), HeaderStatus::Submitted => oldest_headers(&self.submitted, f), } } @@ -207,6 +245,7 @@ impl QueuedHeaders

{ HeaderStatus::MaybeExtra | HeaderStatus::Extra | HeaderStatus::Ready + | HeaderStatus::Incomplete | HeaderStatus::Submitted | HeaderStatus::Synced => { insert_header(&mut self.maybe_extra, id, header); @@ -226,67 +265,7 @@ impl QueuedHeaders

{ /// Receive best header from the target node. pub fn target_best_header_response(&mut self, id: &HeaderId) { - // all ancestors of this header are now synced => let's remove them from - // queues - let mut current = *id; - let mut id_processed = false; - loop { - let header = match self.status(¤t) { - HeaderStatus::Unknown => break, - HeaderStatus::MaybeOrphan => remove_header(&mut self.maybe_orphan, ¤t), - HeaderStatus::Orphan => remove_header(&mut self.orphan, ¤t), - HeaderStatus::MaybeExtra => remove_header(&mut self.maybe_extra, ¤t), - HeaderStatus::Extra => remove_header(&mut self.extra, ¤t), - HeaderStatus::Ready => remove_header(&mut self.ready, ¤t), - HeaderStatus::Submitted => remove_header(&mut self.submitted, ¤t), - HeaderStatus::Synced => break, - } - .expect("header has a given status; given queue has the header; qed"); - - log::debug!( - target: "bridge", - "{} header {:?} is now {:?}", - P::SOURCE_NAME, - current, - HeaderStatus::Synced, - ); - *self - .known_headers - .entry(current.0) - .or_default() - .entry(current.1) - .or_insert(HeaderStatus::Synced) = HeaderStatus::Synced; - current = header.parent_id(); - id_processed = true; - } - - // remember that the header is synced - if !id_processed { - // to avoid duplicate log message - log::debug!( - target: "bridge", - "{} header {:?} is now {:?}", - P::SOURCE_NAME, - id, - HeaderStatus::Synced, - ); - *self - .known_headers - .entry(id.0) - .or_default() - .entry(id.1) - .or_insert(HeaderStatus::Synced) = HeaderStatus::Synced; - } - - // now let's move all descendants from maybe_orphan && orphan queues to - // maybe_extra queue - move_header_descendants::

( - &mut [&mut self.maybe_orphan, &mut self.orphan], - &mut self.maybe_extra, - &mut self.known_headers, - HeaderStatus::MaybeExtra, - id, - ); + self.header_synced(id) } /// Receive target node response for MaybeOrphan request. @@ -315,6 +294,8 @@ impl QueuedHeaders

{ pub fn maybe_extra_response(&mut self, id: &HeaderId, response: bool) { let (destination_status, destination_queue) = if response { (HeaderStatus::Extra, &mut self.extra) + } else if self.is_parent_incomplete(id) { + (HeaderStatus::Incomplete, &mut self.incomplete) } else { (HeaderStatus::Ready, &mut self.ready) }; @@ -331,17 +312,48 @@ impl QueuedHeaders

{ /// Receive extra from source node. pub fn extra_response(&mut self, id: &HeaderId, extra: P::Extra) { + let (destination_status, destination_queue) = if self.is_parent_incomplete(id) { + (HeaderStatus::Incomplete, &mut self.incomplete) + } else { + (HeaderStatus::Ready, &mut self.ready) + }; + // move header itself from extra to ready queue move_header( &mut self.extra, - &mut self.ready, + destination_queue, &mut self.known_headers, - HeaderStatus::Ready, + destination_status, id, |header| header.set_extra(extra), ); } + /// Receive completion response from source node. + pub fn completion_response(&mut self, id: &HeaderId, completion: Option) { + let completion = match completion { + Some(completion) => completion, + None => return, // we'll try refetch later + }; + + if let Some(_) = self.incomplete_headers.remove(id) { + log::debug!( + target: "bridge", + "Received completion data from {} for header: {:?}", + P::SOURCE_NAME, + id, + ); + + self.completion_data.insert( + id.clone(), + HeaderCompletion { + last_upload_time: None, + completion, + }, + ); + } + } + /// When header is submitted to target node. pub fn headers_submitted(&mut self, ids: Vec>) { for id in ids { @@ -356,6 +368,116 @@ impl QueuedHeaders

{ } } + /// When header completion data is sent to target node. + pub fn header_completed(&mut self, id: &HeaderId) { + if let Some(mut incomplete_header) = self.completion_data.remove(id) { + log::debug!( + target: "bridge", + "Sent completion data to {} for header: {:?}", + P::TARGET_NAME, + id, + ); + + incomplete_header.last_upload_time = Some(Instant::now()); + + // reinsert it to maintain sorting + self.completion_data.insert(id.clone(), incomplete_header); + } + } + + /// When incomplete headers ids are receved from target node. + pub fn incomplete_headers_response(&mut self, ids: HashSet>) { + // all new incomplete headers are marked Synced and all their descendants + // are moved from Ready/Submitted to Incomplete queue + let new_incomplete_headers = ids + .iter() + .filter(|id| !self.incomplete_headers.contains_key(id) && !self.completion_data.contains_key(id)) + .cloned() + .collect::>(); + for new_incomplete_header in new_incomplete_headers { + self.header_synced(&new_incomplete_header); + move_header_descendants::

( + &mut [&mut self.ready, &mut self.submitted], + &mut self.incomplete, + &mut self.known_headers, + HeaderStatus::Incomplete, + &new_incomplete_header, + ); + + log::debug!( + target: "bridge", + "Scheduling completion data retrieval for header: {:?}", + new_incomplete_header, + ); + + self.incomplete_headers.insert(new_incomplete_header, None); + } + + // for all headers that were incompleted previously, but now are completed, we move + // all descendants from incomplete to ready + let just_completed_headers = self.incomplete_headers.keys() + .chain(self.completion_data.keys()) + .filter(|id| !ids.contains(id)) + .cloned() + .collect::>(); + for just_completed_header in just_completed_headers { + move_header_descendants::

( + &mut [&mut self.incomplete], + &mut self.ready, + &mut self.known_headers, + HeaderStatus::Ready, + &just_completed_header, + ); + + log::debug!( + target: "bridge", + "Completion data is no more required for header: {:?}", + just_completed_header, + ); + + self.incomplete_headers.remove(&just_completed_header); + self.completion_data.remove(&just_completed_header); + } + } + + /// Returns id of the header for which we want to fetch completion data. + pub fn incomplete_header(&mut self) -> Option> { + queued_incomplete_header( + &mut self.incomplete_headers, + |last_fetch_time| { + let retry = match *last_fetch_time { + Some(last_fetch_time) => last_fetch_time.elapsed() > RETRY_FETCH_COMPLETION_INTERVAL, + None => true, + }; + + if retry { + *last_fetch_time = Some(Instant::now()); + } + + retry + }, + ).map(|(id, _)| id) + } + + /// Returns header completion data to upload to target node. + pub fn header_to_complete(&mut self) -> Option<(HeaderId, &P::Completion)> { + queued_incomplete_header( + &mut self.completion_data, + |incomplete_header| { + let retry = match incomplete_header.last_upload_time { + Some(last_upload_time) => last_upload_time.elapsed() > RETRY_COMPLETION_INTERVAL, + None => true, + }; + + if retry { + incomplete_header.last_upload_time = Some(Instant::now()); + } + + retry + }, + ).map(|(id, data)| (id, &data.completion)) + } + /// Prune and never accep headers before this block. pub fn prune(&mut self, prune_border: P::Number) { if prune_border <= self.prune_border { @@ -368,6 +490,7 @@ impl QueuedHeaders

{ prune_queue(&mut self.extra, prune_border); prune_queue(&mut self.ready, prune_border); prune_queue(&mut self.submitted, prune_border); + prune_queue(&mut self.submitted, prune_border); prune_known_headers::

(&mut self.known_headers, prune_border); self.prune_border = prune_border; } @@ -379,10 +502,81 @@ impl QueuedHeaders

{ self.maybe_extra.clear(); self.extra.clear(); self.ready.clear(); + self.incomplete.clear(); self.submitted.clear(); self.known_headers.clear(); self.prune_border = Zero::zero(); } + + /// Returns true if parent of this header is either incomplete or waiting for + /// its own incomplete ancestor to be completed. + fn is_parent_incomplete(&self, id: &HeaderId) -> bool { + let status = self.status(id); + let header = match status { + HeaderStatus::MaybeOrphan => header(&self.maybe_orphan, id), + HeaderStatus::Orphan => header(&self.orphan, id), + HeaderStatus::MaybeExtra => header(&self.maybe_extra, id), + HeaderStatus::Extra => header(&self.extra, id), + HeaderStatus::Ready => header(&self.ready, id), + HeaderStatus::Incomplete => header(&self.incomplete, id), + HeaderStatus::Submitted => header(&self.submitted, id), + HeaderStatus::Unknown => return false, + HeaderStatus::Synced => return false, + }; + + match header { + Some(header) => { + let parent_id = header.header().parent_id(); + self.incomplete_headers.contains_key(&parent_id) + || self.completion_data.contains_key(&parent_id) + || self.status(&parent_id) == HeaderStatus::Incomplete + }, + None => false, + } + } + + /// When we receive new Synced header from target node. + fn header_synced(&mut self, id: &HeaderId) { + // all ancestors of this header are now synced => let's remove them from + // queues + let mut current = *id; + let mut id_processed = false; + loop { + let header = match self.status(¤t) { + HeaderStatus::Unknown => break, + HeaderStatus::MaybeOrphan => remove_header(&mut self.maybe_orphan, ¤t), + HeaderStatus::Orphan => remove_header(&mut self.orphan, ¤t), + HeaderStatus::MaybeExtra => remove_header(&mut self.maybe_extra, ¤t), + HeaderStatus::Extra => remove_header(&mut self.extra, ¤t), + HeaderStatus::Ready => remove_header(&mut self.ready, ¤t), + HeaderStatus::Incomplete => remove_header(&mut self.incomplete, ¤t), + HeaderStatus::Submitted => remove_header(&mut self.submitted, ¤t), + HeaderStatus::Synced => break, + } + .expect("header has a given status; given queue has the header; qed"); + + set_header_status::

(&mut self.known_headers, ¤t, HeaderStatus::Synced); + + current = header.parent_id(); + id_processed = true; + } + + // remember that the header itself is synced + // (condition is here to avoid duplicate log messages) + if !id_processed { + set_header_status::

(&mut self.known_headers, &id, HeaderStatus::Synced); + } + + // now let's move all descendants from maybe_orphan && orphan queues to + // maybe_extra queue + move_header_descendants::

( + &mut [&mut self.maybe_orphan, &mut self.orphan], + &mut self.maybe_extra, + &mut self.known_headers, + HeaderStatus::MaybeExtra, + id, + ); + } } /// Insert header to the queue. @@ -411,6 +605,14 @@ fn remove_header( header } +/// Get header from the qeueue. +fn header<'a, P: HeadersSyncPipeline>( + queue: &'a HeadersQueue

, + id: &HeaderId, +) -> Option<&'a QueuedHeader

> { + queue.get(&id.0).and_then(|by_hash| by_hash.get(&id.1)) +} + /// Move header from source to destination queue. /// /// Returns ID of parent header, if header has been moved, or None otherwise. @@ -428,16 +630,8 @@ fn move_header( }; let parent_id = header.header().parent_id(); - known_headers.entry(id.0).or_default().insert(id.1, destination_status); destination_queue.entry(id.0).or_default().insert(id.1, header); - - log::debug!( - target: "bridge", - "{} header {:?} is now {:?}", - P::SOURCE_NAME, - id, - destination_status, - ); + set_header_status::

(known_headers, id, destination_status); Some(parent_id) } @@ -473,19 +667,8 @@ fn move_header_descendants( if current_parents.contains(&entry.get().header().parent_id().1) { let header_to_move = entry.remove(); let header_to_move_id = header_to_move.id(); - known_headers - .entry(header_to_move_id.0) - .or_default() - .insert(header_to_move_id.1, destination_status); headers_to_move.push((header_to_move_id, header_to_move)); - - log::debug!( - target: "bridge", - "{} header {:?} is now {:?}", - P::SOURCE_NAME, - header_to_move_id, - destination_status, - ); + set_header_status::

(known_headers, &header_to_move_id, destination_status); } } @@ -544,6 +727,53 @@ fn prune_known_headers(known_headers: &mut KnownHeaders< *known_headers = new_known_headers; } +/// Change header status. +fn set_header_status( + known_headers: &mut KnownHeaders

, + id: &HeaderId, + status: HeaderStatus, +) { + log::debug!( + target: "bridge", + "{} header {:?} is now {:?}", + P::SOURCE_NAME, + id, + status, + ); + *known_headers + .entry(id.0) + .or_default() + .entry(id.1) + .or_insert(status) = status; +} + +/// Returns queued imcomplete header with maximal elapsed time since last update. +fn queued_incomplete_header( + map: &mut LinkedHashMap, + filter: impl FnMut(&mut T) -> bool, +) -> Option<(Id, &T)> { + // TODO: headers that have been just appended to the end of the queue would have to wait until + // all previous headers will be retried + + let retry_old_header = map + .front() + .map(|(key, _)| key.clone()) + .and_then(|key| map + .get_mut(&key) + .map(filter) + ) + .unwrap_or(false); + if retry_old_header { + let (header_key, header) = map.pop_front().expect("we have checked that front() exists; qed"); + map.insert(header_key, header); + return map + .back() + .map(|(id, data)| (id.clone(), data)); + } + + None +} + #[cfg(test)] pub(crate) mod tests { use super::*; diff --git a/relays/ethereum/src/substrate_client.rs b/relays/ethereum/src/substrate_client.rs index 3a7f314410..d82dc9186e 100644 --- a/relays/ethereum/src/substrate_client.rs +++ b/relays/ethereum/src/substrate_client.rs @@ -16,8 +16,8 @@ use crate::ethereum_types::{Bytes, EthereumHeaderId, QueuedEthereumHeader, H256}; use crate::substrate_types::{ - into_substrate_ethereum_header, into_substrate_ethereum_receipts, Hash, Header as SubstrateHeader, Justification, - Number, TransactionHash, + into_substrate_ethereum_header, into_substrate_ethereum_receipts, Hash, Header as SubstrateHeader, Number, + GrandpaJustification, SubstrateHeaderId, TransactionHash, SignedBlock as SignedSubstrateBlock, }; use crate::sync_types::{HeaderId, MaybeConnectionError, SourceHeader}; use crate::{bail_on_arg_error, bail_on_error}; @@ -129,11 +129,6 @@ pub async fn header_by_number(client: Client, number: Number) -> (Client, Result header_by_hash(client, hash).await } -/// Returns justification for Substrate header. -pub async fn justification(client: Client, _hash: Hash) -> (Client, Result, Error>) { - (client, Ok(Some(vec![42]))) // TODO: implement me -} - /// Returns best Ethereum block that Substrate runtime knows of. pub async fn best_ethereum_block(client: Client) -> (Client, Result) { let (client, result) = call_rpc( @@ -285,6 +280,19 @@ pub async fn submit_unsigned_ethereum_headers( (client, Ok((transactions_hashes, ids))) } +/// Get GRANDPA justification for given block. +pub async fn grandpa_justification(client: Client, id: SubstrateHeaderId) -> (Client, Result<(SubstrateHeaderId, Option), Error>) { + let hash = bail_on_arg_error!(to_value(id.1).map_err(|e| Error::RequestSerialization(e)), client); + let (client, signed_block) = call_rpc( + client, + "chain_getBlock", + Params::Array(vec![hash]), + rpc_returns_value, + ) + .await; + (client, signed_block.map(|signed_block: SignedSubstrateBlock| (id, signed_block.justification))) +} + /// Get GRANDPA authorities set at given block. pub async fn grandpa_authorities_set(client: Client, block: Hash) -> (Client, Result, Error>) { let block = bail_on_arg_error!(to_value(block).map_err(|e| Error::RequestSerialization(e)), client); diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index 7fcbc177b9..83e2e3a41b 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -14,17 +14,20 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +//! Substrate -> Ethereum synchronization. + use crate::ethereum_client::{self, EthereumConnectionParams, EthereumSigningParams}; use crate::ethereum_types::Address; use crate::substrate_client::{self, SubstrateConnectionParams}; use crate::substrate_types::{ - Hash, Header, Justification, Number, QueuedSubstrateHeader, SubstrateHeaderId, SubstrateHeadersSyncPipeline, + Hash, Header, Number, QueuedSubstrateHeader, SubstrateHeaderId, SubstrateHeadersSyncPipeline, + GrandpaJustification, }; use crate::sync::{HeadersSyncParams, TargetTransactionMode}; use crate::sync_loop::{SourceClient, TargetClient}; use crate::sync_types::SourceHeader; use futures::future::{ready, FutureExt, Ready}; -use std::{future::Future, pin::Pin}; +use std::{collections::HashSet, future::Future, pin::Pin}; /// Interval (in ms) at which we check new Substrate headers when we are synced/almost synced. const SUBSTRATE_TICK_INTERVAL_MS: u64 = 10_000; @@ -80,9 +83,8 @@ impl SourceClient for SubstrateHeadersSource { type BestBlockNumberFuture = Pin)>>>; type HeaderByHashFuture = Pin)>>>; type HeaderByNumberFuture = Pin)>>>; - type HeaderAsyncExtraFuture = - Pin), Self::Error>)>>>; type HeaderExtraFuture = Ready<(Self, Result<(SubstrateHeaderId, ()), Self::Error>)>; + type HeaderCompletionFuture = Pin), Self::Error>)>>>; fn best_block_number(self) -> Self::BestBlockNumberFuture { substrate_client::best_header(self.client) @@ -102,20 +104,15 @@ impl SourceClient for SubstrateHeadersSource { .boxed() } - fn header_async_extra(self, id: SubstrateHeaderId) -> Self::HeaderAsyncExtraFuture { - substrate_client::justification(self.client, id.1) - .map(move |(client, result)| { - ( - SubstrateHeadersSource { client }, - result.map(|justification| (id, justification)), - ) - }) - .boxed() - } - fn header_extra(self, id: SubstrateHeaderId, _header: &Header) -> Self::HeaderExtraFuture { ready((self, Ok((id, ())))) } + + fn header_completion(self, id: SubstrateHeaderId) -> Self::HeaderCompletionFuture { + substrate_client::grandpa_justification(self.client, id) + .map(|(client, result)| (SubstrateHeadersSource { client }, result)) + .boxed() + } } /// Ethereum client as Substrate headers target. @@ -132,10 +129,10 @@ impl TargetClient for EthereumHeadersTarget { type Error = ethereum_client::Error; type BestHeaderIdFuture = Pin)>>>; type IsKnownHeaderFuture = Pin)>>>; - type RequiresAsyncExtraFuture = - Pin)>>>; type RequiresExtraFuture = Ready<(Self, Result<(SubstrateHeaderId, bool), Self::Error>)>; type SubmitHeadersFuture = Pin, Self::Error>)>>>; + type IncompleteHeadersFuture = Pin, Self::Error>)>>>; + type CompleteHeadersFuture = Pin)>>>; fn best_header_id(self) -> Self::BestHeaderIdFuture { let (contract, sign_params) = (self.contract, self.sign_params); @@ -169,10 +166,6 @@ impl TargetClient for EthereumHeadersTarget { .boxed() } - fn requires_async_extra(self, id: SubstrateHeaderId) -> Self::RequiresAsyncExtraFuture { - ready((self, Ok((id, false)))).boxed() // TODO: actual impl - } - fn requires_extra(self, header: &QueuedSubstrateHeader) -> Self::RequiresExtraFuture { ready((self, Ok((header.header().id(), false)))) } @@ -192,6 +185,38 @@ impl TargetClient for EthereumHeadersTarget { }) .boxed() } + + fn incomplete_headers_ids(self) -> Self::IncompleteHeadersFuture { + let (contract, sign_params) = (self.contract, self.sign_params); + ethereum_client::incomplete_substrate_headers(self.client, contract) + .map(move |(client, result)| { + ( + EthereumHeadersTarget { + client, + contract, + sign_params, + }, + result, + ) + }) + .boxed() + } + + fn complete_header(self, id: SubstrateHeaderId, completion: GrandpaJustification) -> Self::CompleteHeadersFuture { + let (contract, sign_params) = (self.contract, self.sign_params); + ethereum_client::complete_substrate_header(self.client, sign_params.clone(), contract, id, completion) + .map(move |(client, result)| { + ( + EthereumHeadersTarget { + client, + contract, + sign_params, + }, + result.map(|(_, id)| id), + ) + }) + .boxed() + } } /// Run Substrate headers synchronization. diff --git a/relays/ethereum/src/substrate_types.rs b/relays/ethereum/src/substrate_types.rs index 1cfa7384d6..a4cd723a5d 100644 --- a/relays/ethereum/src/substrate_types.rs +++ b/relays/ethereum/src/substrate_types.rs @@ -36,8 +36,11 @@ pub type Number = bridge_node_runtime::BlockNumber; /// Substrate header type. pub type Header = bridge_node_runtime::Header; -/// Substrate justification type. -pub type Justification = Vec; +/// Substrate signed block type. +pub type SignedBlock = bridge_node_runtime::SignedBlock; + +/// GRANDPA justification. +pub type GrandpaJustification = Vec; /// Substrate header ID. pub type SubstrateHeaderId = HeaderId; @@ -57,8 +60,8 @@ impl HeadersSyncPipeline for SubstrateHeadersSyncPipeline { type Hash = bridge_node_runtime::Hash; type Number = bridge_node_runtime::BlockNumber; type Header = Header; - type AsyncExtra = Justification; type Extra = (); + type Completion = GrandpaJustification; fn estimate_size(_source: &QueuedHeader) -> usize { // we may only submit Substrate headers wit finality proof diff --git a/relays/ethereum/src/sync_loop.rs b/relays/ethereum/src/sync_loop.rs index 785e1608c5..b6357a2900 100644 --- a/relays/ethereum/src/sync_loop.rs +++ b/relays/ethereum/src/sync_loop.rs @@ -18,7 +18,7 @@ use crate::sync::HeadersSyncParams; use crate::sync_types::{HeaderId, HeaderStatus, HeadersSyncPipeline, MaybeConnectionError, QueuedHeader}; use futures::{future::FutureExt, stream::StreamExt}; use num_traits::{Saturating, Zero}; -use std::future::Future; +use std::{collections::HashSet, future::Future}; /// When we submit headers to target node, but see no updates of best /// source block known to target node during STALL_SYNC_TIMEOUT_MS milliseconds, @@ -48,15 +48,10 @@ pub trait SourceClient: Sized { type HeaderByHashFuture: Future)>; /// Future that returns header by number. type HeaderByNumberFuture: Future)>; - /// Future that returns async extra data associated with header. - type HeaderAsyncExtraFuture: Future< - Output = ( - Self, - Result<(HeaderId, Option), Self::Error>, - ), - >; /// Future that returns extra data associated with header. type HeaderExtraFuture: Future, P::Extra), Self::Error>)>; + /// Future that returns data required to 'complete' header. + type HeaderCompletionFuture: Future, Option), Self::Error>)>; /// Get best block number. fn best_block_number(self) -> Self::BestBlockNumberFuture; @@ -64,10 +59,10 @@ pub trait SourceClient: Sized { fn header_by_hash(self, hash: P::Hash) -> Self::HeaderByHashFuture; /// Get canonical header by number. fn header_by_number(self, number: P::Number) -> Self::HeaderByNumberFuture; - /// Get async extra data by header hash. - fn header_async_extra(self, id: HeaderId) -> Self::HeaderAsyncExtraFuture; /// Get extra data by header hash. fn header_extra(self, id: HeaderId, header: &P::Header) -> Self::HeaderExtraFuture; + /// Get completion data by header hash. + fn header_completion(self, id: HeaderId) -> Self::HeaderCompletionFuture; } /// Target client trait. @@ -78,23 +73,27 @@ pub trait TargetClient: Sized { type BestHeaderIdFuture: Future, Self::Error>)>; /// Future that returns known header check result. type IsKnownHeaderFuture: Future, bool), Self::Error>)>; - /// Future that returns async extra check result. - type RequiresAsyncExtraFuture: Future, bool), Self::Error>)>; /// Future that returns extra check result. type RequiresExtraFuture: Future, bool), Self::Error>)>; /// Future that returns header submission result. type SubmitHeadersFuture: Future>, Self::Error>)>; + /// Future that returns incomplete headers ids. + type IncompleteHeadersFuture: Future>, Self::Error>)>; + /// Future that returns header completion result. + type CompleteHeadersFuture: Future, Self::Error>)>; /// Returns ID of best header known to the target node. fn best_header_id(self) -> Self::BestHeaderIdFuture; /// Returns true if header is known to the target node. fn is_known_header(self, id: HeaderId) -> Self::IsKnownHeaderFuture; - /// Returns true if header requires async extra data to be submitted. - fn requires_async_extra(self, id: HeaderId) -> Self::RequiresAsyncExtraFuture; /// Returns true if header requires extra data to be submitted. fn requires_extra(self, header: &QueuedHeader

) -> Self::RequiresExtraFuture; /// Submit headers. fn submit_headers(self, headers: Vec>) -> Self::SubmitHeadersFuture; + /// Returns ID of headers that require to be 'completed' before children can be submitted. + fn incomplete_headers_ids(self) -> Self::IncompleteHeadersFuture; + /// Submit completion data for header. + fn complete_header(self, id: HeaderId, completion: P::Completion) -> Self::CompleteHeadersFuture; } /// Run headers synchronization. @@ -119,15 +118,19 @@ pub fn run( let source_new_header_future = futures::future::Fuse::terminated(); let source_orphan_header_future = futures::future::Fuse::terminated(); let source_extra_future = futures::future::Fuse::terminated(); + let source_completion_future = futures::future::Fuse::terminated(); let source_go_offline_future = futures::future::Fuse::terminated(); let source_tick_stream = interval(source_tick_ms).fuse(); let mut target_maybe_client = None; let mut target_best_block_required = false; + let mut target_incomplete_headers_required = true; let target_best_block_future = target_client.best_header_id().fuse(); + let target_incomplete_headers_future = futures::future::Fuse::terminated(); let target_extra_check_future = futures::future::Fuse::terminated(); let target_existence_status_future = futures::future::Fuse::terminated(); let target_submit_header_future = futures::future::Fuse::terminated(); + let target_complete_header_future = futures::future::Fuse::terminated(); let target_go_offline_future = futures::future::Fuse::terminated(); let target_tick_stream = interval(target_tick_ms).fuse(); @@ -136,12 +139,15 @@ pub fn run( source_new_header_future, source_orphan_header_future, source_extra_future, + source_completion_future, source_go_offline_future, source_tick_stream, target_best_block_future, + target_incomplete_headers_future, target_extra_check_future, target_existence_status_future, target_submit_header_future, + target_complete_header_future, target_go_offline_future, target_tick_stream ); @@ -194,6 +200,17 @@ pub fn run( || format!("Error retrieving extra data from {} node", P::SOURCE_NAME), ); }, + (source_client, source_completion) = source_completion_future => { + process_future_result( + &mut source_maybe_client, + source_client, + source_completion, + |(header, completion)| sync.headers_mut().completion_response(&header, completion), + &mut source_go_offline_future, + |source_client| delay(CONNECTION_ERROR_DELAY_MS, source_client), + || format!("Error retrieving completion data from {} node", P::SOURCE_NAME), + ); + }, source_client = source_go_offline_future => { source_maybe_client = Some(source_client); }, @@ -248,6 +265,19 @@ pub fn run( || format!("Error retrieving best known header from {} node", P::TARGET_NAME), ); }, + (target_client, incomplete_headers_ids) = target_incomplete_headers_future => { + target_incomplete_headers_required = false; + + process_future_result( + &mut target_maybe_client, + target_client, + incomplete_headers_ids, + |incomplete_headers_ids| sync.headers_mut().incomplete_headers_response(incomplete_headers_ids), + &mut target_go_offline_future, + |target_client| delay(CONNECTION_ERROR_DELAY_MS, target_client), + || format!("Error retrieving incomplete headers from {} node", P::TARGET_NAME), + ); + }, (target_client, target_existence_status) = target_existence_status_future => { process_future_result( &mut target_maybe_client, @@ -272,6 +302,17 @@ pub fn run( || format!("Error submitting headers to {} node", P::TARGET_NAME), ); }, + (target_client, target_complete_header_result) = target_complete_header_future => { + process_future_result( + &mut target_maybe_client, + target_client, + target_complete_header_result, + |completed_header| sync.headers_mut().header_completed(&completed_header), + &mut target_go_offline_future, + |target_client| delay(CONNECTION_ERROR_DELAY_MS, target_client), + || format!("Error completing headers at {}", P::TARGET_NAME), + ); + }, (target_client, target_extra_check_result) = target_extra_check_future => { process_future_result( &mut target_maybe_client, @@ -290,6 +331,7 @@ pub fn run( }, _ = target_tick_stream.next() => { target_best_block_required = true; + target_incomplete_headers_required = true; }, } @@ -300,13 +342,26 @@ pub fn run( if let Some(target_client) = target_maybe_client.take() { // the priority is to: // 1) get best block - it stops us from downloading/submitting new blocks + we call it rarely; - // 2) check if we need extra data from source - it stops us from downloading/submitting new blocks; - // 3) check existence - it stops us from submitting new blocks; - // 4) submit header + // 2) get incomplete headers - it stops us from submitting new blocks + we call it rarely; + // 3) complete headers - it stops us from submitting new blocks; + // 4) check if we need extra data from source - it stops us from downloading/submitting new blocks; + // 5) check existence - it stops us from submitting new blocks; + // 6) submit header if target_best_block_required { log::debug!(target: "bridge", "Asking {} about best block", P::TARGET_NAME); target_best_block_future.set(target_client.best_header_id().fuse()); + } else if target_incomplete_headers_required { + log::debug!(target: "bridge", "Asking {} about incomplete headers", P::TARGET_NAME); + target_incomplete_headers_future.set(target_client.incomplete_headers_ids().fuse()); + } else if let Some((id, completion)) = sync.headers_mut().header_to_complete() { + log::debug!( + target: "bridge", + "Going to complete header: {:?}", + id, + ); + + target_complete_header_future.set(target_client.complete_header(id, completion.clone()).fuse()); } else if let Some(header) = sync.headers().header(HeaderStatus::MaybeExtra) { log::debug!( target: "bridge", @@ -359,13 +414,21 @@ pub fn run( if let Some(source_client) = source_maybe_client.take() { // the priority is to: // 1) get best block - it stops us from downloading new blocks + we call it rarely; - // 2) download extra data - it stops us from submitting new blocks; - // 3) download missing headers - it stops us from downloading/submitting new blocks; - // 4) downloading new headers + // 2) download completion data - it stops us from submitting new blocks; + // 3) download extra data - it stops us from submitting new blocks; + // 4) download missing headers - it stops us from downloading/submitting new blocks; + // 5) downloading new headers if source_best_block_number_required { log::debug!(target: "bridge", "Asking {} node about best block number", P::SOURCE_NAME); source_best_block_number_future.set(source_client.best_block_number().fuse()); + } else if let Some(id) = sync.headers_mut().incomplete_header() { + log::debug!( + target: "bridge", + "Retrieving completion data for header: {:?}", + id, + ); + source_completion_future.set(source_client.header_completion(id).fuse()); } else if let Some(header) = sync.headers().header(HeaderStatus::Extra) { let id = header.id(); log::debug!( diff --git a/relays/ethereum/src/sync_types.rs b/relays/ethereum/src/sync_types.rs index 28b7646b85..4767a5daac 100644 --- a/relays/ethereum/src/sync_types.rs +++ b/relays/ethereum/src/sync_types.rs @@ -15,7 +15,7 @@ // along with Parity Bridges Common. If not, see . /// Ethereum header Id. -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)] pub struct HeaderId(pub Number, pub Hash); /// Ethereum header synchronization status. @@ -33,6 +33,8 @@ pub enum HeaderStatus { Extra, /// Header is in Ready queue. Ready, + /// Header is in Incomplete queue. + Incomplete, /// Header has been recently submitted to the target node. Submitted, /// Header is known to the target node. @@ -61,6 +63,7 @@ pub trait HeadersSyncPipeline: Clone + Copy { + Copy + std::fmt::Debug + std::fmt::Display + + std::hash::Hash + std::ops::Add + std::ops::Sub + num_traits::Saturating @@ -70,10 +73,10 @@ pub trait HeadersSyncPipeline: Clone + Copy { type Header: Clone + std::fmt::Debug + SourceHeader; /// Type of extra data for the header that we're receiving from the source node. type Extra: Clone + std::fmt::Debug; - /// Type of extra data that we're sending separately from the header itself. - type AsyncExtra: Clone + std::fmt::Debug; + /// Type of data required to 'complete' header that we're receiving from the source node. + type Completion: Clone + std::fmt::Debug; - /// Function used to convert from queued header to target header. + /// Function used to estimate size of target-encoded header. fn estimate_size(source: &QueuedHeader) -> usize; } From 89578fb16f7f7340a42e307a387bb6fe930d3cfd Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 20 Apr 2020 19:04:42 +0300 Subject: [PATCH 31/92] added TODO --- modules/ethereum-contract/contracts/substrate-bridge.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/ethereum-contract/contracts/substrate-bridge.sol b/modules/ethereum-contract/contracts/substrate-bridge.sol index 1f6b7e8fe4..4eb67b9ae4 100644 --- a/modules/ethereum-contract/contracts/substrate-bridge.sol +++ b/modules/ethereum-contract/contracts/substrate-bridge.sol @@ -218,6 +218,8 @@ contract SubstrateBridge { bestFinalizedHeaderHash = newBestFinalizedHeaderHash; bestFinalizedHeaderNumber = newFinalizedHeader.number; + // TODO: we may actually use prevSignalHeaderHash to find previous signal block instead of this while? + // apply validators set change signal if required while (newBestFinalizedHeaderHash != oldBestFinalizedHeaderHash) { bytes32 finalizingHeader = newBestFinalizedHeaderHash; From 48928ec2c382f7d5f38f07b1892c8e67fd9be11f Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 21 Apr 2020 09:54:23 +0300 Subject: [PATCH 32/92] substrate-bridge.json -> substrate-bridge-abi.json --- .../res/{substrate-bridge.json => substrate-bridge-abi.json} | 0 relays/ethereum/src/ethereum_client.rs | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename relays/ethereum/res/{substrate-bridge.json => substrate-bridge-abi.json} (100%) diff --git a/relays/ethereum/res/substrate-bridge.json b/relays/ethereum/res/substrate-bridge-abi.json similarity index 100% rename from relays/ethereum/res/substrate-bridge.json rename to relays/ethereum/res/substrate-bridge-abi.json diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index 8bf17e41e8..3cbbf9fbab 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -28,7 +28,7 @@ use serde::{de::DeserializeOwned, Serialize}; use serde_json::{from_value, to_value}; // to encode/decode contract calls -ethabi_contract::use_contract!(bridge_contract, "res/substrate-bridge.json"); +ethabi_contract::use_contract!(bridge_contract, "res/substrate-bridge-abi.json"); /// Proof of hash serialization success. const HASH_SERIALIZATION_PROOF: &'static str = "hash serialization never fails; qed"; From 47c07cfa5f34af36eb0f5ab59a5097d7a2403eb8 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 21 Apr 2020 10:01:52 +0300 Subject: [PATCH 33/92] get rid of substrate transactions hashes --- relays/ethereum/src/ethereum_sync_loop.rs | 2 +- relays/ethereum/src/substrate_client.rs | 21 +++++++++------------ relays/ethereum/src/substrate_types.rs | 3 --- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index 072a0ade92..a223ebbefc 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -175,7 +175,7 @@ impl TargetClient for SubstrateHeadersTarget { sign_transactions, sign_params, }, - result.map(|(_, submitted_headers)| submitted_headers), + result, ) }) .boxed() diff --git a/relays/ethereum/src/substrate_client.rs b/relays/ethereum/src/substrate_client.rs index beb2d2f196..30e620ccb3 100644 --- a/relays/ethereum/src/substrate_client.rs +++ b/relays/ethereum/src/substrate_client.rs @@ -17,7 +17,6 @@ use crate::ethereum_types::{Bytes, EthereumHeaderId, QueuedEthereumHeader, H256}; use crate::substrate_types::{ into_substrate_ethereum_header, into_substrate_ethereum_receipts, Hash, Header as SubstrateHeader, Number, - TransactionHash, }; use crate::sync_types::{HeaderId, MaybeConnectionError, SourceHeader}; use crate::{bail_on_arg_error, bail_on_error}; @@ -205,7 +204,7 @@ pub async fn submit_ethereum_headers( params: SubstrateSigningParams, headers: Vec, sign_transactions: bool, -) -> (Client, Result<(Vec, Vec), Error>) { +) -> (Client, Result, Error>) { match sign_transactions { true => submit_signed_ethereum_headers(client, params, headers).await, false => submit_unsigned_ethereum_headers(client, headers).await, @@ -217,7 +216,7 @@ pub async fn submit_signed_ethereum_headers( client: Client, params: SubstrateSigningParams, headers: Vec, -) -> (Client, Result<(Vec, Vec), Error>) { +) -> (Client, Result, Error>) { let ids = headers.iter().map(|header| header.id()).collect(); let (client, genesis_hash) = match client.genesis_hash { Some(genesis_hash) => (client, genesis_hash), @@ -235,17 +234,17 @@ pub async fn submit_signed_ethereum_headers( to_value(Bytes(transaction.encode())).map_err(|e| Error::RequestSerialization(e)), client ); - let (client, transaction_hash) = call_rpc( + let (client, _) = call_rpc( client, "author_submitExtrinsic", Params::Array(vec![encoded_transaction]), - rpc_returns_value, + |_| Ok(()), ) .await; ( client, - transaction_hash.map(|transaction_hash| (vec![transaction_hash], ids)), + Ok(ids), ) } @@ -253,9 +252,8 @@ pub async fn submit_signed_ethereum_headers( pub async fn submit_unsigned_ethereum_headers( mut client: Client, headers: Vec, -) -> (Client, Result<(Vec, Vec), Error>) { +) -> (Client, Result, Error>) { let ids = headers.iter().map(|header| header.id()).collect(); - let mut transactions_hashes = Vec::new(); for header in headers { let transaction = create_unsigned_submit_transaction(header); @@ -263,21 +261,20 @@ pub async fn submit_unsigned_ethereum_headers( to_value(Bytes(transaction.encode())).map_err(|e| Error::RequestSerialization(e)), client ); - let (used_client, transaction_hash) = bail_on_error!( + let (used_client, _) = bail_on_error!( call_rpc( client, "author_submitExtrinsic", Params::Array(vec![encoded_transaction]), - rpc_returns_value, + |_| Ok(()), ) .await ); client = used_client; - transactions_hashes.push(transaction_hash); } - (client, Ok((transactions_hashes, ids))) + (client, Ok(ids)) } /// Get GRANDPA authorities set at given block. diff --git a/relays/ethereum/src/substrate_types.rs b/relays/ethereum/src/substrate_types.rs index 268bf48a5d..5f812f0c01 100644 --- a/relays/ethereum/src/substrate_types.rs +++ b/relays/ethereum/src/substrate_types.rs @@ -24,9 +24,6 @@ pub use sp_bridge_eth_poa::{ Receipt as SubstrateEthereumReceipt, TransactionOutcome as SubstrateEthereumTransactionOutcome, H256, U256, }; -/// Substrate transaction hash type. -pub type TransactionHash = bridge_node_runtime::Hash; - /// Substrate header hash. pub type Hash = bridge_node_runtime::Hash; From ccc58b09594e8bb82fad2a3fc1a3053a2200b4c6 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 21 Apr 2020 09:57:33 +0300 Subject: [PATCH 34/92] get rid of ethereum transactions hashes --- relays/ethereum/src/ethereum_client.rs | 19 ++++++++++--------- relays/ethereum/src/ethereum_types.rs | 3 +++ relays/ethereum/src/substrate_sync_loop.rs | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index 3cbbf9fbab..1cec4bea1c 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::ethereum_types::{Address, Bytes, EthereumHeaderId, Header, Receipt, H256, U256, U64}; +use crate::ethereum_types::{Address, Bytes, EthereumHeaderId, Header, Receipt, TransactionHash, H256, U256, U64}; use crate::substrate_types::{Hash as SubstrateHash, QueuedSubstrateHeader, SubstrateHeaderId}; use crate::sync_types::{HeaderId, MaybeConnectionError}; use crate::{bail_on_arg_error, bail_on_error}; @@ -275,14 +275,13 @@ pub async fn submit_substrate_headers( params: EthereumSigningParams, contract_address: Address, headers: Vec, -) -> (Client, Result<(Vec, Vec), Error>) { +) -> (Client, Result, Error>) { let (mut client, mut nonce) = bail_on_error!(account_nonce(client, params.signer.address().as_fixed_bytes().into()).await); - let mut tx_hashes = Vec::with_capacity(headers.len()); let ids = headers.iter().map(|header| header.id()).collect(); for header in headers { - let (ret_client, tx_hash) = bail_on_error!( + let (ret_client, _) = bail_on_error!( submit_ethereum_transaction( client, ¶ms, @@ -295,11 +294,10 @@ pub async fn submit_substrate_headers( ); nonce += 1.into(); - tx_hashes.push(tx_hash); client = ret_client; } - (client, Ok((tx_hashes, ids))) + (client, Ok(ids)) } /// Deploy bridge contract. @@ -310,7 +308,7 @@ pub async fn deploy_bridge_contract( initial_header: Vec, initial_set_id: u64, initial_authorities: Vec, -) -> (Client, Result) { +) -> (Client, Result<(), Error>) { submit_ethereum_transaction( client, params, @@ -330,7 +328,7 @@ async fn submit_ethereum_transaction( nonce: Option, double_gas: bool, encoded_call: Vec, -) -> (Client, Result) { +) -> (Client, Result<(), Error>) { let (client, nonce) = match nonce { Some(nonce) => (client, nonce), None => bail_on_error!(account_nonce(client, params.signer.address().as_fixed_bytes().into()).await), @@ -359,7 +357,10 @@ async fn submit_ethereum_transaction( to_value(Bytes(raw_transaction)).map_err(|e| Error::RequestSerialization(e)), client ); - call_rpc(client, "eth_submitTransaction", Params::Array(vec![transaction])).await + let (client, _) = bail_on_error!( + call_rpc::(client, "eth_submitTransaction", Params::Array(vec![transaction])).await + ); + (client, Ok(())) } /// Get account nonce. diff --git a/relays/ethereum/src/ethereum_types.rs b/relays/ethereum/src/ethereum_types.rs index dc61db2deb..d996ac7c29 100644 --- a/relays/ethereum/src/ethereum_types.rs +++ b/relays/ethereum/src/ethereum_types.rs @@ -28,6 +28,9 @@ pub const HEADER_ID_PROOF: &'static str = "checked on retrieval; qed"; /// gas_used field filled. pub const RECEIPT_GAS_USED_PROOF: &'static str = "checked on retrieval; qed"; +/// Ethereum transaction hash type. +pub type TransactionHash = H256; + /// Ethereum header type. pub type Header = web3::types::Block; diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index 539b9f8e59..1245b4cfef 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -168,7 +168,7 @@ impl TargetClient for EthereumHeadersTarget { contract, sign_params, }, - result.map(|(_, submitted_headers)| submitted_headers), + result, ) }) .boxed() From 369afaa210fe9d9a259182542e1f1d3ded398aac Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 21 Apr 2020 10:25:25 +0300 Subject: [PATCH 35/92] extracted contract bytecode to separate file --- relays/ethereum/res/substrate-bridge-bytecode.hex | 1 + relays/ethereum/src/ethereum_deploy_contract.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 relays/ethereum/res/substrate-bridge-bytecode.hex diff --git a/relays/ethereum/res/substrate-bridge-bytecode.hex b/relays/ethereum/res/substrate-bridge-bytecode.hex new file mode 100644 index 0000000000..e507f0b1a0 --- /dev/null +++ b/relays/ethereum/res/substrate-bridge-bytecode.hex @@ -0,0 +1 @@ +60806040523480156200001157600080fd5b5060405162000dfa38038062000dfa833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b506040818152602083015192018051929491939192846401000000008211156200010f57600080fd5b9083019060208201858111156200012557600080fd5b82516401000000008111828201881017156200014057600080fd5b82525081516020918201929091019080838360005b838110156200016f57818101518382015260200162000155565b50505050905090810190601f1680156200019d5780820380516001836020036101000a031916815260200191505b50604052505050620001ae620003d4565b620001c2846001600160e01b03620002dc16565b805160008181556002918255604080840180516001908155825160e08101845281815260208088015181830190815293518286019081526080808a0151606085019081526001600160401b038e169185019190915260a0840188905260c084018890528951885260058352959096208251815460ff191690151517815593519284019290925593519482019490945590518051949550919390926200026f92600385019291019062000409565b506080820151600482810180546001600160401b03199081166001600160401b039485161790915560a0850151600585015560c09094015160069093019290925560038054909316908616179091558251620002d19190602085019062000409565b5050505050620004ae565b620002e6620003d4565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa6200031e57600080fd5b93519251915190519351929b50909950975090955093505082159050620003a757816001600160401b03811180156200035657600080fd5b506040519080825280601f01601f19166020018201604052801562000382576020820181803683370190505b50905087516020890160208301848184846011600019fa620003a357600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200044c57805160ff19168380011785556200047c565b828001600101855582156200047c579182015b828111156200047c5782518255916020019190600101906200045f565b506200048a9291506200048e565b5090565b620004ab91905b808211156200048a576000815560010162000495565b90565b61093c80620004be6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063871ebe181461005c578063a98bfaad1461008d578063d96a2deb146100aa578063e7af0779146100cb578063fae71ae814610173575b600080fd5b6100796004803603602081101561007257600080fd5b5035610225565b604080519115158252519081900360200190f35b610079600480360360208110156100a357600080fd5b503561023a565b6100b2610297565b6040805192835260208301919091528051918290030190f35b610171600480360360208110156100e157600080fd5b8101906020810181356401000000008111156100fc57600080fd5b82018360208201111561010e57600080fd5b8035906020019184600183028401116401000000008311171561013057600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506102af945050505050565b005b6101716004803603606081101561018957600080fd5b8135916020810135918101906060810160408201356401000000008111156101b057600080fd5b8201836020820111156101c257600080fd5b803590602001918460018302840111640100000000831117156101e457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610521945050505050565b60009081526005602052604090205460ff1690565b6000818152600560205260408120805460ff16801561025e57506001548160020154115b8015610271575080600601548160020154145b80156102905750600354600482015467ffffffffffffffff9081169116145b9392505050565b60008054808252600560205260409091206002015491565b6102b761073b565b6102c08261063f565b905060006005600083602001518152602001908152602001600020905060018260400151038160020154146103265760405162461bcd60e51b81526004018080602001828103825260268152602001806108816026913960400191505060405180910390fd5b600681015415801590610340575080600201548160060154145b15610389578160200151600254146103895760405162461bcd60e51b81526004018080602001828103825260318152602001806108d66031913960400191505060405180910390fd5b6006810154608083015151156103fe57826040015181106103f1576040805162461bcd60e51b815260206004820152601960248201527f4f7665726c617070696e67207369676e616c7320666f756e6400000000000000604482015290519081900360640190fd5b5060608201516040830151015b60048201546005830154600384015467ffffffffffffffff90921691600260001960018316156101000201909116041561043f575060208401516001909101905b6040805160e0810182526001808252602088810151818401908152898501518486019081526080808c01516060870190815267ffffffffffffffff8a169187019190915260a0860188905260c086018a90528b51600090815260058552969096208551815460ff19169015151781559151938201939093559151600283015592518051929391926104d69260038501920190610770565b50608082015160048201805467ffffffffffffffff191667ffffffffffffffff90921691909117905560a0820151600582015560c09091015160069091015550509151600055505050565b60008281526005602052604090206002015483146105705760405162461bcd60e51b815260040180806020018281038252602f8152602001806108a7602f913960400191505060405180910390fd5b6002546000610580858585610731565b600081815260056020526040902060028281558101546001559091505b828214610637575060009081526005602052604090206001810154600682015460028301549192911415610632576005818101546000908152602091909152604090206003805467ffffffffffffffff198116600167ffffffffffffffff9283168101909216178255908201805461062b9260049291600261010092821615929092026000190116046107ee565b5050610637565b61059d565b505050505050565b61064761073b565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa61067e57600080fd5b93519251915190519351929b50909950975090955093505082159050610704578167ffffffffffffffff811180156106b557600080fd5b506040519080825280601f01601f1916602001820160405280156106e0576020820181803683370190505b50905087516020890160208301848184846011600019fa61070057600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6002549392505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106107b157805160ff19168380011785556107de565b828001600101855582156107de579182015b828111156107de5782518255916020019190600101906107c3565b506107ea929150610863565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061082757805485556107de565b828001600101855582156107de57600052602060002091601f016020900482015b828111156107de578254825591600101919060010190610848565b61087d91905b808211156107ea5760008155600101610869565b9056fe4d697373696e6720706172656e74206865616465722066726f6d207468652073746f726167654d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f726167654d697373696e672072657175697265642066696e616c6974792070726f6f6620666f7220706172656e7420686561646572a2646970667358221220920ca01b59940884722a766076b4f1d1d825eba446e530980bd310f776703dad64736f6c63430006060033 \ No newline at end of file diff --git a/relays/ethereum/src/ethereum_deploy_contract.rs b/relays/ethereum/src/ethereum_deploy_contract.rs index 935b7c335a..d35b640c86 100644 --- a/relays/ethereum/src/ethereum_deploy_contract.rs +++ b/relays/ethereum/src/ethereum_deploy_contract.rs @@ -45,7 +45,7 @@ impl Default for EthereumDeployContractParams { eth: Default::default(), eth_sign: Default::default(), // compiler: 0.6.6+commit.6c089d02 + optimization - eth_contract_code: hex::decode("60806040523480156200001157600080fd5b5060405162000dfa38038062000dfa833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b506040818152602083015192018051929491939192846401000000008211156200010f57600080fd5b9083019060208201858111156200012557600080fd5b82516401000000008111828201881017156200014057600080fd5b82525081516020918201929091019080838360005b838110156200016f57818101518382015260200162000155565b50505050905090810190601f1680156200019d5780820380516001836020036101000a031916815260200191505b50604052505050620001ae620003d4565b620001c2846001600160e01b03620002dc16565b805160008181556002918255604080840180516001908155825160e08101845281815260208088015181830190815293518286019081526080808a0151606085019081526001600160401b038e169185019190915260a0840188905260c084018890528951885260058352959096208251815460ff191690151517815593519284019290925593519482019490945590518051949550919390926200026f92600385019291019062000409565b506080820151600482810180546001600160401b03199081166001600160401b039485161790915560a0850151600585015560c09094015160069093019290925560038054909316908616179091558251620002d19190602085019062000409565b5050505050620004ae565b620002e6620003d4565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa6200031e57600080fd5b93519251915190519351929b50909950975090955093505082159050620003a757816001600160401b03811180156200035657600080fd5b506040519080825280601f01601f19166020018201604052801562000382576020820181803683370190505b50905087516020890160208301848184846011600019fa620003a357600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200044c57805160ff19168380011785556200047c565b828001600101855582156200047c579182015b828111156200047c5782518255916020019190600101906200045f565b506200048a9291506200048e565b5090565b620004ab91905b808211156200048a576000815560010162000495565b90565b61093c80620004be6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063871ebe181461005c578063a98bfaad1461008d578063d96a2deb146100aa578063e7af0779146100cb578063fae71ae814610173575b600080fd5b6100796004803603602081101561007257600080fd5b5035610225565b604080519115158252519081900360200190f35b610079600480360360208110156100a357600080fd5b503561023a565b6100b2610297565b6040805192835260208301919091528051918290030190f35b610171600480360360208110156100e157600080fd5b8101906020810181356401000000008111156100fc57600080fd5b82018360208201111561010e57600080fd5b8035906020019184600183028401116401000000008311171561013057600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506102af945050505050565b005b6101716004803603606081101561018957600080fd5b8135916020810135918101906060810160408201356401000000008111156101b057600080fd5b8201836020820111156101c257600080fd5b803590602001918460018302840111640100000000831117156101e457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610521945050505050565b60009081526005602052604090205460ff1690565b6000818152600560205260408120805460ff16801561025e57506001548160020154115b8015610271575080600601548160020154145b80156102905750600354600482015467ffffffffffffffff9081169116145b9392505050565b60008054808252600560205260409091206002015491565b6102b761073b565b6102c08261063f565b905060006005600083602001518152602001908152602001600020905060018260400151038160020154146103265760405162461bcd60e51b81526004018080602001828103825260268152602001806108816026913960400191505060405180910390fd5b600681015415801590610340575080600201548160060154145b15610389578160200151600254146103895760405162461bcd60e51b81526004018080602001828103825260318152602001806108d66031913960400191505060405180910390fd5b6006810154608083015151156103fe57826040015181106103f1576040805162461bcd60e51b815260206004820152601960248201527f4f7665726c617070696e67207369676e616c7320666f756e6400000000000000604482015290519081900360640190fd5b5060608201516040830151015b60048201546005830154600384015467ffffffffffffffff90921691600260001960018316156101000201909116041561043f575060208401516001909101905b6040805160e0810182526001808252602088810151818401908152898501518486019081526080808c01516060870190815267ffffffffffffffff8a169187019190915260a0860188905260c086018a90528b51600090815260058552969096208551815460ff19169015151781559151938201939093559151600283015592518051929391926104d69260038501920190610770565b50608082015160048201805467ffffffffffffffff191667ffffffffffffffff90921691909117905560a0820151600582015560c09091015160069091015550509151600055505050565b60008281526005602052604090206002015483146105705760405162461bcd60e51b815260040180806020018281038252602f8152602001806108a7602f913960400191505060405180910390fd5b6002546000610580858585610731565b600081815260056020526040902060028281558101546001559091505b828214610637575060009081526005602052604090206001810154600682015460028301549192911415610632576005818101546000908152602091909152604090206003805467ffffffffffffffff198116600167ffffffffffffffff9283168101909216178255908201805461062b9260049291600261010092821615929092026000190116046107ee565b5050610637565b61059d565b505050505050565b61064761073b565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa61067e57600080fd5b93519251915190519351929b50909950975090955093505082159050610704578167ffffffffffffffff811180156106b557600080fd5b506040519080825280601f01601f1916602001820160405280156106e0576020820181803683370190505b50905087516020890160208301848184846011600019fa61070057600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6002549392505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106107b157805160ff19168380011785556107de565b828001600101855582156107de579182015b828111156107de5782518255916020019190600101906107c3565b506107ea929150610863565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061082757805485556107de565b828001600101855582156107de57600052602060002091601f016020900482015b828111156107de578254825591600101919060010190610848565b61087d91905b808211156107ea5760008155600101610869565b9056fe4d697373696e6720706172656e74206865616465722066726f6d207468652073746f726167654d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f726167654d697373696e672072657175697265642066696e616c6974792070726f6f6620666f7220706172656e7420686561646572a2646970667358221220920ca01b59940884722a766076b4f1d1d825eba446e530980bd310f776703dad64736f6c63430006060033") + eth_contract_code: hex::decode(include_str!("../res/substrate-bridge-bytecode.hex")) .expect("code is hardcoded, thus valid; qed"), sub: Default::default(), sub_initial_authorities_set_id: None, From 27505e3e38524dfdc3a05bad55fd72c9b371c8b0 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 21 Apr 2020 10:27:52 +0300 Subject: [PATCH 36/92] cargo fmt --all --- relays/ethereum/src/substrate_client.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/relays/ethereum/src/substrate_client.rs b/relays/ethereum/src/substrate_client.rs index 30e620ccb3..3d74dec250 100644 --- a/relays/ethereum/src/substrate_client.rs +++ b/relays/ethereum/src/substrate_client.rs @@ -242,10 +242,7 @@ pub async fn submit_signed_ethereum_headers( ) .await; - ( - client, - Ok(ids), - ) + (client, Ok(ids)) } /// Submits unsigned Ethereum header to Substrate runtime. From c1daf3c8d4eb9abb911441622dfe4ee8b4c8bc7e Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 21 Apr 2020 13:15:12 +0300 Subject: [PATCH 37/92] avoid duplicate import in contracts --- .../ethereum-contract/contracts/substrate-bridge.sol | 10 ++++++++-- relays/ethereum/res/substrate-bridge-bytecode.hex | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/ethereum-contract/contracts/substrate-bridge.sol b/modules/ethereum-contract/contracts/substrate-bridge.sol index befd358c70..9e26fe266d 100644 --- a/modules/ethereum-contract/contracts/substrate-bridge.sol +++ b/modules/ethereum-contract/contracts/substrate-bridge.sol @@ -123,11 +123,17 @@ contract SubstrateBridge { function importHeader( bytes memory rawHeader ) public { - // parse and save header + // parse header ParsedHeader memory header = parseSubstrateHeader(rawHeader); + require( + !headerByHash[header.hash].isKnown, + "Header is already known" + ); + + // check if we're able to coninue chain with this header Header storage parentHeader = headerByHash[header.parentHash]; require( - parentHeader.number == header.number - 1, + parentHeader.isKnown && parentHeader.number == header.number - 1, "Missing parent header from the storage" ); diff --git a/relays/ethereum/res/substrate-bridge-bytecode.hex b/relays/ethereum/res/substrate-bridge-bytecode.hex index e507f0b1a0..54c252b65d 100644 --- a/relays/ethereum/res/substrate-bridge-bytecode.hex +++ b/relays/ethereum/res/substrate-bridge-bytecode.hex @@ -1 +1 @@ -60806040523480156200001157600080fd5b5060405162000dfa38038062000dfa833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b506040818152602083015192018051929491939192846401000000008211156200010f57600080fd5b9083019060208201858111156200012557600080fd5b82516401000000008111828201881017156200014057600080fd5b82525081516020918201929091019080838360005b838110156200016f57818101518382015260200162000155565b50505050905090810190601f1680156200019d5780820380516001836020036101000a031916815260200191505b50604052505050620001ae620003d4565b620001c2846001600160e01b03620002dc16565b805160008181556002918255604080840180516001908155825160e08101845281815260208088015181830190815293518286019081526080808a0151606085019081526001600160401b038e169185019190915260a0840188905260c084018890528951885260058352959096208251815460ff191690151517815593519284019290925593519482019490945590518051949550919390926200026f92600385019291019062000409565b506080820151600482810180546001600160401b03199081166001600160401b039485161790915560a0850151600585015560c09094015160069093019290925560038054909316908616179091558251620002d19190602085019062000409565b5050505050620004ae565b620002e6620003d4565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa6200031e57600080fd5b93519251915190519351929b50909950975090955093505082159050620003a757816001600160401b03811180156200035657600080fd5b506040519080825280601f01601f19166020018201604052801562000382576020820181803683370190505b50905087516020890160208301848184846011600019fa620003a357600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200044c57805160ff19168380011785556200047c565b828001600101855582156200047c579182015b828111156200047c5782518255916020019190600101906200045f565b506200048a9291506200048e565b5090565b620004ab91905b808211156200048a576000815560010162000495565b90565b61093c80620004be6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063871ebe181461005c578063a98bfaad1461008d578063d96a2deb146100aa578063e7af0779146100cb578063fae71ae814610173575b600080fd5b6100796004803603602081101561007257600080fd5b5035610225565b604080519115158252519081900360200190f35b610079600480360360208110156100a357600080fd5b503561023a565b6100b2610297565b6040805192835260208301919091528051918290030190f35b610171600480360360208110156100e157600080fd5b8101906020810181356401000000008111156100fc57600080fd5b82018360208201111561010e57600080fd5b8035906020019184600183028401116401000000008311171561013057600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506102af945050505050565b005b6101716004803603606081101561018957600080fd5b8135916020810135918101906060810160408201356401000000008111156101b057600080fd5b8201836020820111156101c257600080fd5b803590602001918460018302840111640100000000831117156101e457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610521945050505050565b60009081526005602052604090205460ff1690565b6000818152600560205260408120805460ff16801561025e57506001548160020154115b8015610271575080600601548160020154145b80156102905750600354600482015467ffffffffffffffff9081169116145b9392505050565b60008054808252600560205260409091206002015491565b6102b761073b565b6102c08261063f565b905060006005600083602001518152602001908152602001600020905060018260400151038160020154146103265760405162461bcd60e51b81526004018080602001828103825260268152602001806108816026913960400191505060405180910390fd5b600681015415801590610340575080600201548160060154145b15610389578160200151600254146103895760405162461bcd60e51b81526004018080602001828103825260318152602001806108d66031913960400191505060405180910390fd5b6006810154608083015151156103fe57826040015181106103f1576040805162461bcd60e51b815260206004820152601960248201527f4f7665726c617070696e67207369676e616c7320666f756e6400000000000000604482015290519081900360640190fd5b5060608201516040830151015b60048201546005830154600384015467ffffffffffffffff90921691600260001960018316156101000201909116041561043f575060208401516001909101905b6040805160e0810182526001808252602088810151818401908152898501518486019081526080808c01516060870190815267ffffffffffffffff8a169187019190915260a0860188905260c086018a90528b51600090815260058552969096208551815460ff19169015151781559151938201939093559151600283015592518051929391926104d69260038501920190610770565b50608082015160048201805467ffffffffffffffff191667ffffffffffffffff90921691909117905560a0820151600582015560c09091015160069091015550509151600055505050565b60008281526005602052604090206002015483146105705760405162461bcd60e51b815260040180806020018281038252602f8152602001806108a7602f913960400191505060405180910390fd5b6002546000610580858585610731565b600081815260056020526040902060028281558101546001559091505b828214610637575060009081526005602052604090206001810154600682015460028301549192911415610632576005818101546000908152602091909152604090206003805467ffffffffffffffff198116600167ffffffffffffffff9283168101909216178255908201805461062b9260049291600261010092821615929092026000190116046107ee565b5050610637565b61059d565b505050505050565b61064761073b565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa61067e57600080fd5b93519251915190519351929b50909950975090955093505082159050610704578167ffffffffffffffff811180156106b557600080fd5b506040519080825280601f01601f1916602001820160405280156106e0576020820181803683370190505b50905087516020890160208301848184846011600019fa61070057600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6002549392505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106107b157805160ff19168380011785556107de565b828001600101855582156107de579182015b828111156107de5782518255916020019190600101906107c3565b506107ea929150610863565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061082757805485556107de565b828001600101855582156107de57600052602060002091601f016020900482015b828111156107de578254825591600101919060010190610848565b61087d91905b808211156107ea5760008155600101610869565b9056fe4d697373696e6720706172656e74206865616465722066726f6d207468652073746f726167654d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f726167654d697373696e672072657175697265642066696e616c6974792070726f6f6620666f7220706172656e7420686561646572a2646970667358221220920ca01b59940884722a766076b4f1d1d825eba446e530980bd310f776703dad64736f6c63430006060033 \ No newline at end of file +60806040523480156200001157600080fd5b5060405162000e6738038062000e67833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b506040818152602083015192018051929491939192846401000000008211156200010f57600080fd5b9083019060208201858111156200012557600080fd5b82516401000000008111828201881017156200014057600080fd5b82525081516020918201929091019080838360005b838110156200016f57818101518382015260200162000155565b50505050905090810190601f1680156200019d5780820380516001836020036101000a031916815260200191505b50604052505050620001ae620003d4565b620001c2846001600160e01b03620002dc16565b805160008181556002918255604080840180516001908155825160e08101845281815260208088015181830190815293518286019081526080808a0151606085019081526001600160401b038e169185019190915260a0840188905260c084018890528951885260058352959096208251815460ff191690151517815593519284019290925593519482019490945590518051949550919390926200026f92600385019291019062000409565b506080820151600482810180546001600160401b03199081166001600160401b039485161790915560a0850151600585015560c09094015160069093019290925560038054909316908616179091558251620002d19190602085019062000409565b5050505050620004ae565b620002e6620003d4565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa6200031e57600080fd5b93519251915190519351929b50909950975090955093505082159050620003a757816001600160401b03811180156200035657600080fd5b506040519080825280601f01601f19166020018201604052801562000382576020820181803683370190505b50905087516020890160208301848184846011600019fa620003a357600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200044c57805160ff19168380011785556200047c565b828001600101855582156200047c579182015b828111156200047c5782518255916020019190600101906200045f565b506200048a9291506200048e565b5090565b620004ab91905b808211156200048a576000815560010162000495565b90565b6109a980620004be6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063871ebe181461005c578063a98bfaad1461008d578063d96a2deb146100aa578063e7af0779146100cb578063fae71ae814610173575b600080fd5b6100796004803603602081101561007257600080fd5b5035610225565b604080519115158252519081900360200190f35b610079600480360360208110156100a357600080fd5b503561023a565b6100b2610297565b6040805192835260208301919091528051918290030190f35b610171600480360360208110156100e157600080fd5b8101906020810181356401000000008111156100fc57600080fd5b82018360208201111561010e57600080fd5b8035906020019184600183028401116401000000008311171561013057600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506102af945050505050565b005b6101716004803603606081101561018957600080fd5b8135916020810135918101906060810160408201356401000000008111156101b057600080fd5b8201836020820111156101c257600080fd5b803590602001918460018302840111640100000000831117156101e457600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061058e945050505050565b60009081526005602052604090205460ff1690565b6000818152600560205260408120805460ff16801561025e57506001548160020154115b8015610271575080600601548160020154145b80156102905750600354600482015467ffffffffffffffff9081169116145b9392505050565b60008054808252600560205260409091206002015491565b6102b76107a8565b6102c0826106ac565b805160009081526005602052604090205490915060ff1615610329576040805162461bcd60e51b815260206004820152601760248201527f48656164657220697320616c7265616479206b6e6f776e000000000000000000604482015290519081900360640190fd5b6020808201516000908152600590915260409020805460ff168015610358575060018260400151038160020154145b6103935760405162461bcd60e51b81526004018080602001828103825260268152602001806108ee6026913960400191505060405180910390fd5b6006810154158015906103ad575080600201548160060154145b156103f6578160200151600254146103f65760405162461bcd60e51b81526004018080602001828103825260318152602001806109436031913960400191505060405180910390fd5b60068101546080830151511561046b578260400151811061045e576040805162461bcd60e51b815260206004820152601960248201527f4f7665726c617070696e67207369676e616c7320666f756e6400000000000000604482015290519081900360640190fd5b5060608201516040830151015b60048201546005830154600384015467ffffffffffffffff9092169160026000196001831615610100020190911604156104ac575060208401516001909101905b6040805160e0810182526001808252602088810151818401908152898501518486019081526080808c01516060870190815267ffffffffffffffff8a169187019190915260a0860188905260c086018a90528b51600090815260058552969096208551815460ff191690151517815591519382019390935591516002830155925180519293919261054392600385019201906107dd565b50608082015160048201805467ffffffffffffffff191667ffffffffffffffff90921691909117905560a0820151600582015560c09091015160069091015550509151600055505050565b60008281526005602052604090206002015483146105dd5760405162461bcd60e51b815260040180806020018281038252602f815260200180610914602f913960400191505060405180910390fd5b60025460006105ed85858561079e565b600081815260056020526040902060028281558101546001559091505b8282146106a457506000908152600560205260409020600181015460068201546002830154919291141561069f576005818101546000908152602091909152604090206003805467ffffffffffffffff198116600167ffffffffffffffff9283168101909216178255908201805461069892600492916002610100928216159290920260001901160461085b565b50506106a4565b61060a565b505050505050565b6106b46107a8565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa6106eb57600080fd5b93519251915190519351929b50909950975090955093505082159050610771578167ffffffffffffffff8111801561072257600080fd5b506040519080825280601f01601f19166020018201604052801561074d576020820181803683370190505b50905087516020890160208301848184846011600019fa61076d57600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6002549392505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061081e57805160ff191683800117855561084b565b8280016001018555821561084b579182015b8281111561084b578251825591602001919060010190610830565b506108579291506108d0565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610894578054855561084b565b8280016001018555821561084b57600052602060002091601f016020900482015b8281111561084b5782548255916001019190600101906108b5565b6108ea91905b8082111561085757600081556001016108d6565b9056fe4d697373696e6720706172656e74206865616465722066726f6d207468652073746f726167654d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f726167654d697373696e672072657175697265642066696e616c6974792070726f6f6620666f7220706172656e7420686561646572a26469706673582212206cc35a10288e85e37e14250b2d4af37dc4fbcd59635965d9ac0421cb8db1f66c64736f6c63430006060033 \ No newline at end of file From e560d1cd88ec6ba344125182bbad981101bba88f Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 22 Apr 2020 09:38:47 +0300 Subject: [PATCH 38/92] removed Default::default() --- relays/ethereum/src/ethereum_client.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index 1cec4bea1c..856aa43dde 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -339,7 +339,6 @@ async fn submit_ethereum_transaction( CallRequest { to: contract_address, data: Some(encoded_call.clone().into()), - ..Default::default() } ) .await From 7bcc95f6d64c984d47319545434df970cae66365 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 22 Apr 2020 10:02:57 +0300 Subject: [PATCH 39/92] swapped configurations for sub2eth && eth2sub --- relays/ethereum/src/ethereum_sync_loop.rs | 10 +++++----- relays/ethereum/src/substrate_sync_loop.rs | 8 ++++---- relays/ethereum/src/substrate_types.rs | 6 ++---- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index a223ebbefc..dd0be0e9aa 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -47,11 +47,11 @@ impl Default for EthereumSyncParams { sub: Default::default(), sub_sign: Default::default(), sync_params: HeadersSyncParams { - max_future_headers_to_download: 8, - max_headers_in_submitted_status: 4, - max_headers_in_single_submit: 4, - max_headers_size_in_single_submit: 64 * 1024 * 1024, // something that we should never hit - prune_depth: 256, + max_future_headers_to_download: 128, + max_headers_in_submitted_status: 128, + max_headers_in_single_submit: 32, + max_headers_size_in_single_submit: 131_072, + prune_depth: 4096, target_tx_mode: TargetTransactionMode::Signed, }, } diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index 1245b4cfef..f0a020dc29 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -58,11 +58,11 @@ impl Default for SubstrateSyncParams { .expect("address is hardcoded, thus valid; qed"), sub: Default::default(), sync_params: HeadersSyncParams { - max_future_headers_to_download: 128, - max_headers_in_submitted_status: 128, - max_headers_in_single_submit: 32, + max_future_headers_to_download: 8, + max_headers_in_submitted_status: 4, + max_headers_in_single_submit: 4, max_headers_size_in_single_submit: 131_072, - prune_depth: 4096, + prune_depth: 256, target_tx_mode: TargetTransactionMode::Signed, }, } diff --git a/relays/ethereum/src/substrate_types.rs b/relays/ethereum/src/substrate_types.rs index 5f812f0c01..19be9940ac 100644 --- a/relays/ethereum/src/substrate_types.rs +++ b/relays/ethereum/src/substrate_types.rs @@ -53,10 +53,8 @@ impl HeadersSyncPipeline for SubstrateHeadersSyncPipeline { type Header = Header; type Extra = (); - fn estimate_size(_source: &QueuedHeader) -> usize { - // we may only submit Substrate headers wit finality proof - // => this value should never be used - 0 + fn estimate_size(source: &QueuedHeader) -> usize { + source.header().encode().len() } } From e37fb2b88118d9b09b476795a8229e089d6384c1 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 22 Apr 2020 10:12:26 +0300 Subject: [PATCH 40/92] fix compilation --- relays/ethereum/src/substrate_types.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/relays/ethereum/src/substrate_types.rs b/relays/ethereum/src/substrate_types.rs index 19be9940ac..3d15ec95dd 100644 --- a/relays/ethereum/src/substrate_types.rs +++ b/relays/ethereum/src/substrate_types.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +use codec::Encode; use crate::ethereum_types::{ Header as EthereumHeader, Receipt as EthereumReceipt, HEADER_ID_PROOF as ETHEREUM_HEADER_ID_PROOF, RECEIPT_GAS_USED_PROOF as ETHEREUM_RECEIPT_GAS_USED_PROOF, From bdfaaf29c4fa395fadcac765c543069002e25e25 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 22 Apr 2020 10:12:46 +0300 Subject: [PATCH 41/92] do not double gas limit when submitting Substrate headers --- relays/ethereum/src/ethereum_client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index 856aa43dde..93368f3977 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -287,7 +287,7 @@ pub async fn submit_substrate_headers( ¶ms, Some(contract_address), Some(nonce), - true, // we may need slightly more gas because other actors could change contract state + false, bridge_contract::functions::import_header::encode_input(header.extract().0.encode(),), ) .await From ddb14c671890fb9596e73c959aa325d04c72892c Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 22 Apr 2020 12:42:14 +0300 Subject: [PATCH 42/92] fix finality storage --- bin/node/node/src/chain_spec.rs | 3 ++ bin/node/runtime/src/lib.rs | 37 +++++++++++++++---- .../contracts/substrate-bridge.sol | 11 ++---- .../ethereum/src/ethereum_deploy_contract.rs | 2 +- 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/bin/node/node/src/chain_spec.rs b/bin/node/node/src/chain_spec.rs index c237474e34..b5d9476c89 100644 --- a/bin/node/node/src/chain_spec.rs +++ b/bin/node/node/src/chain_spec.rs @@ -97,6 +97,9 @@ impl Alternative { vec![ get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob"), + get_authority_keys_from_seed("Charlie"), + get_authority_keys_from_seed("Dave"), + get_authority_keys_from_seed("Eve"), ], get_account_id_from_seed::("Alice"), vec![ diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 028e7c935e..22d915aa43 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -24,6 +24,7 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +use codec::{Decode, Encode}; use pallet_grandpa::fg_primitives; use pallet_grandpa::AuthorityList as GrandpaAuthorityList; use sp_api::impl_runtime_apis; @@ -234,7 +235,7 @@ impl pallet_sudo::Trait for Runtime { } parameter_types! { - pub const Period: BlockNumber = 8; + pub const Period: BlockNumber = 4; pub const Offset: BlockNumber = 0; } @@ -252,17 +253,39 @@ impl pallet_session::Trait for Runtime { pub struct ShiftSessionManager; impl pallet_session::SessionManager for ShiftSessionManager { fn end_session(_: sp_staking::SessionIndex) {} -// fn start_session(_: sp_staking::SessionIndex) {} fn new_session(session_index: sp_staking::SessionIndex) -> Option> { + // can't access genesis config here :/ if session_index == 0 || session_index == 1 { return None; } - let mut current_validators = >::validators(); - if session_index % 2 != 0 { - current_validators.reverse(); - } - Some(current_validators) + // the idea that on first call (i.e. when session 1 ends) we're reading current + // set of validators from session module (they are initial validators) and save + // in our 'local storage'. + // then for every session we select (deterministically) 2/3 of these initial + // validators to serve validators of new session + let available_validators = sp_io::storage::get(b":available_validators") + .and_then(|validators| Decode::decode(&mut &validators[..]).ok()) + .unwrap_or_else(|| { + let validators = >::validators(); + sp_io::storage::set(b":available_validators", &validators.encode()); + validators + }); + + let available_validators_count = available_validators.len(); + let count = 2 * available_validators_count / 3; + let offset = session_index as usize % available_validators_count; + let end = offset + count; + let session_validators = match end.overflowing_sub(available_validators_count) { + (wrapped_end, false) if wrapped_end != 0 => + available_validators[offset..].iter() + .chain(available_validators[..wrapped_end].iter()) + .cloned() + .collect(), + _ => available_validators[offset..end].to_vec(), + }; + + Some(session_validators) } } diff --git a/modules/ethereum-contract/contracts/substrate-bridge.sol b/modules/ethereum-contract/contracts/substrate-bridge.sol index 4eb67b9ae4..9e53644d14 100644 --- a/modules/ethereum-contract/contracts/substrate-bridge.sol +++ b/modules/ethereum-contract/contracts/substrate-bridge.sol @@ -140,21 +140,18 @@ contract SubstrateBridge { } // forbid overlapping signals + uint64 validatorsSetId = parentHeader.validatorsSetId; + bytes32 prevSignalHeaderHash = parentHeader.prevSignalHeaderHash; uint256 prevSignalTargetNumber = parentHeader.prevSignalTargetNumber; if (header.signal.length != 0) { require( prevSignalTargetNumber < header.number, "Overlapping signals found" ); - prevSignalTargetNumber = header.number + header.signalDelay; - } - // check if parent header has emitted validators set change signal - uint64 validatorsSetId = parentHeader.validatorsSetId; - bytes32 prevSignalHeaderHash = parentHeader.prevSignalHeaderHash; - if (parentHeader.signal.length != 0) { - prevSignalHeaderHash = header.parentHash; validatorsSetId = validatorsSetId + 1; + prevSignalHeaderHash = header.hash; + prevSignalTargetNumber = header.number + header.signalDelay; } // remember if we need finality proof for this header diff --git a/relays/ethereum/src/ethereum_deploy_contract.rs b/relays/ethereum/src/ethereum_deploy_contract.rs index 6215d9feac..337942df9b 100644 --- a/relays/ethereum/src/ethereum_deploy_contract.rs +++ b/relays/ethereum/src/ethereum_deploy_contract.rs @@ -45,7 +45,7 @@ impl Default for EthereumDeployContractParams { eth: Default::default(), eth_sign: Default::default(), // compiler: 0.6.6+commit.6c089d02 + optimization - eth_contract_code: hex::decode("60806040523480156200001157600080fd5b506040516200120238038062001202833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b506040818152602083015192018051929491939192846401000000008211156200010f57600080fd5b9083019060208201858111156200012557600080fd5b82516401000000008111828201881017156200014057600080fd5b82525081516020918201929091019080838360005b838110156200016f57818101518382015260200162000155565b50505050905090810190601f1680156200019d5780820380516001836020036101000a031916815260200191505b50604052505050620001ae620003d5565b620001c2846001600160e01b03620002dc16565b805160008181556002918255604080840180516001908155825160e08101845281815260208088015181830190815293518286019081526080808a0151606085019081526001600160401b038e169185019190915260a0840188905260c084018890528951885260078352959096208251815460ff191690151517815593519284019290925593519482019490945590518051949550919390926200026f9260038501929101906200040a565b506080820151600482810180546001600160401b03199081166001600160401b039485161790915560a0850151600585015560c09094015160069093019290925560038054909316908616179091558251620002d1919060208501906200040a565b5050505050620004af565b620002e6620003d5565b60008060008060008651602088016040516020810160208101602081016020810160a08588886010600019fa6200031c57600080fd5b84519b5083519a50825199508151985080519750505050505050506060816001600160401b03811180156200035057600080fd5b506040519080825280601f01601f1916602001820160405280156200037c576020820181803683370190505b5090508115620003a85787516020890160208301848184846011600019fa620003a457600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200044d57805160ff19168380011785556200047d565b828001600101855582156200047d579182015b828111156200047d57825182559160200191906001019062000460565b506200048b9291506200048f565b5090565b620004ac91905b808211156200048b576000815560010162000496565b90565b610d4380620004bf6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063374c2c261461005c578063871ebe18146100fd578063d96a2deb1461012e578063e7af07791461014f578063fae71ae8146101f7575b600080fd5b6100646102a9565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156100a8578181015183820152602001610090565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156100e75781810151838201526020016100cf565b5050505090500194505050505060405180910390f35b61011a6004803603602081101561011357600080fd5b50356103ae565b604080519115158252519081900360200190f35b6101366103c3565b6040805192835260208301919091528051918290030190f35b6101f56004803603602081101561016557600080fd5b81019060208101813564010000000081111561018057600080fd5b82018360208201111561019257600080fd5b803590602001918460018302840111640100000000831117156101b457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506103db945050505050565b005b6101f56004803603606081101561020d57600080fd5b81359160208101359181019060608101604082013564010000000081111561023457600080fd5b82018360208201111561024657600080fd5b8035906020019184600183028401116401000000008311171561026857600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506106a8945050505050565b6005546060908190818167ffffffffffffffff811180156102c957600080fd5b506040519080825280602002602001820160405280156102f3578160200160208202803683370190505b50905060005b8281101561034e57600760006005838154811061031257fe5b906000526020600020015481526020019081526020016000206002015482828151811061033b57fe5b60209081029190910101526001016102f9565b508060058080548060200260200160405190810160405280929190818152602001828054801561039d57602002820191906000526020600020905b815481526020019060010190808311610389575b505050505090509350935050509091565b60009081526007602052604090205460ff1690565b60008054808252600760205260409091206002015491565b6103e3610b42565b6103ec8261090d565b602080820151600090815260079091526040902080549192509060ff16801561041f575060018260400151038160020154145b61045a5760405162461bcd60e51b8152600401808060200182810382526026815260200180610c886026913960400191505060405180910390fd5b600681015415801590610474575080600201548160060154145b156104bd578160200151600254146104bd5760405162461bcd60e51b8152600401808060200182810382526031815260200180610cdd6031913960400191505060405180910390fd5b6006810154608083015151156105325782604001518110610525576040805162461bcd60e51b815260206004820152601960248201527f4f7665726c617070696e67207369676e616c7320666f756e6400000000000000604482015290519081900360640190fd5b5060608201516040830151015b60048201546005830154600384015467ffffffffffffffff909216916002600019600183161561010002019091160415610573575060208401516001909101905b84604001518314156105c6576005805486516001820180845560009384527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0909201558651825260066020526040909120555b6040805160e0810182526001808252602088810151818401908152898501518486019081526080808c01516060870190815267ffffffffffffffff8a169187019190915260a0860188905260c086018a90528b51600090815260078552969096208551815460ff191690151517815591519382019390935591516002830155925180519293919261065d9260038501920190610b77565b50608082015160048201805467ffffffffffffffff191667ffffffffffffffff90921691909117905560a0820151600582015560c09091015160069091015550509151600055505050565b60008281526007602052604090206002015483146106f75760405162461bcd60e51b815260040180806020018281038252602f815260200180610cae602f913960400191505060405180910390fd5b60028054600354600480546040805160206101006001851615026000190190931696909604601f810183900483028701830190915280865293946000946107a8948a948a9467ffffffffffffffff9092169392909183018282801561079d5780601f106107725761010080835404028352916020019161079d565b820191906000526020600020905b81548152906001019060200180831161078057829003601f168201915b505050505087610a00565b600081815260076020526040902060028281558101546001559091505b828214610905575060008181526007602090815260408083206001810154600690935292205490929080156108875760055460001991820191810182146108535760006005600183038154811061081857fe5b90600052602060002001549050806005848154811061083357fe5b600091825260208083209091019290925591825260069052604090208290555b600580548061085e57fe5b600082815260208082208301600019908101839055909201909255848252600690526040812055505b8260060154836002015414156108fe57600583015460009081526007602052604090206003805467ffffffffffffffff198116600167ffffffffffffffff928316810190921617825590820180546108f5926004929160026101009282161592909202600019011604610bf5565b50505050610905565b50506107c5565b505050505050565b610915610b42565b60008060008060008651602088016040516020810160208101602081016020810160a08588886010600019fa61094a57600080fd5b84519b5083519a508251995081519850805197505050505050505060608167ffffffffffffffff8111801561097e57600080fd5b506040519080825280601f01601f1916602001820160405280156109a9576020820181803683370190505b50905081156109d35787516020890160208301848184846011600019fa6109cf57600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b600060608686868686604051602001808681526020018581526020018467ffffffffffffffff1667ffffffffffffffff1681526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015610a73578181015183820152602001610a5b565b50505050905090810190601f168015610aa05780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015610ad3578181015183820152602001610abb565b50505050905090810190601f168015610b005780820380516001836020036101000a031916815260200191505b50975050505050505050604051602081830303815290604052905080516020820160008083836012600019fa610b3557600080fd5b5095979650505050505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610bb857805160ff1916838001178555610be5565b82800160010185558215610be5579182015b82811115610be5578251825591602001919060010190610bca565b50610bf1929150610c6a565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610c2e5780548555610be5565b82800160010185558215610be557600052602060002091601f016020900482015b82811115610be5578254825591600101919060010190610c4f565b610c8491905b80821115610bf15760008155600101610c70565b9056fe4d697373696e6720706172656e74206865616465722066726f6d207468652073746f726167654d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f726167654d697373696e672072657175697265642066696e616c6974792070726f6f6620666f7220706172656e7420686561646572a264697066735822122034edec1aca7ff06bb5846092314f1aea2738d1856546c4fea9ede700d0ae364864736f6c63430006060033") + eth_contract_code: hex::decode("60806040523480156200001157600080fd5b50604051620011e1380380620011e1833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b506040818152602083015192018051929491939192846401000000008211156200010f57600080fd5b9083019060208201858111156200012557600080fd5b82516401000000008111828201881017156200014057600080fd5b82525081516020918201929091019080838360005b838110156200016f57818101518382015260200162000155565b50505050905090810190601f1680156200019d5780820380516001836020036101000a031916815260200191505b50604052505050620001ae620003d5565b620001c2846001600160e01b03620002dc16565b805160008181556002918255604080840180516001908155825160e08101845281815260208088015181830190815293518286019081526080808a0151606085019081526001600160401b038e169185019190915260a0840188905260c084018890528951885260078352959096208251815460ff191690151517815593519284019290925593519482019490945590518051949550919390926200026f9260038501929101906200040a565b506080820151600482810180546001600160401b03199081166001600160401b039485161790915560a0850151600585015560c09094015160069093019290925560038054909316908616179091558251620002d1919060208501906200040a565b5050505050620004af565b620002e6620003d5565b60008060008060008651602088016040516020810160208101602081016020810160a08588886010600019fa6200031c57600080fd5b84519b5083519a50825199508151985080519750505050505050506060816001600160401b03811180156200035057600080fd5b506040519080825280601f01601f1916602001820160405280156200037c576020820181803683370190505b5090508115620003a85787516020890160208301848184846011600019fa620003a457600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200044d57805160ff19168380011785556200047d565b828001600101855582156200047d579182015b828111156200047d57825182559160200191906001019062000460565b506200048b9291506200048f565b5090565b620004ac91905b808211156200048b576000815560010162000496565b90565b610d2280620004bf6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063374c2c261461005c578063871ebe18146100fd578063d96a2deb1461012e578063e7af07791461014f578063fae71ae8146101f7575b600080fd5b6100646102a9565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156100a8578181015183820152602001610090565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156100e75781810151838201526020016100cf565b5050505090500194505050505060405180910390f35b61011a6004803603602081101561011357600080fd5b50356103ae565b604080519115158252519081900360200190f35b6101366103c3565b6040805192835260208301919091528051918290030190f35b6101f56004803603602081101561016557600080fd5b81019060208101813564010000000081111561018057600080fd5b82018360208201111561019257600080fd5b803590602001918460018302840111640100000000831117156101b457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506103db945050505050565b005b6101f56004803603606081101561020d57600080fd5b81359160208101359181019060608101604082013564010000000081111561023457600080fd5b82018360208201111561024657600080fd5b8035906020019184600183028401116401000000008311171561026857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610687945050505050565b6005546060908190818167ffffffffffffffff811180156102c957600080fd5b506040519080825280602002602001820160405280156102f3578160200160208202803683370190505b50905060005b8281101561034e57600760006005838154811061031257fe5b906000526020600020015481526020019081526020016000206002015482828151811061033b57fe5b60209081029190910101526001016102f9565b508060058080548060200260200160405190810160405280929190818152602001828054801561039d57602002820191906000526020600020905b815481526020019060010190808311610389575b505050505090509350935050509091565b60009081526007602052604090205460ff1690565b60008054808252600760205260409091206002015491565b6103e3610b21565b6103ec826108ec565b602080820151600090815260079091526040902080549192509060ff16801561041f575060018260400151038160020154145b61045a5760405162461bcd60e51b8152600401808060200182810382526026815260200180610c676026913960400191505060405180910390fd5b600681015415801590610474575080600201548160060154145b156104bd578160200151600254146104bd5760405162461bcd60e51b8152600401808060200182810382526031815260200180610cbc6031913960400191505060405180910390fd5b60048101546005820154600683015460808501515167ffffffffffffffff9093169215610552578460400151811061053c576040805162461bcd60e51b815260206004820152601960248201527f4f7665726c617070696e67207369676e616c7320666f756e6400000000000000604482015290519081900360640190fd5b5050825160608401516040850151600190930192015b84604001518114156105a5576005805486516001820180845560009384527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0909201558651825260066020526040909120555b6040805160e0810182526001808252602088810151818401908152898501518486019081526080808c01516060870190815267ffffffffffffffff8b169187019190915260a0860189905260c086018890528b51600090815260078552969096208551815460ff191690151517815591519382019390935591516002830155925180519293919261063c9260038501920190610b56565b50608082015160048201805467ffffffffffffffff191667ffffffffffffffff90921691909117905560a0820151600582015560c09091015160069091015550509151600055505050565b60008281526007602052604090206002015483146106d65760405162461bcd60e51b815260040180806020018281038252602f815260200180610c8d602f913960400191505060405180910390fd5b60028054600354600480546040805160206101006001851615026000190190931696909604601f81018390048302870183019091528086529394600094610787948a948a9467ffffffffffffffff9092169392909183018282801561077c5780601f106107515761010080835404028352916020019161077c565b820191906000526020600020905b81548152906001019060200180831161075f57829003601f168201915b5050505050876109df565b600081815260076020526040902060028281558101546001559091505b8282146108e457506000818152600760209081526040808320600181015460069093529220549092908015610866576005546000199182019181018214610832576000600560018303815481106107f757fe5b90600052602060002001549050806005848154811061081257fe5b600091825260208083209091019290925591825260069052604090208290555b600580548061083d57fe5b600082815260208082208301600019908101839055909201909255848252600690526040812055505b8260060154836002015414156108dd57600583015460009081526007602052604090206003805467ffffffffffffffff198116600167ffffffffffffffff928316810190921617825590820180546108d4926004929160026101009282161592909202600019011604610bd4565b505050506108e4565b50506107a4565b505050505050565b6108f4610b21565b60008060008060008651602088016040516020810160208101602081016020810160a08588886010600019fa61092957600080fd5b84519b5083519a508251995081519850805197505050505050505060608167ffffffffffffffff8111801561095d57600080fd5b506040519080825280601f01601f191660200182016040528015610988576020820181803683370190505b50905081156109b25787516020890160208301848184846011600019fa6109ae57600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b600060608686868686604051602001808681526020018581526020018467ffffffffffffffff1667ffffffffffffffff1681526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015610a52578181015183820152602001610a3a565b50505050905090810190601f168015610a7f5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015610ab2578181015183820152602001610a9a565b50505050905090810190601f168015610adf5780820380516001836020036101000a031916815260200191505b50975050505050505050604051602081830303815290604052905080516020820160008083836012600019fa610b1457600080fd5b5095979650505050505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610b9757805160ff1916838001178555610bc4565b82800160010185558215610bc4579182015b82811115610bc4578251825591602001919060010190610ba9565b50610bd0929150610c49565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610c0d5780548555610bc4565b82800160010185558215610bc457600052602060002091601f016020900482015b82811115610bc4578254825591600101919060010190610c2e565b610c6391905b80821115610bd05760008155600101610c4f565b9056fe4d697373696e6720706172656e74206865616465722066726f6d207468652073746f726167654d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f726167654d697373696e672072657175697265642066696e616c6974792070726f6f6620666f7220706172656e7420686561646572a264697066735822122040c7224d3ac66e5c75701f73ebc76ffff6a734c28ba8c666df7720d28268b2cc64736f6c63430006060033") .expect("code is hardcoded, thus valid; qed"), sub: Default::default(), sub_initial_authorities_set_id: None, From e3f8bac6540d2cb1bdd3ce0b485c69eac9135c5d Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 22 Apr 2020 13:00:57 +0300 Subject: [PATCH 43/92] at least 1 validator required --- bin/node/runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 22d915aa43..90b8dc3ff0 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -273,7 +273,7 @@ impl pallet_session::SessionManager for ShiftSessionManager { }); let available_validators_count = available_validators.len(); - let count = 2 * available_validators_count / 3; + let count = sp_std::cmp::max(1, 2 * available_validators_count / 3); let offset = session_index as usize % available_validators_count; let end = offset + count; let session_validators = match end.overflowing_sub(available_validators_count) { From e95fe307e647704679fcf4688339a29986cb9216 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 22 Apr 2020 13:15:52 +0300 Subject: [PATCH 44/92] shift_session_manager_works --- bin/node/runtime/src/lib.rs | 84 ++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 14 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 90b8dc3ff0..0936f61cb9 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -251,6 +251,30 @@ impl pallet_session::Trait for Runtime { } pub struct ShiftSessionManager; + +impl ShiftSessionManager { + /// Select validators for session. + fn select_validators( + session_index: sp_staking::SessionIndex, + available_validators: &[AccountId], + ) -> Vec { + let available_validators_count = available_validators.len(); + let count = sp_std::cmp::max(1, 2 * available_validators_count / 3); + let offset = session_index as usize % available_validators_count; + let end = offset + count; + let session_validators = match end.overflowing_sub(available_validators_count) { + (wrapped_end, false) if wrapped_end != 0 => + available_validators[offset..].iter() + .chain(available_validators[..wrapped_end].iter()) + .cloned() + .collect(), + _ => available_validators[offset..end].to_vec(), + }; + + session_validators + } +} + impl pallet_session::SessionManager for ShiftSessionManager { fn end_session(_: sp_staking::SessionIndex) {} fn new_session(session_index: sp_staking::SessionIndex) -> Option> { @@ -272,20 +296,7 @@ impl pallet_session::SessionManager for ShiftSessionManager { validators }); - let available_validators_count = available_validators.len(); - let count = sp_std::cmp::max(1, 2 * available_validators_count / 3); - let offset = session_index as usize % available_validators_count; - let end = offset + count; - let session_validators = match end.overflowing_sub(available_validators_count) { - (wrapped_end, false) if wrapped_end != 0 => - available_validators[offset..].iter() - .chain(available_validators[..wrapped_end].iter()) - .cloned() - .collect(), - _ => available_validators[offset..end].to_vec(), - }; - - Some(session_validators) + Some(Self::select_validators(session_index, &available_validators)) } } @@ -447,3 +458,48 @@ impl_runtime_apis! { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn shift_session_manager_works() { + let acc1 = AccountId::from([1u8; 32]); + let acc2 = AccountId::from([2u8; 32]); + let acc3 = AccountId::from([3u8; 32]); + let acc4 = AccountId::from([4u8; 32]); + let acc5 = AccountId::from([5u8; 32]); + let all_accs = vec![acc1.clone(), acc2.clone(), acc3.clone(), acc4.clone(), acc5.clone()]; + + // at least 1 validator is selected + assert_eq!( + ShiftSessionManager::select_validators(0, &[acc1.clone()]), + vec![acc1.clone()], + ); + + // at session#0, shift is also 0 + assert_eq!( + ShiftSessionManager::select_validators(0, &all_accs), + vec![acc1.clone(), acc2.clone(), acc3.clone()], + ); + + // at session#1, shift is also 1 + assert_eq!( + ShiftSessionManager::select_validators(1, &all_accs), + vec![acc2.clone(), acc3.clone(), acc4.clone()], + ); + + // at session#3, we're wrapping + assert_eq!( + ShiftSessionManager::select_validators(3, &all_accs), + vec![acc4, acc5, acc1.clone()], + ); + + // at session#5, we're starting from the beginning again + assert_eq!( + ShiftSessionManager::select_validators(5, &all_accs), + vec![acc1, acc2, acc3], + ); + } +} From 0ba79b1380bacf8bc7eb00979115182575264f23 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 22 Apr 2020 13:16:28 +0300 Subject: [PATCH 45/92] cargo fmt --all --- relays/ethereum/src/substrate_types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/substrate_types.rs b/relays/ethereum/src/substrate_types.rs index 3d15ec95dd..d657f0269d 100644 --- a/relays/ethereum/src/substrate_types.rs +++ b/relays/ethereum/src/substrate_types.rs @@ -14,12 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use codec::Encode; use crate::ethereum_types::{ Header as EthereumHeader, Receipt as EthereumReceipt, HEADER_ID_PROOF as ETHEREUM_HEADER_ID_PROOF, RECEIPT_GAS_USED_PROOF as ETHEREUM_RECEIPT_GAS_USED_PROOF, }; use crate::sync_types::{HeaderId, HeadersSyncPipeline, QueuedHeader, SourceHeader}; +use codec::Encode; pub use sp_bridge_eth_poa::{ Address, Bloom, Bytes, Header as SubstrateEthereumHeader, LogEntry as SubstrateEthereumLogEntry, Receipt as SubstrateEthereumReceipt, TransactionOutcome as SubstrateEthereumTransactionOutcome, H256, U256, From 5123adc9a23cd25c387362d35c8344b45463503d Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 23 Apr 2020 09:49:08 +0300 Subject: [PATCH 46/92] solidity contract removed --- .../contracts/substrate-bridge.sol | 327 ------------------ 1 file changed, 327 deletions(-) delete mode 100644 modules/ethereum-contract/contracts/substrate-bridge.sol diff --git a/modules/ethereum-contract/contracts/substrate-bridge.sol b/modules/ethereum-contract/contracts/substrate-bridge.sol deleted file mode 100644 index 9e26fe266d..0000000000 --- a/modules/ethereum-contract/contracts/substrate-bridge.sol +++ /dev/null @@ -1,327 +0,0 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity Bridges Common is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity Bridges Common. If not, see . - -pragma solidity ^0.6.4; - -// for simplicity, this contract works with 32-bit headers hashes and headers -// numbers that can be represented as uint256 (supporting uint256 arithmetics) - -/// @title Substrate-to-PoA Bridge Contract. -contract SubstrateBridge { - /// Parsed header. - struct ParsedHeader { - /// Header hash. - bytes32 hash; - /// Parent header hash. - bytes32 parentHash; - /// Header number. - uint256 number; - /// Validators set change signal delay. - uint256 signalDelay; - /// Validators set change signal. - bytes signal; - } - - /// Header as it is stored in the storage. - struct Header { - /// Flag to ensure that the header exists :/ - bool isKnown; - - /// Parent header hash. - bytes32 parentHash; - /// Header number. - uint256 number; - - /// Validators set change signal. - bytes signal; - - /// ID of validators set that must finalize this header. This equals to same - /// field of the parent + 1 if parent header should enact new set. - uint64 validatorsSetId; - /// Hash of the latest header of this fork that has emitted last validators set - /// change signal. - bytes32 prevSignalHeaderHash; - /// Number of the header where latest signal of this fork must be enacted. - uint256 prevSignalTargetNumber; - } - - /// Initializes bridge contract. - /// @param rawInitialHeader Raw finalized header that will be ancestor of all importing headers. - /// @param initialValidatorsSetId ID of validators set that must finalize direct children of the initial header. - /// @param initialValidatorsSet Raw validators set that must finalize direct children of the initial header. - constructor( - bytes memory rawInitialHeader, - uint64 initialValidatorsSetId, - bytes memory initialValidatorsSet - ) public { - // parse and save header - ParsedHeader memory header = parseSubstrateHeader(rawInitialHeader); - lastImportedHeaderHash = header.hash; - bestFinalizedHeaderHash = header.hash; - bestFinalizedHeaderNumber = header.number; - headerByHash[header.hash] = Header({ - isKnown: true, - parentHash: header.parentHash, - number: header.number, - signal: header.signal, - validatorsSetId: initialValidatorsSetId, - prevSignalHeaderHash: bytes32(0), - prevSignalTargetNumber: 0 - }); - - // save best validators set - bestFinalizedValidatorsSetId = initialValidatorsSetId; - bestFinalizedValidatorsSet = initialValidatorsSet; - } - - /// Reject direct payments. - fallback() external { revert(); } - - /// Returns number and hash of the best known header. Best known header is - /// the last header we have received, no matter hash or number. We can't - /// verify unfinalized header => we are only signalling relay that we are - /// receiving new headers here, so honest relay can continue to submit valid - /// headers and, eventually, finality proofs. - function bestKnownHeader() public view returns (uint256, bytes32) { - Header storage lastImportedHeader = headerByHash[lastImportedHeaderHash]; - return (lastImportedHeader.number, lastImportedHeaderHash); - } - - /// Returns true if header is known to the bridge. - /// @param headerHash Hash of the header we want to check. - function isKnownHeader( - bytes32 headerHash - ) public view returns (bool) { - return headerByHash[headerHash].isKnown; - } - - /// Returns true if finality proof is required for this header. - function isFinalityProofRequired( - bytes32 headerHash - ) public view returns (bool) { - Header storage header = headerByHash[headerHash]; - return header.isKnown - && header.number > bestFinalizedHeaderNumber - && header.number == header.prevSignalTargetNumber - && header.validatorsSetId == bestFinalizedValidatorsSetId; - } - - /// Import header. - function importHeader( - bytes memory rawHeader - ) public { - // parse header - ParsedHeader memory header = parseSubstrateHeader(rawHeader); - require( - !headerByHash[header.hash].isKnown, - "Header is already known" - ); - - // check if we're able to coninue chain with this header - Header storage parentHeader = headerByHash[header.parentHash]; - require( - parentHeader.isKnown && parentHeader.number == header.number - 1, - "Missing parent header from the storage" - ); - - // forbid appending to fork until we'll get finality proof for header that - // requires it - if (parentHeader.prevSignalTargetNumber != 0 && parentHeader.prevSignalTargetNumber == parentHeader.number) { - require( - bestFinalizedHeaderHash == header.parentHash, - "Missing required finality proof for parent header" - ); - } - - // forbid overlapping signals - uint256 prevSignalTargetNumber = parentHeader.prevSignalTargetNumber; - if (header.signal.length != 0) { - require( - prevSignalTargetNumber < header.number, - "Overlapping signals found" - ); - prevSignalTargetNumber = header.number + header.signalDelay; - } - - // check if parent header has emitted validators set change signal - uint64 validatorsSetId = parentHeader.validatorsSetId; - bytes32 prevSignalHeaderHash = parentHeader.prevSignalHeaderHash; - if (parentHeader.signal.length != 0) { - prevSignalHeaderHash = header.parentHash; - validatorsSetId = validatorsSetId + 1; - } - - // store header in the storage - headerByHash[header.hash] = Header({ - isKnown: true, - parentHash: header.parentHash, - number: header.number, - signal: header.signal, - validatorsSetId: validatorsSetId, - prevSignalHeaderHash: prevSignalHeaderHash, - prevSignalTargetNumber: prevSignalTargetNumber - }); - lastImportedHeaderHash = header.hash; - } - - /// Import finality proof. - function importFinalityProof( - uint256 finalityTargetNumber, - bytes32 finalityTargetHash, - bytes memory rawFinalityProof - ) public { - // check that header that we're going to finalize is already imported - require( - headerByHash[finalityTargetHash].number == finalityTargetNumber, - "Missing finality target header from the storage" - ); - - // verify finality proof - bytes32 oldBestFinalizedHeaderHash = bestFinalizedHeaderHash; - bytes32 newBestFinalizedHeaderHash = verifyFinalityProof( - finalityTargetNumber, - finalityTargetHash, - rawFinalityProof - ); - - // remember new best finalized header - Header storage newFinalizedHeader = headerByHash[newBestFinalizedHeaderHash]; - bestFinalizedHeaderHash = newBestFinalizedHeaderHash; - bestFinalizedHeaderNumber = newFinalizedHeader.number; - - // apply validators set change signal if required - while (newBestFinalizedHeaderHash != oldBestFinalizedHeaderHash) { - newFinalizedHeader = headerByHash[newBestFinalizedHeaderHash]; - newBestFinalizedHeaderHash = newFinalizedHeader.parentHash; - // if we are finalizing header that should enact validators set change, do this - // (this only affects latest scheduled change) - if (newFinalizedHeader.number == newFinalizedHeader.prevSignalTargetNumber) { - Header storage signalHeader = headerByHash[newFinalizedHeader.prevSignalHeaderHash]; - bestFinalizedValidatorsSetId += 1; - bestFinalizedValidatorsSet = signalHeader.signal; - break; - } - } - } - - /// Parse Substrate header. - function parseSubstrateHeader( - bytes memory rawHeader - ) private view returns (ParsedHeader memory) { - bytes32 headerHash; - bytes32 headerParentHash; - uint256 headerNumber; - uint256 headerSignalDelay; - uint256 headerSignalSize; - bytes memory headerSignal; - - assembly { - // inputs - let rawHeaderSize := mload(rawHeader) - let rawHeaderPointer := add(rawHeader, 0x20) - - // output - let headerHashPointer := mload(0x40) - let headerParentHashPointer := add(headerHashPointer, 0x20) - let headerNumberPointer := add(headerParentHashPointer, 0x20) - let headerSignalDelayPointer := add(headerNumberPointer, 0x20) - let headerSignalSizePointer := add(headerSignalDelayPointer, 0x20) - - // parse substrate header - if iszero(staticcall( - not(0), - SUBSTRATE_PARSE_HEADER_BUILTIN_ADDRESS, - rawHeaderPointer, - rawHeaderSize, - headerHashPointer, - 0xA0 - )) { - revert(0, 0) - } - - // fill basic header fields - headerHash := mload(headerHashPointer) - headerParentHash := mload(headerParentHashPointer) - headerNumber := mload(headerNumberPointer) - headerSignalDelay := mload(headerSignalDelayPointer) - headerSignalSize := mload(headerSignalSizePointer) - } - - // if validators set change is signalled, read it - if (headerSignalSize != 0) { - headerSignal = new bytes(headerSignalSize); - - assembly { - // inputs - let rawHeadersSize := mload(rawHeader) - let rawHeadersPointer := add(rawHeader, 0x20) - - // output - let headerSignalPointer := add(headerSignal, 0x20) - - // get substrate header valdiators set change signal - if iszero(staticcall( - not(0), - SUBSTRATE_GET_HEADER_SIGNAL_BUILTIN_ADDRESS, - rawHeadersPointer, - rawHeadersSize, - headerSignalPointer, - headerSignalSize - )) { - revert(0, 0) - } - } - } - - return ParsedHeader({ - hash: headerHash, - parentHash: headerParentHash, - number: headerNumber, - signalDelay: headerSignalDelay, - signal: headerSignal - }); - } - - - /// Verify finality proof. - function verifyFinalityProof( - uint256 /*finalityTargetNumber*/, - bytes32 /*finalityTargetHash*/, - bytes memory /*rawFinalityProof*/ - ) private view returns (bytes32) { - return bestFinalizedHeaderHash; // TODO: call builtin instead - } - - /// Address of parse_substrate_header builtin. - uint256 constant SUBSTRATE_PARSE_HEADER_BUILTIN_ADDRESS = 0x10; - /// Address of get_substrate_validators_set_signal builtin. - uint256 constant SUBSTRATE_GET_HEADER_SIGNAL_BUILTIN_ADDRESS = 0x11; - - /// Last imported header hash. - bytes32 lastImportedHeaderHash; - - /// Best finalized header number. - uint256 bestFinalizedHeaderNumber; - /// Best finalized header hash. - bytes32 bestFinalizedHeaderHash; - /// Best finalized validators set id. - uint64 bestFinalizedValidatorsSetId; - /// Best finalized validators set. - bytes bestFinalizedValidatorsSet; - - /// Map of headers by their hashes. - mapping (bytes32 => Header) headerByHash; -} From d9efb22bf8aceb47c5e8919c9b54f091dfd94da8 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 23 Apr 2020 10:34:39 +0300 Subject: [PATCH 47/92] consts --- relays/ethereum/src/ethereum_sync_loop.rs | 10 ++++++++-- relays/ethereum/src/substrate_sync_loop.rs | 4 +++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index dd0be0e9aa..de7688f193 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -27,6 +27,12 @@ use web3::types::H256; const ETHEREUM_TICK_INTERVAL_MS: u64 = 10_000; /// Interval (in ms) at which we check new Substrate blocks. const SUBSTRATE_TICK_INTERVAL_MS: u64 = 5_000; +/// Max number of headers in single submit transaction. +const MAX_HEADERS_IN_SINGLE_SUBMIT: usize = 32; +/// Max total size of headers in single submit transaction. This only affects signed +/// submissions, when several headers are submitted at once. 4096 is the maximal **expected** +/// size of the Ethereum header + transactions receipts (if they're required). +const MAX_HEADERS_SIZE_IN_SINGLE_SUBMIT: usize = MAX_HEADERS_IN_SINGLE_SUBMIT * 4096; /// Ethereum synchronization parameters. pub struct EthereumSyncParams { @@ -49,8 +55,8 @@ impl Default for EthereumSyncParams { sync_params: HeadersSyncParams { max_future_headers_to_download: 128, max_headers_in_submitted_status: 128, - max_headers_in_single_submit: 32, - max_headers_size_in_single_submit: 131_072, + max_headers_in_single_submit: MAX_HEADERS_IN_SINGLE_SUBMIT, + max_headers_size_in_single_submit: MAX_HEADERS_SIZE_IN_SINGLE_SUBMIT, prune_depth: 4096, target_tx_mode: TargetTransactionMode::Signed, }, diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index f0a020dc29..fd3bddbd80 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -60,8 +60,10 @@ impl Default for SubstrateSyncParams { sync_params: HeadersSyncParams { max_future_headers_to_download: 8, max_headers_in_submitted_status: 4, + // since we always have single Substrate header in separate Ethereum transaction, + // all max_**_in_single_submit aren't important here max_headers_in_single_submit: 4, - max_headers_size_in_single_submit: 131_072, + max_headers_size_in_single_submit: std::usize::MAX, prune_depth: 256, target_tx_mode: TargetTransactionMode::Signed, }, From 16a06f8f50783429baaa165f35a576b41d2e7861 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 28 Apr 2020 08:55:14 +0300 Subject: [PATCH 48/92] extracted solc compilation details to separate file --- relays/ethereum/res/substrate-bridge-metadata.txt | 5 +++++ relays/ethereum/src/ethereum_deploy_contract.rs | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 relays/ethereum/res/substrate-bridge-metadata.txt diff --git a/relays/ethereum/res/substrate-bridge-metadata.txt b/relays/ethereum/res/substrate-bridge-metadata.txt new file mode 100644 index 0000000000..0dc5d853f2 --- /dev/null +++ b/relays/ethereum/res/substrate-bridge-metadata.txt @@ -0,0 +1,5 @@ +Last Change Date: 2020-04-28 +Solc version: 0.6.6+commit.6c089d02 +Source hash (keccak256): 0xdc46aff04e37129265223e507d17f1407a70cb1ecea3230e1eaa77a17586724d +Source gist: https://gist.github.com/svyatonik/876b388f9507a8de242cb2db9547c4f0 +Compiler flags used (command to produce the file): `docker run -i ethereum/solc:0.6.6 --optimize --bin - < substrate-bridge.sol` \ No newline at end of file diff --git a/relays/ethereum/src/ethereum_deploy_contract.rs b/relays/ethereum/src/ethereum_deploy_contract.rs index d35b640c86..bd8750abe6 100644 --- a/relays/ethereum/src/ethereum_deploy_contract.rs +++ b/relays/ethereum/src/ethereum_deploy_contract.rs @@ -44,7 +44,6 @@ impl Default for EthereumDeployContractParams { EthereumDeployContractParams { eth: Default::default(), eth_sign: Default::default(), - // compiler: 0.6.6+commit.6c089d02 + optimization eth_contract_code: hex::decode(include_str!("../res/substrate-bridge-bytecode.hex")) .expect("code is hardcoded, thus valid; qed"), sub: Default::default(), From 09119214e4dd8998c06e1595dfd1de4cb800bcaa Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 28 Apr 2020 08:58:26 +0300 Subject: [PATCH 49/92] removed (obsolete in future Vec justification) --- modules/ethereum-contract/builtin/src/lib.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/modules/ethereum-contract/builtin/src/lib.rs b/modules/ethereum-contract/builtin/src/lib.rs index fc86d5d7ef..3249307ac9 100644 --- a/modules/ethereum-contract/builtin/src/lib.rs +++ b/modules/ethereum-contract/builtin/src/lib.rs @@ -15,7 +15,7 @@ // along with Parity Bridges Common. If not, see . use bridge_node_runtime::{BlockNumber, Hash, Header as RuntimeHeader}; -use codec::{Decode, Encode}; +use codec::Decode; use sp_blockchain::Error as ClientError; /// Builtin errors. @@ -53,15 +53,6 @@ pub struct ValidatorsSetSignal { pub validators: Vec, } -/// All types of finality proofs. -#[derive(Decode, Encode)] -pub enum FinalityProof { - /// GRANDPA justification. - Justification(Vec), - /// GRANDPA commit. - Commit(Vec), -} - /// Parse Substrate header. pub fn parse_substrate_header(raw_header: &[u8]) -> Result { RuntimeHeader::decode(&mut &raw_header[..]) From da6f9b12a88c5dacc5f8b4cc7cd676fa7087117b Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 28 Apr 2020 09:13:09 +0300 Subject: [PATCH 50/92] fixed cli option description --- relays/ethereum/src/cli.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/cli.yml b/relays/ethereum/src/cli.yml index a934c1d171..4cb33fd7b9 100644 --- a/relays/ethereum/src/cli.yml +++ b/relays/ethereum/src/cli.yml @@ -95,7 +95,7 @@ subcommands: - eth-contract-code: long: eth-contract-code value_name: ETH_CONTRACT_CODE - help: Code of bridge contract. + help: Bytecode of bridge contract. takes_value: true - sub-host: long: sub-host From 427ef9bfae5460fcb6b1122282c4bc9b81dbb5dd Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 28 Apr 2020 09:19:48 +0300 Subject: [PATCH 51/92] fix typos --- relays/ethereum/src/ethereum_client.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index 93368f3977..f9c96a6389 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -186,11 +186,11 @@ pub async fn header_by_hash(client: Client, hash: H256) -> (Client, Result, + transactions: Vec, ) -> (Client, Result<(EthereumHeaderId, Vec), Error>) { - let mut transactions_receipts = Vec::with_capacity(transacactions.len()); - for transacaction in transacactions { - let (next_client, transaction_receipt) = bail_on_error!(transaction_receipt(client, transacaction).await); + let mut transactions_receipts = Vec::with_capacity(transactions.len()); + for transaction in transactions { + let (next_client, transaction_receipt) = bail_on_error!(transaction_receipt(client, transaction).await); transactions_receipts.push(transaction_receipt); client = next_client; } From bbdad9e2a35084152632c667c03f49d48f09d8ff Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 28 Apr 2020 09:21:02 +0300 Subject: [PATCH 52/92] fix grumble --- relays/ethereum/src/ethereum_client.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index f9c96a6389..ed92eeee2e 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -281,7 +281,7 @@ pub async fn submit_substrate_headers( let ids = headers.iter().map(|header| header.id()).collect(); for header in headers { - let (ret_client, _) = bail_on_error!( + client = bail_on_error!( submit_ethereum_transaction( client, ¶ms, @@ -291,10 +291,9 @@ pub async fn submit_substrate_headers( bridge_contract::functions::import_header::encode_input(header.extract().0.encode(),), ) .await - ); + ).0; nonce += 1.into(); - client = ret_client; } (client, Ok(ids)) From d1f8bb0d6ba79b8056bd01726381dbbb9f8806c9 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 28 Apr 2020 09:28:57 +0300 Subject: [PATCH 53/92] extracted constants --- relays/ethereum/src/ethereum_sync_loop.rs | 12 +++++++++--- relays/ethereum/src/substrate_sync_loop.rs | 12 +++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index de7688f193..06bc570d07 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -33,6 +33,12 @@ const MAX_HEADERS_IN_SINGLE_SUBMIT: usize = 32; /// submissions, when several headers are submitted at once. 4096 is the maximal **expected** /// size of the Ethereum header + transactions receipts (if they're required). const MAX_HEADERS_SIZE_IN_SINGLE_SUBMIT: usize = MAX_HEADERS_IN_SINGLE_SUBMIT * 4096; +/// Max Ethereum headers we want to have in all 'before-submitted' states. +const MAX_FUTURE_HEADERS_TO_DOWNLOAD: usize = 128; +/// Max Ethereum headers count we want to have in 'submitted' state. +const MAX_SUBMITTED_HEADERS: usize = 128; +/// Max depth of in-memory headers in all states, before we'll forget about them. +const PRUNE_DEPTH: u32 = 4096; /// Ethereum synchronization parameters. pub struct EthereumSyncParams { @@ -53,11 +59,11 @@ impl Default for EthereumSyncParams { sub: Default::default(), sub_sign: Default::default(), sync_params: HeadersSyncParams { - max_future_headers_to_download: 128, - max_headers_in_submitted_status: 128, + max_future_headers_to_download: MAX_FUTURE_HEADERS_TO_DOWNLOAD, + max_headers_in_submitted_status: MAX_SUBMITTED_HEADERS, max_headers_in_single_submit: MAX_HEADERS_IN_SINGLE_SUBMIT, max_headers_size_in_single_submit: MAX_HEADERS_SIZE_IN_SINGLE_SUBMIT, - prune_depth: 4096, + prune_depth: PRUNE_DEPTH, target_tx_mode: TargetTransactionMode::Signed, }, } diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index fd3bddbd80..45d19bdd50 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -30,6 +30,12 @@ use std::{future::Future, pin::Pin}; const SUBSTRATE_TICK_INTERVAL_MS: u64 = 10_000; /// Interval (in ms) at which we check new Ethereum blocks. const ETHEREUM_TICK_INTERVAL_MS: u64 = 5_000; +/// Max Ethereum headers we want to have in all 'before-submitted' states. +const MAX_FUTURE_HEADERS_TO_DOWNLOAD: usize = 8; +/// Max Ethereum headers count we want to have in 'submitted' state. +const MAX_SUBMITTED_HEADERS: usize = 4; +/// Max depth of in-memory headers in all states, before we'll forget about them. +const PRUNE_DEPTH: u32 = 256; /// Substrate synchronization parameters. #[derive(Debug)] @@ -58,13 +64,13 @@ impl Default for SubstrateSyncParams { .expect("address is hardcoded, thus valid; qed"), sub: Default::default(), sync_params: HeadersSyncParams { - max_future_headers_to_download: 8, - max_headers_in_submitted_status: 4, + max_future_headers_to_download: MAX_FUTURE_HEADERS_TO_DOWNLOAD, + max_headers_in_submitted_status: MAX_SUBMITTED_HEADERS, // since we always have single Substrate header in separate Ethereum transaction, // all max_**_in_single_submit aren't important here max_headers_in_single_submit: 4, max_headers_size_in_single_submit: std::usize::MAX, - prune_depth: 256, + prune_depth: PRUNE_DEPTH, target_tx_mode: TargetTransactionMode::Signed, }, } From 042d8fe13f1063a691173073b59b3f3712c79ced Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 28 Apr 2020 09:46:07 +0300 Subject: [PATCH 54/92] log decoded header --- relays/ethereum/src/ethereum_deploy_contract.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/relays/ethereum/src/ethereum_deploy_contract.rs b/relays/ethereum/src/ethereum_deploy_contract.rs index bd8750abe6..eb9f66be92 100644 --- a/relays/ethereum/src/ethereum_deploy_contract.rs +++ b/relays/ethereum/src/ethereum_deploy_contract.rs @@ -74,7 +74,8 @@ pub fn run(params: EthereumDeployContractParams) { log::info!( target: "bridge", - "Deploying Ethereum contract.\r\n\tInitial header: {}\r\n\tInitial authorities set ID: {}\r\n\tInitial authorities set: {}", + "Deploying Ethereum contract.\r\n\tInitial header: {:?}\r\n\tInitial header encoded: {}\r\n\tInitial authorities set ID: {}\r\n\tInitial authorities set: {}", + initial_header, hex::encode(&initial_header), initial_set_id, hex::encode(&initial_set), From 736c545fff26dbfb3e879d6a501584e011057457 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 28 Apr 2020 11:54:01 +0300 Subject: [PATCH 55/92] new substrate version + actually verify justification --- Cargo.lock | 1424 ++++++++++-------- bin/node/node/Cargo.toml | 38 +- bin/node/runtime/Cargo.toml | 52 +- bin/node/runtime/src/lib.rs | 34 +- modules/ethereum-contract/builtin/Cargo.toml | 15 +- modules/ethereum-contract/builtin/src/lib.rs | 149 +- modules/ethereum/Cargo.toml | 10 +- modules/ethereum/src/lib.rs | 18 +- modules/substrate/Cargo.toml | 18 +- modules/substrate/src/lib.rs | 6 +- primitives/ethereum-poa/Cargo.toml | 8 +- relays/ethereum/Cargo.toml | 12 +- relays/substrate/Cargo.toml | 6 +- 13 files changed, 927 insertions(+), 863 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 95e24f3d71..25451d2457 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,7 +46,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" dependencies = [ "block-cipher-trait", - "byteorder 1.3.4", + "byteorder", "opaque-debug", ] @@ -88,6 +88,17 @@ dependencies = [ "memchr", ] +[[package]] +name = "alga" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f823d037a7ec6ea2197046bafd4ae150e6bc36f9ca347404f46a46823fa84f2" +dependencies = [ + "approx", + "num-complex", + "num-traits 0.2.11", +] + [[package]] name = "ansi_term" version = "0.11.0" @@ -124,6 +135,15 @@ dependencies = [ "xdg", ] +[[package]] +name = "approx" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" +dependencies = [ + "num-traits 0.2.11", +] + [[package]] name = "arc-swap" version = "0.4.5" @@ -240,11 +260,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce6977f57fa68da77ffe5542950d47e9c23d65f5bc7cb0a9f8700996913eec7" dependencies = [ "futures 0.3.4", - "rustls", + "rustls 0.16.0", "webpki", "webpki-roots 0.17.0", ] +[[package]] +name = "async-tls" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95fd83426b89b034bf4e9ceb9c533c2f2386b813fd3dcae0a425ec6f1837d78a" +dependencies = [ + "futures 0.3.4", + "rustls 0.17.0", + "webpki", + "webpki-roots 0.19.0", +] + [[package]] name = "atty" version = "0.2.14" @@ -308,7 +340,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" dependencies = [ - "byteorder 1.3.4", + "byteorder", "safemem", ] @@ -318,7 +350,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" dependencies = [ - "byteorder 1.3.4", + "byteorder", ] [[package]] @@ -401,6 +433,28 @@ dependencies = [ "constant_time_eq", ] +[[package]] +name = "blake2b_simd" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" +dependencies = [ + "arrayref", + "arrayvec 0.5.1", + "constant_time_eq", +] + +[[package]] +name = "blake2s_simd" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab9e07352b829279624ceb7c64adb4f585dacdb81d35cafae81139ccd617cf44" +dependencies = [ + "arrayref", + "arrayvec 0.5.1", + "constant_time_eq", +] + [[package]] name = "block-buffer" version = "0.7.3" @@ -409,7 +463,7 @@ checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" dependencies = [ "block-padding", "byte-tools", - "byteorder 1.3.4", + "byteorder", "generic-array", ] @@ -523,12 +577,6 @@ dependencies = [ "slab 0.4.2", ] -[[package]] -name = "bs58" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c95ee6bba9d950218b6cc910cf62bc9e0a171d0f4537e3627b0f54d08549b188" - [[package]] name = "bs58" version = "0.3.0" @@ -562,12 +610,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" -[[package]] -name = "byteorder" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" - [[package]] name = "byteorder" version = "1.3.4" @@ -580,7 +622,7 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" dependencies = [ - "byteorder 1.3.4", + "byteorder", "either", "iovec", ] @@ -637,7 +679,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" dependencies = [ "num-integer", - "num-traits", + "num-traits 0.2.11", "time 0.1.42", ] @@ -712,32 +754,16 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" -[[package]] -name = "core-foundation" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" -dependencies = [ - "core-foundation-sys 0.6.2", - "libc", -] - [[package]] name = "core-foundation" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" dependencies = [ - "core-foundation-sys 0.7.0", + "core-foundation-sys", "libc", ] -[[package]] -name = "core-foundation-sys" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" - [[package]] name = "core-foundation-sys" version = "0.7.0" @@ -855,36 +881,13 @@ dependencies = [ "winapi 0.3.8", ] -[[package]] -name = "cuckoofilter" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dd43f7cfaffe0a386636a10baea2ee05cc50df3b77bea4a456c9572a939bf1f" -dependencies = [ - "byteorder 0.5.3", - "rand 0.3.23", -] - -[[package]] -name = "curve25519-dalek" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b7dcd30ba50cdf88b55b033456138b7c0ac4afdc436d82e1b79f370f24cc66d" -dependencies = [ - "byteorder 1.3.4", - "clear_on_drop", - "digest", - "rand_core 0.3.1", - "subtle 2.2.2", -] - [[package]] name = "curve25519-dalek" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26778518a7f6cffa1d25a44b602b62b979bd88adb9e99ffec546998cf3404839" dependencies = [ - "byteorder 1.3.4", + "byteorder", "digest", "rand_core 0.5.1", "subtle 2.2.2", @@ -929,7 +932,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" dependencies = [ - "byteorder 1.3.4", + "byteorder", "quick-error", ] @@ -946,7 +949,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978710b352437433c97b2bff193f2fb1dfd58a093f863dd95e225a19baa599a2" dependencies = [ "clear_on_drop", - "curve25519-dalek 2.0.0", + "curve25519-dalek", "rand 0.7.3", "sha2", ] @@ -957,6 +960,17 @@ version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" +[[package]] +name = "enum-primitive-derive" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2b90e520ec62c1864c8c78d637acbfe8baf5f63240f2fb8165b8325c07812dd" +dependencies = [ + "num-traits 0.1.43", + "quote 0.3.15", + "syn 0.11.11", +] + [[package]] name = "env_logger" version = "0.7.1" @@ -1074,8 +1088,8 @@ version = "0.1.0" dependencies = [ "bridge-node-runtime", "ethereum-types 0.8.0", - "finality-grandpa", "parity-scale-codec", + "sc-finality-grandpa", "sp-blockchain", "sp-finality-grandpa", "sp-runtime", @@ -1102,7 +1116,7 @@ dependencies = [ "linked-hash-map", "log 0.4.8", "node-primitives", - "num-traits", + "num-traits 0.2.11", "pallet-transaction-payment", "parity-crypto 0.6.1", "parity-scale-codec", @@ -1139,7 +1153,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d65552d3f9f24d3085823d47bb6cdee8a42a53b2ce8f262d69c1780262dd121" dependencies = [ "ethereum-types 0.8.0", - "num-traits", + "num-traits 0.2.11", "rlp", "secp256k1 0.17.2", "serde", @@ -1245,7 +1259,7 @@ dependencies = [ "futures 0.3.4", "futures-timer 2.0.2", "log 0.4.8", - "num-traits", + "num-traits 0.2.11", "parity-scale-codec", "parking_lot 0.9.0", ] @@ -1256,8 +1270,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" dependencies = [ - "byteorder 1.3.4", - "libc", + "byteorder", "rand 0.7.3", "rustc-hex", "static_assertions", @@ -1269,7 +1282,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32529fc42e86ec06e5047092082aab9ad459b070c5d2a76b14f4f5ce70bf2e84" dependencies = [ - "byteorder 1.3.4", + "byteorder", "rand 0.7.3", "rustc-hex", "static_assertions", @@ -1317,28 +1330,33 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fork-tree" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "parity-scale-codec", ] [[package]] name = "frame-benchmarking" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ + "frame-support", + "frame-system", + "linregress", "parity-scale-codec", + "paste", "sp-api", "sp-io", + "sp-runtime", "sp-runtime-interface", "sp-std", ] [[package]] name = "frame-executive" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "frame-support", "frame-system", @@ -1347,12 +1365,13 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std", + "sp-tracing", ] [[package]] name = "frame-metadata" -version = "11.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "11.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "parity-scale-codec", "serde", @@ -1362,8 +1381,8 @@ dependencies = [ [[package]] name = "frame-support" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "bitmask", "frame-metadata", @@ -1381,13 +1400,13 @@ dependencies = [ "sp-runtime", "sp-state-machine", "sp-std", - "tracing", + "sp-tracing", ] [[package]] name = "frame-support-procedural" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "frame-support-procedural-tools", "proc-macro2 1.0.10", @@ -1397,8 +1416,8 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", @@ -1409,8 +1428,8 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "proc-macro2 1.0.10", "quote 1.0.3", @@ -1419,8 +1438,8 @@ dependencies = [ [[package]] name = "frame-system" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -1435,8 +1454,8 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "parity-scale-codec", "sp-api", @@ -1626,7 +1645,6 @@ dependencies = [ "proc-macro-hack", "proc-macro-nested", "slab 0.4.2", - "tokio-io", ] [[package]] @@ -1726,7 +1744,7 @@ version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" dependencies = [ - "byteorder 1.3.4", + "byteorder", "bytes 0.4.12", "fnv", "futures 0.1.29", @@ -1990,15 +2008,16 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.19.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ea6215c7314d450ee45970ab8b3851ab447a0e6bafdd19e31b20a42dbb7faf" +checksum = "ac965ea399ec3a25ac7d13b8affd4b8f39325cca00858ddf5eb29b79e6b14b08" dependencies = [ "bytes 0.5.4", "ct-logs", "futures-util", "hyper 0.13.4", - "rustls", + "log 0.4.8", + "rustls 0.17.0", "rustls-native-certs", "tokio 0.2.16", "tokio-rustls", @@ -2118,6 +2137,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" +[[package]] +name = "intervalier" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64fa110ec7b8f493f416eed552740d10e7030ad5f63b2308f82c9608ec2df275" +dependencies = [ + "futures 0.3.4", + "futures-timer 2.0.2", +] + [[package]] name = "iovec" version = "0.1.4" @@ -2127,6 +2156,12 @@ dependencies = [ "libc", ] +[[package]] +name = "ip_network" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ee15951c035f79eddbef745611ec962f63f4558f1dadf98ab723cc603487c6f" + [[package]] name = "ipnet" version = "2.3.0" @@ -2270,8 +2305,8 @@ version = "1.0.0" source = "git+https://github.com/paritytech/jsonrpsee.git#62da58d12321355aac76975bfedfbc3ab0fe08e3" dependencies = [ "async-std", - "async-tls", - "bs58 0.3.0", + "async-tls 0.6.0", + "bs58", "bytes 0.5.4", "fnv", "futures 0.3.4", @@ -2334,20 +2369,19 @@ dependencies = [ [[package]] name = "kvdb" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03080afe6f42cd996da9f568d6add5d7fb5ee2ea7fb7802d2d2cbd836958fd87" +checksum = "cad096c6849b2ef027fabe35c4aed356d0e3d3f586d0a8361e5e17f1e50a7ce5" dependencies = [ - "parity-bytes", "parity-util-mem", "smallvec 1.2.0", ] [[package]] name = "kvdb-memorydb" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9355274e5a9e0a7e8ef43916950eae3949024de2a8dffe4d5a6c13974a37c8e" +checksum = "4aa954d12cfac958822dfd77aab34f3eec71f103b918c4ab79ab59a36ee594ea" dependencies = [ "kvdb", "parity-util-mem", @@ -2356,9 +2390,9 @@ dependencies = [ [[package]] name = "kvdb-rocksdb" -version = "0.5.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af36fd66ccd99f3f771ae39b75aaba28b952372b6debfb971134bf1f03466ab2" +checksum = "b3f14c3a10c8894d26175e57e9e26032e6d6c49c30cbe2468c5bf5f6b64bb0be" dependencies = [ "fs-swap", "interleaved-ordered", @@ -2397,6 +2431,18 @@ version = "0.2.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" +[[package]] +name = "libflate" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9135df43b1f5d0e333385cb6e7897ecd1a43d7d11b91ac003f4d2c2d2401fdd" +dependencies = [ + "adler32", + "crc32fast", + "rle-decode-fast", + "take_mut", +] + [[package]] name = "libloading" version = "0.5.2" @@ -2407,38 +2453,37 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "libm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" + [[package]] name = "libp2p" -version = "0.16.2" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bba17ee9cac4bb89de5812159877d9b4f0a993bf41697a5a875940cd1eb71f24" +checksum = "32ea742c86405b659c358223a8f0f9f5a9eb27bb6083894c6340959b05269662" dependencies = [ "bytes 0.5.4", "futures 0.3.4", "lazy_static", "libp2p-core", "libp2p-core-derive", - "libp2p-deflate", "libp2p-dns", - "libp2p-floodsub", - "libp2p-gossipsub", "libp2p-identify", "libp2p-kad", "libp2p-mdns", "libp2p-mplex", "libp2p-noise", "libp2p-ping", - "libp2p-plaintext", - "libp2p-pnet", - "libp2p-secio", "libp2p-swarm", "libp2p-tcp", - "libp2p-uds", "libp2p-wasm-ext", "libp2p-websocket", "libp2p-yamux", - "parity-multiaddr 0.7.3", - "parity-multihash 0.2.3", + "multihash", + "parity-multiaddr 0.8.0", "parking_lot 0.10.2", "pin-project", "smallvec 1.2.0", @@ -2447,22 +2492,23 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.16.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b874594c4b29de1a29f27871feba8e6cd13aa54a8a1e8f8c7cf3dfac5ca287c" +checksum = "a1d2c17158c4dca984a77a5927aac6f0862d7f50c013470a415f93be498b5739" dependencies = [ "asn1_der", - "bs58 0.3.0", + "bs58", "ed25519-dalek", + "either", "fnv", "futures 0.3.4", "futures-timer 3.0.2", "lazy_static", "libsecp256k1", "log 0.4.8", + "multihash", "multistream-select", - "parity-multiaddr 0.7.3", - "parity-multihash 0.2.3", + "parity-multiaddr 0.8.0", "parking_lot 0.10.2", "pin-project", "prost", @@ -2473,90 +2519,37 @@ dependencies = [ "sha2", "smallvec 1.2.0", "thiserror", - "unsigned-varint 0.3.2", + "unsigned-varint", "void", "zeroize 1.1.0", ] [[package]] name = "libp2p-core-derive" -version = "0.16.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d472e9d522f588805c77801de10b957be84e10f019ca5f869fa1825b15ea9b" +checksum = "329127858e4728db5ab60c33d5ae352a999325fdf190ed022ec7d3a4685ae2e6" dependencies = [ "quote 1.0.3", "syn 1.0.17", ] -[[package]] -name = "libp2p-deflate" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e25004d4d9837b44b22c5f1a69be1724a5168fef6cff1716b5176a972c3aa62" -dependencies = [ - "flate2", - "futures 0.3.4", - "libp2p-core", -] - [[package]] name = "libp2p-dns" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b99e552f9939b606eb4b59f7f64d9b01e3f96752f47e350fc3c5fc646ed3f649" -dependencies = [ - "futures 0.3.4", - "libp2p-core", - "log 0.4.8", -] - -[[package]] -name = "libp2p-floodsub" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3234f12e44f9a50351a9807b97fe7de11eb9ae4482370392ba10da6dc90722" -dependencies = [ - "cuckoofilter", - "fnv", - "futures 0.3.4", - "libp2p-core", - "libp2p-swarm", - "prost", - "prost-build", - "rand 0.7.3", - "smallvec 1.2.0", -] - -[[package]] -name = "libp2p-gossipsub" -version = "0.16.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d46cb3e0841bd951cbf4feae56cdc081e6347836a644fb260c3ec554149b4006" +checksum = "c0d0993481203d68e5ce2f787d033fb0cac6b850659ed6c784612db678977c71" dependencies = [ - "base64 0.11.0", - "byteorder 1.3.4", - "bytes 0.5.4", - "fnv", "futures 0.3.4", - "futures_codec", "libp2p-core", - "libp2p-swarm", "log 0.4.8", - "lru", - "prost", - "prost-build", - "rand 0.7.3", - "sha2", - "smallvec 1.2.0", - "unsigned-varint 0.3.2", - "wasm-timer", ] [[package]] name = "libp2p-identify" -version = "0.16.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfeb935a9bd41263e4f3a24b988e9f4a044f3ae89ac284e83c17fe2f84e0d66b" +checksum = "a38ca3eb807789e26f41c82ca7cd2b3843c66c5587b8b5f709a2f421f3061414" dependencies = [ "futures 0.3.4", "libp2p-core", @@ -2570,9 +2563,9 @@ dependencies = [ [[package]] name = "libp2p-kad" -version = "0.16.2" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464dc8412978d40f0286be72ed9ab5e0e1386a4a06e7f174526739b5c3c1f041" +checksum = "a92cda1fb8149ea64d092a2b99d2bd7a2c309eee38ea322d02e4480bd6ee1759" dependencies = [ "arrayvec 0.5.1", "bytes 0.5.4", @@ -2583,23 +2576,23 @@ dependencies = [ "libp2p-core", "libp2p-swarm", "log 0.4.8", - "parity-multihash 0.2.3", + "multihash", "prost", "prost-build", "rand 0.7.3", "sha2", "smallvec 1.2.0", "uint", - "unsigned-varint 0.3.2", + "unsigned-varint", "void", "wasm-timer", ] [[package]] name = "libp2p-mdns" -version = "0.16.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881fcfb360c2822db9f0e6bb6f89529621556ed9a8b038313414eda5107334de" +checksum = "41e908d2aaf8ff0ec6ad1f02fe1844fd777fb0b03a68a226423630750ab99471" dependencies = [ "async-std", "data-encoding", @@ -2619,9 +2612,9 @@ dependencies = [ [[package]] name = "libp2p-mplex" -version = "0.16.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8507b37ad0eed275efcde67a023c3d85af6c80768b193845b9288e848e1af95" +checksum = "0832882b06619b2e81d74e71447753ea3c068164a0bca67847d272e856a04a02" dependencies = [ "bytes 0.5.4", "fnv", @@ -2630,16 +2623,16 @@ dependencies = [ "libp2p-core", "log 0.4.8", "parking_lot 0.10.2", - "unsigned-varint 0.3.2", + "unsigned-varint", ] [[package]] name = "libp2p-noise" -version = "0.16.2" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15a8a3d71f898beb6f854c8aae27aa1d198e0d1f2e49412261c2d90ef39675a" +checksum = "918e94a649e1139c24ee9f1f8c1f2adaba6d157b9471af787f2d9beac8c29c77" dependencies = [ - "curve25519-dalek 2.0.0", + "curve25519-dalek", "futures 0.3.4", "lazy_static", "libp2p-core", @@ -2656,9 +2649,9 @@ dependencies = [ [[package]] name = "libp2p-ping" -version = "0.16.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d22f2f228b3a828dca1cb8aa9fa331e0bc9c36510cb2c1916956e20dc85e8c" +checksum = "f9bfbf87eebb492d040f9899c5c81c9738730465ac5e78d9b7a7d086d0f07230" dependencies = [ "futures 0.3.4", "libp2p-core", @@ -2669,77 +2662,16 @@ dependencies = [ "wasm-timer", ] -[[package]] -name = "libp2p-plaintext" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56126a204d7b3382bac163143ff4125a14570b3ba76ba979103d1ae1abed1923" -dependencies = [ - "bytes 0.5.4", - "futures 0.3.4", - "futures_codec", - "libp2p-core", - "log 0.4.8", - "prost", - "prost-build", - "rw-stream-sink", - "unsigned-varint 0.3.2", - "void", -] - -[[package]] -name = "libp2p-pnet" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b916938a8868f75180aeeffcc6a516a922d165e8fa2a90b57bad989d1ccbb57a" -dependencies = [ - "futures 0.3.4", - "log 0.4.8", - "pin-project", - "rand 0.7.3", - "salsa20", - "sha3", -] - -[[package]] -name = "libp2p-secio" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1219e9ecb4945d7331a05f5ffe96a1f6e28051bfa1223d4c60353c251de0354e" -dependencies = [ - "aes-ctr", - "ctr", - "futures 0.3.4", - "hmac", - "js-sys", - "lazy_static", - "libp2p-core", - "log 0.4.8", - "parity-send-wrapper", - "pin-project", - "prost", - "prost-build", - "quicksink", - "rand 0.7.3", - "ring", - "rw-stream-sink", - "sha2", - "static_assertions", - "twofish", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - [[package]] name = "libp2p-swarm" -version = "0.16.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "275471e7c0e88ae004660866cd54f603bd8bd1f4caef541a27f50dd8640c4d4c" +checksum = "44ab289ae44cc691da0a6fe96aefa43f26c86c6c7813998e203f6d80f1860f18" dependencies = [ "futures 0.3.4", "libp2p-core", "log 0.4.8", + "rand 0.7.3", "smallvec 1.2.0", "void", "wasm-timer", @@ -2747,9 +2679,9 @@ dependencies = [ [[package]] name = "libp2p-tcp" -version = "0.16.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9e80ad4e3535345f3d666554ce347d3100453775611c05c60786bf9a1747a10" +checksum = "b37ea44823d3ed223e4605da94b50177bc520f05ae2452286700549a32d81669" dependencies = [ "async-std", "futures 0.3.4", @@ -2760,23 +2692,11 @@ dependencies = [ "log 0.4.8", ] -[[package]] -name = "libp2p-uds" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d329564a43da9d0e055a5b938633c4a8ceab1f59cec133fbc4647917c07341" -dependencies = [ - "async-std", - "futures 0.3.4", - "libp2p-core", - "log 0.4.8", -] - [[package]] name = "libp2p-wasm-ext" -version = "0.16.2" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "923581c055bc4b8c5f42d4ce5ef43e52fe5216f1ea4bc26476cb8a966ce6220b" +checksum = "e3ac7dbde0f88cad191dcdfd073b8bae28d01823e8ca313f117b6ecb914160c3" dependencies = [ "futures 0.3.4", "js-sys", @@ -2788,18 +2708,18 @@ dependencies = [ [[package]] name = "libp2p-websocket" -version = "0.16.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5351ca9eea122081c1c0f9323164d2918cac29b5a6bfe5054d4ba8ec9447cf42" +checksum = "6874c9069ce93d899df9dc7b29f129c706b2a0fdc048f11d878935352b580190" dependencies = [ - "async-tls", + "async-tls 0.7.0", "bytes 0.5.4", "either", "futures 0.3.4", "libp2p-core", "log 0.4.8", "quicksink", - "rustls", + "rustls 0.17.0", "rw-stream-sink", "soketto", "url 2.1.1", @@ -2809,9 +2729,9 @@ dependencies = [ [[package]] name = "libp2p-yamux" -version = "0.16.2" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dac30de24ccde0e67f363d71a125c587bbe6589503f664947e9b084b68a34f1" +checksum = "02f91aea50f6571e0bc6c058dc0e9b270afd41ec28dd94e9e4bf607e78b9ab87" dependencies = [ "futures 0.3.4", "libp2p-core", @@ -2875,6 +2795,17 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "linregress" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9290cf6f928576eeb9c096c6fad9d8d452a0a1a70a2bbffa6e36064eedc0aac9" +dependencies = [ + "failure", + "nalgebra", + "statrs", +] + [[package]] name = "lock_api" version = "0.3.4" @@ -2917,6 +2848,15 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" +[[package]] +name = "matrixmultiply" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4f7ec66360130972f34830bfad9ef05c6610a43938a467bcc9ab9369ab3478f" +dependencies = [ + "rawpointer", +] + [[package]] name = "maybe-uninit" version = "2.0.0" @@ -2929,6 +2869,16 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +[[package]] +name = "memmap" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +dependencies = [ + "libc", + "winapi 0.3.8", +] + [[package]] name = "memoffset" version = "0.5.4" @@ -2940,9 +2890,9 @@ dependencies = [ [[package]] name = "memory-db" -version = "0.19.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "198831fe8722331a395bc199a5d08efbc197497ef354cb4c77b969c02ffc0fc4" +checksum = "be512cb2ccb4ecbdca937fdd4a62ea5f09f8e7195466a85e4632b3d5bcce82e6" dependencies = [ "ahash 0.2.18", "hash-db", @@ -2958,13 +2908,13 @@ checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" [[package]] name = "merlin" -version = "1.3.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b0942b357c1b4d0dc43ba724674ec89c3218e6ca2b3e8269e7cb53bcecd2f6e" +checksum = "c6feca46f4fa3443a01769d768727f10c10a20fdb65e52dc16a81f0c8269bb78" dependencies = [ - "byteorder 1.3.4", + "byteorder", "keccak", - "rand_core 0.4.2", + "rand_core 0.5.1", "zeroize 1.1.0", ] @@ -3040,6 +2990,21 @@ dependencies = [ "ws2_32-sys", ] +[[package]] +name = "multihash" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47fbc227f7e2b1cb701f95404579ecb2668abbdd3c7ef7a6cbb3cc0d3b236869" +dependencies = [ + "blake2b_simd", + "blake2s_simd", + "digest", + "sha-1", + "sha2", + "sha3", + "unsigned-varint", +] + [[package]] name = "multimap" version = "0.8.1" @@ -3048,16 +3013,33 @@ checksum = "d8883adfde9756c1d30b0f519c9b8c502a94b41ac62f696453c37c7fc0a958ce" [[package]] name = "multistream-select" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f938ffe420493e77c8b6cbcc3f282283f68fc889c5dcbc8e51668d5f3a01ad94" +checksum = "74cdcf7cfb3402881e15a1f95116cb033d69b33c83d481e1234777f5ef0c3d2c" dependencies = [ "bytes 0.5.4", - "futures 0.1.29", + "futures 0.3.4", "log 0.4.8", + "pin-project", "smallvec 1.2.0", - "tokio-io", - "unsigned-varint 0.3.2", + "unsigned-varint", +] + +[[package]] +name = "nalgebra" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaa9fddbc34c8c35dd2108515587b8ce0cab396f17977b8c738568e4edb521a2" +dependencies = [ + "alga", + "approx", + "generic-array", + "matrixmultiply", + "num-complex", + "num-rational", + "num-traits 0.2.11", + "rand 0.6.5", + "typenum", ] [[package]] @@ -3082,8 +3064,8 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "security-framework 0.4.2", - "security-framework-sys 0.4.2", + "security-framework", + "security-framework-sys", "tempfile", ] @@ -3098,6 +3080,20 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "netstat2" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29449d242064c48d3057a194b049a2bdcccadda16faa18a91468677b44e8d422" +dependencies = [ + "bitflags 1.2.1", + "byteorder", + "enum-primitive-derive", + "libc", + "num-traits 0.2.11", + "thiserror", +] + [[package]] name = "nix" version = "0.17.0" @@ -3113,8 +3109,8 @@ dependencies = [ [[package]] name = "node-primitives" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "sp-core", "sp-runtime", @@ -3142,6 +3138,15 @@ dependencies = [ "version_check 0.9.1", ] +[[package]] +name = "ntapi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26e041cd983acbc087e30fcba770380cfa352d0e392e175b2344ebaf7ea0602" +dependencies = [ + "winapi 0.3.8", +] + [[package]] name = "num-bigint" version = "0.2.6" @@ -3150,7 +3155,17 @@ checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" dependencies = [ "autocfg 1.0.0", "num-integer", - "num-traits", + "num-traits 0.2.11", +] + +[[package]] +name = "num-complex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" +dependencies = [ + "autocfg 1.0.0", + "num-traits 0.2.11", ] [[package]] @@ -3160,7 +3175,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" dependencies = [ "autocfg 1.0.0", - "num-traits", + "num-traits 0.2.11", ] [[package]] @@ -3172,7 +3187,16 @@ dependencies = [ "autocfg 1.0.0", "num-bigint", "num-integer", - "num-traits", + "num-traits 0.2.11", +] + +[[package]] +name = "num-traits" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" +dependencies = [ + "num-traits 0.2.11", ] [[package]] @@ -3182,6 +3206,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" dependencies = [ "autocfg 1.0.0", + "libm", ] [[package]] @@ -3263,8 +3288,8 @@ dependencies = [ [[package]] name = "pallet-aura" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "frame-support", "frame-system", @@ -3284,8 +3309,8 @@ dependencies = [ [[package]] name = "pallet-balances" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "frame-benchmarking", "frame-support", @@ -3332,8 +3357,8 @@ dependencies = [ [[package]] name = "pallet-finality-tracker" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "frame-support", "frame-system", @@ -3348,8 +3373,8 @@ dependencies = [ [[package]] name = "pallet-grandpa" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "frame-support", "frame-system", @@ -3366,8 +3391,8 @@ dependencies = [ [[package]] name = "pallet-randomness-collective-flip" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "frame-support", "frame-system", @@ -3379,8 +3404,8 @@ dependencies = [ [[package]] name = "pallet-session" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "frame-support", "frame-system", @@ -3397,8 +3422,8 @@ dependencies = [ [[package]] name = "pallet-sudo" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "frame-support", "frame-system", @@ -3411,8 +3436,8 @@ dependencies = [ [[package]] name = "pallet-timestamp" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "frame-benchmarking", "frame-support", @@ -3421,7 +3446,6 @@ dependencies = [ "parity-scale-codec", "serde", "sp-inherents", - "sp-io", "sp-runtime", "sp-std", "sp-timestamp", @@ -3429,8 +3453,8 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "frame-support", "frame-system", @@ -3442,8 +3466,8 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "frame-support", "parity-scale-codec", @@ -3507,21 +3531,17 @@ dependencies = [ ] [[package]] -name = "parity-multiaddr" -version = "0.5.0" +name = "parity-db" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "045b3c7af871285146300da35b1932bb6e4639b66c7c98e85d06a32cbc4e8fa7" +checksum = "00d595e372d119261593297debbe4193811a4dc811d2a1ccbb8caaa6666ad7ab" dependencies = [ - "arrayref", - "bs58 0.2.5", - "byteorder 1.3.4", - "bytes 0.4.12", - "data-encoding", - "parity-multihash 0.1.3", - "percent-encoding 1.0.1", - "serde", - "unsigned-varint 0.2.3", - "url 1.7.2", + "blake2-rfc", + "crc32fast", + "libc", + "log 0.4.8", + "memmap", + "parking_lot 0.10.2", ] [[package]] @@ -3531,30 +3551,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f77055f9e81921a8cc7bebeb6cded3d128931d51f1e3dd6251f0770a6d431477" dependencies = [ "arrayref", - "bs58 0.3.0", - "byteorder 1.3.4", + "bs58", + "byteorder", "data-encoding", - "parity-multihash 0.2.3", + "parity-multihash", "percent-encoding 2.1.0", "serde", "static_assertions", - "unsigned-varint 0.3.2", + "unsigned-varint", "url 2.1.1", ] [[package]] -name = "parity-multihash" -version = "0.1.3" +name = "parity-multiaddr" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3a17dc27848fd99e4f87eb0f8c9baba6ede0a6d555400c850ca45254ef4ce3" +checksum = "4db35e222f783ef4e6661873f6c165c4eb7b65e0c408349818517d5705c2d7d3" dependencies = [ - "blake2", - "bytes 0.4.12", - "rand 0.6.5", - "sha-1", - "sha2", - "sha3", - "unsigned-varint 0.2.3", + "arrayref", + "bs58", + "byteorder", + "data-encoding", + "multihash", + "percent-encoding 2.1.0", + "serde", + "static_assertions", + "unsigned-varint", + "url 2.1.1", ] [[package]] @@ -3569,7 +3592,7 @@ dependencies = [ "sha-1", "sha2", "sha3", - "unsigned-varint 0.3.2", + "unsigned-varint", ] [[package]] @@ -3605,15 +3628,15 @@ checksum = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" [[package]] name = "parity-util-mem" -version = "0.5.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9344bc978467339b9ae688f9dcf279d1aaa0ccfc88e9a780c729b765a82d57d5" +checksum = "2c6e2583649a3ca84894d1d71da249abcfda54d5aca24733d72ca10d0f02361c" dependencies = [ "cfg-if", "impl-trait-for-tuples", "parity-util-mem-derive", "parking_lot 0.10.2", - "primitive-types 0.6.2", + "primitive-types 0.7.0", "smallvec 1.2.0", "winapi 0.3.8", ] @@ -3714,7 +3737,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" dependencies = [ "base64 0.9.3", - "byteorder 1.3.4", + "byteorder", "crypto-mac", "hmac", "rand 0.5.6", @@ -3797,6 +3820,12 @@ dependencies = [ "crunchy", ] +[[package]] +name = "platforms" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feb3b2b1033b8a60b4da6ee470325f887758c95d5320f52f9ce0df055a55940e" + [[package]] name = "ppv-lite86" version = "0.2.6" @@ -3894,32 +3923,33 @@ dependencies = [ "unicode-xid 0.2.0", ] +[[package]] +name = "procfs" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe50036aa1b71e553a4a0c48ab7baabf8aa8c7a5a61aae06bf38c2eab7430475" +dependencies = [ + "bitflags 1.2.1", + "byteorder", + "chrono", + "hex", + "lazy_static", + "libc", + "libflate", +] + [[package]] name = "prometheus" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5567486d5778e2c6455b1b90ff1c558f29e751fc018130fa182e15828e728af1" +checksum = "b0575e258dab62268e7236d7307caa38848acbda7ec7ab87bd9093791e999d20" dependencies = [ "cfg-if", "fnv", "lazy_static", "protobuf", - "quick-error", "spin", -] - -[[package]] -name = "prometheus-exporter" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" -dependencies = [ - "async-std", - "derive_more", - "futures-util", - "hyper 0.13.4", - "log 0.4.8", - "prometheus", - "tokio 0.2.16", + "thiserror", ] [[package]] @@ -3996,6 +4026,12 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "quote" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" + [[package]] name = "quote" version = "0.6.13" @@ -4070,7 +4106,7 @@ dependencies = [ "rand_isaac", "rand_jitter", "rand_os", - "rand_pcg", + "rand_pcg 0.1.2", "rand_xorshift", "winapi 0.3.8", ] @@ -4086,6 +4122,7 @@ dependencies = [ "rand_chacha 0.2.2", "rand_core 0.5.1", "rand_hc 0.2.0", + "rand_pcg 0.2.1", ] [[package]] @@ -4194,6 +4231,15 @@ dependencies = [ "rand_core 0.4.2", ] +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + [[package]] name = "rand_xorshift" version = "0.1.1" @@ -4203,6 +4249,12 @@ dependencies = [ "rand_core 0.3.1", ] +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + [[package]] name = "rayon" version = "1.3.0" @@ -4242,6 +4294,26 @@ version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +[[package]] +name = "ref-cast" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a214c7875e1b63fc1618db7c80efc0954f6156c9ff07699fd9039e255accdd1" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "602eb59cda66fcb9aec25841fb76bc01d2b34282dcdd705028da297db6f3eec8" +dependencies = [ + "proc-macro2 1.0.10", + "quote 1.0.3", + "syn 1.0.17", +] + [[package]] name = "regex" version = "1.3.6" @@ -4295,6 +4367,12 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "rle-decode-fast" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac" + [[package]] name = "rlp" version = "0.4.5" @@ -4364,16 +4442,29 @@ dependencies = [ "webpki", ] +[[package]] +name = "rustls" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1" +dependencies = [ + "base64 0.11.0", + "log 0.4.8", + "ring", + "sct", + "webpki", +] + [[package]] name = "rustls-native-certs" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51ffebdbb48c14f84eba0b715197d673aff1dd22cc1007ca647e28483bbcc307" +checksum = "a75ffeb84a6bd9d014713119542ce415db3a3e4748f0bfce1e1416cd224a23a5" dependencies = [ "openssl-probe", - "rustls", + "rustls 0.17.0", "schannel", - "security-framework 0.3.4", + "security-framework", ] [[package]] @@ -4419,36 +4510,16 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" -[[package]] -name = "salsa20" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2324b0e8c3bb9a586a571fdb3136f70e7e2c748de00a78043f86e0cff91f91fe" -dependencies = [ - "byteorder 1.3.4", - "salsa20-core", - "stream-cipher", -] - -[[package]] -name = "salsa20-core" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fe6cc1b9f5a5867853ade63099de70f042f7679e408d1ffe52821c9248e6e69" -dependencies = [ - "stream-cipher", -] - [[package]] name = "sc-basic-authorship" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "futures 0.3.4", + "futures-timer 3.0.2", "log 0.4.8", "parity-scale-codec", "sc-block-builder", - "sc-client", "sc-client-api", "sc-telemetry", "sp-api", @@ -4463,8 +4534,8 @@ dependencies = [ [[package]] name = "sc-block-builder" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -4479,8 +4550,8 @@ dependencies = [ [[package]] name = "sc-chain-spec" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "impl-trait-for-tuples", "sc-chain-spec-derive", @@ -4488,14 +4559,15 @@ dependencies = [ "sc-telemetry", "serde", "serde_json", + "sp-chain-spec", "sp-core", "sp-runtime", ] [[package]] name = "sc-chain-spec-derive" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "proc-macro-crate", "proc-macro2 1.0.10", @@ -4505,8 +4577,8 @@ dependencies = [ [[package]] name = "sc-cli" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "ansi_term 0.12.1", "app_dirs", @@ -4520,8 +4592,8 @@ dependencies = [ "lazy_static", "log 0.4.8", "names", + "nix", "parity-util-mem", - "prometheus-exporter", "regex", "rpassword", "sc-client-api", @@ -4537,15 +4609,18 @@ dependencies = [ "sp-panic-handler", "sp-runtime", "sp-state-machine", + "sp-utils", + "sp-version", "structopt", + "substrate-prometheus-endpoint", "time 0.1.42", "tokio 0.2.16", ] [[package]] name = "sc-client" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "derive_more", "fnv", @@ -4556,6 +4631,7 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.2", + "rand 0.7.3", "sc-block-builder", "sc-client-api", "sc-executor", @@ -4564,6 +4640,7 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-core", + "sp-database", "sp-externalities", "sp-inherents", "sp-keyring", @@ -4571,14 +4648,16 @@ dependencies = [ "sp-state-machine", "sp-std", "sp-trie", + "sp-utils", "sp-version", + "substrate-prometheus-endpoint", "tracing", ] [[package]] name = "sc-client-api" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "derive_more", "fnv", @@ -4586,6 +4665,7 @@ dependencies = [ "hash-db", "hex-literal", "kvdb", + "lazy_static", "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.2", @@ -4601,26 +4681,30 @@ dependencies = [ "sp-runtime", "sp-state-machine", "sp-std", + "sp-storage", "sp-transaction-pool", "sp-trie", + "sp-utils", "sp-version", + "substrate-prometheus-endpoint", ] [[package]] name = "sc-client-db" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ + "blake2-rfc", "hash-db", "kvdb", "kvdb-memorydb", "kvdb-rocksdb", "linked-hash-map", "log 0.4.8", + "parity-db", "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.2", - "rand 0.7.3", "sc-client", "sc-client-api", "sc-executor", @@ -4628,15 +4712,17 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-core", + "sp-database", "sp-runtime", "sp-state-machine", "sp-trie", + "substrate-prometheus-endpoint", ] [[package]] name = "sc-consensus-aura" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "derive_more", "futures 0.3.4", @@ -4644,6 +4730,7 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.2", + "sc-block-builder", "sc-client", "sc-client-api", "sc-consensus-slots", @@ -4665,8 +4752,8 @@ dependencies = [ [[package]] name = "sc-consensus-slots" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", @@ -4686,8 +4773,8 @@ dependencies = [ [[package]] name = "sc-executor" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "derive_more", "lazy_static", @@ -4698,6 +4785,7 @@ dependencies = [ "parking_lot 0.10.2", "sc-executor-common", "sc-executor-wasmi", + "sp-api", "sp-core", "sp-externalities", "sp-io", @@ -4712,12 +4800,13 @@ dependencies = [ [[package]] name = "sc-executor-common" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "derive_more", "log 0.4.8", "parity-scale-codec", + "parity-wasm", "sp-allocator", "sp-core", "sp-runtime-interface", @@ -4728,12 +4817,11 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "log 0.4.8", "parity-scale-codec", - "parity-wasm", "sc-executor-common", "sp-allocator", "sp-core", @@ -4744,8 +4832,8 @@ dependencies = [ [[package]] name = "sc-finality-grandpa" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "assert_matches", "finality-grandpa", @@ -4757,6 +4845,7 @@ dependencies = [ "parking_lot 0.10.2", "pin-project", "rand 0.7.3", + "sc-block-builder", "sc-client", "sc-client-api", "sc-keystore", @@ -4764,6 +4853,7 @@ dependencies = [ "sc-network-gossip", "sc-telemetry", "serde_json", + "sp-api", "sp-arithmetic", "sp-blockchain", "sp-consensus", @@ -4772,12 +4862,14 @@ dependencies = [ "sp-finality-tracker", "sp-inherents", "sp-runtime", + "sp-utils", + "substrate-prometheus-endpoint", ] [[package]] name = "sc-informant" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "ansi_term 0.12.1", "futures 0.3.4", @@ -4793,8 +4885,8 @@ dependencies = [ [[package]] name = "sc-keystore" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "derive_more", "hex", @@ -4808,8 +4900,8 @@ dependencies = [ [[package]] name = "sc-network" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "bitflags 1.2.1", "bytes 0.5.4", @@ -4821,6 +4913,8 @@ dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", "futures_codec", + "hex", + "ip_network", "libp2p", "linked-hash-map", "linked_hash_set", @@ -4833,7 +4927,6 @@ dependencies = [ "prost", "prost-build", "rand 0.7.3", - "rustc-hex", "sc-block-builder", "sc-client", "sc-client-api", @@ -4849,8 +4942,10 @@ dependencies = [ "sp-consensus-babe", "sp-core", "sp-runtime", + "sp-utils", + "substrate-prometheus-endpoint", "thiserror", - "unsigned-varint 0.3.2", + "unsigned-varint", "void", "wasm-timer", "zeroize 1.1.0", @@ -4858,24 +4953,24 @@ dependencies = [ [[package]] name = "sc-network-gossip" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "futures 0.3.4", "futures-timer 3.0.2", "libp2p", "log 0.4.8", "lru", - "parking_lot 0.10.2", "sc-network", "sp-runtime", + "sp-utils", "wasm-timer", ] [[package]] name = "sc-offchain" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "bytes 0.5.4", "fnv", @@ -4895,25 +4990,27 @@ dependencies = [ "sp-core", "sp-offchain", "sp-runtime", + "sp-utils", "threadpool", ] [[package]] name = "sc-peerset" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "futures 0.3.4", "libp2p", "log 0.4.8", "serde_json", + "sp-utils", "wasm-timer", ] [[package]] name = "sc-rpc" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "futures 0.3.4", "hash-db", @@ -4922,6 +5019,7 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.2", + "sc-block-builder", "sc-client", "sc-client-api", "sc-executor", @@ -4930,6 +5028,7 @@ dependencies = [ "serde_json", "sp-api", "sp-blockchain", + "sp-chain-spec", "sp-core", "sp-offchain", "sp-rpc", @@ -4937,13 +5036,14 @@ dependencies = [ "sp-session", "sp-state-machine", "sp-transaction-pool", + "sp-utils", "sp-version", ] [[package]] name = "sc-rpc-api" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "derive_more", "futures 0.3.4", @@ -4956,6 +5056,7 @@ dependencies = [ "parking_lot 0.10.2", "serde", "serde_json", + "sp-chain-spec", "sp-core", "sp-rpc", "sp-runtime", @@ -4965,8 +5066,8 @@ dependencies = [ [[package]] name = "sc-rpc-server" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "jsonrpc-core", "jsonrpc-http-server", @@ -4980,22 +5081,23 @@ dependencies = [ [[package]] name = "sc-service" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "derive_more", "exit-future", "futures 0.1.29", "futures 0.3.4", - "futures-diagnose", "futures-timer 3.0.2", "lazy_static", "log 0.4.8", - "parity-multiaddr 0.5.0", + "netstat2", + "parity-multiaddr 0.7.3", "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.2", - "prometheus-exporter", + "pin-project", + "procfs", "sc-chain-spec", "sc-client", "sc-client-api", @@ -5021,27 +5123,31 @@ dependencies = [ "sp-runtime", "sp-session", "sp-transaction-pool", + "sp-utils", + "substrate-prometheus-endpoint", "sysinfo", - "target_info", "tracing", "wasm-timer", ] [[package]] name = "sc-state-db" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "log 0.4.8", "parity-scale-codec", + "parity-util-mem", + "parity-util-mem-derive", "parking_lot 0.10.2", + "sc-client-api", "sp-core", ] [[package]] name = "sc-telemetry" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "bytes 0.5.4", "futures 0.3.4", @@ -5062,8 +5168,8 @@ dependencies = [ [[package]] name = "sc-tracing" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "erased-serde", "log 0.4.8", @@ -5077,8 +5183,8 @@ dependencies = [ [[package]] name = "sc-transaction-graph" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "derive_more", "futures 0.3.4", @@ -5091,18 +5197,19 @@ dependencies = [ "sp-core", "sp-runtime", "sp-transaction-pool", + "sp-utils", "wasm-timer", ] [[package]] name = "sc-transaction-pool" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "derive_more", "futures 0.3.4", "futures-diagnose", - "futures-timer 2.0.2", + "intervalier", "log 0.4.8", "parity-scale-codec", "parity-util-mem", @@ -5113,7 +5220,10 @@ dependencies = [ "sp-blockchain", "sp-core", "sp-runtime", + "sp-tracing", "sp-transaction-pool", + "sp-utils", + "substrate-prometheus-endpoint", "wasm-timer", ] @@ -5129,19 +5239,20 @@ dependencies = [ [[package]] name = "schnorrkel" -version = "0.8.5" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eacd8381b3c37840c9c9f40472af529e49975bdcbc24f83c31059fd6539023d3" +checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862" dependencies = [ - "curve25519-dalek 1.2.3", - "failure", + "arrayref", + "arrayvec 0.5.1", + "curve25519-dalek", + "getrandom", "merlin", - "rand 0.6.5", - "rand_core 0.4.2", - "rand_os", + "rand 0.7.3", + "rand_core 0.5.1", "sha2", "subtle 2.2.2", - "zeroize 0.9.3", + "zeroize 1.1.0", ] [[package]] @@ -5163,7 +5274,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "656c79d0e90d0ab28ac86bf3c3d10bfbbac91450d3f190113b4e76d9fec3cfdd" dependencies = [ "byte-tools", - "byteorder 1.3.4", + "byteorder", "hmac", "pbkdf2", "sha2", @@ -5208,18 +5319,6 @@ dependencies = [ "cc", ] -[[package]] -name = "security-framework" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ef2429d7cefe5fd28bd1d2ed41c944547d4ff84776f5935b456da44593a16df" -dependencies = [ - "core-foundation 0.6.4", - "core-foundation-sys 0.6.2", - "libc", - "security-framework-sys 0.3.3", -] - [[package]] name = "security-framework" version = "0.4.2" @@ -5227,19 +5326,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "572dfa3a0785509e7a44b5b4bebcf94d41ba34e9ed9eb9df722545c3b3c4144a" dependencies = [ "bitflags 1.2.1", - "core-foundation 0.7.0", - "core-foundation-sys 0.7.0", + "core-foundation", + "core-foundation-sys", "libc", - "security-framework-sys 0.4.2", -] - -[[package]] -name = "security-framework-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e31493fc37615debb8c5090a7aeb4a9730bc61e77ab10b9af59f1a202284f895" -dependencies = [ - "core-foundation-sys 0.6.2", + "security-framework-sys", ] [[package]] @@ -5248,7 +5338,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ddb15a5fec93b7021b8a9e96009c5d8d51c15673569f7c0f6b7204e5b7b404f" dependencies = [ - "core-foundation-sys 0.7.0", + "core-foundation-sys", "libc", ] @@ -5494,8 +5584,8 @@ dependencies = [ [[package]] name = "sp-allocator" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "derive_more", "log 0.4.8", @@ -5506,8 +5596,8 @@ dependencies = [ [[package]] name = "sp-api" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "hash-db", "parity-scale-codec", @@ -5521,8 +5611,8 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "blake2-rfc", "proc-macro-crate", @@ -5533,8 +5623,8 @@ dependencies = [ [[package]] name = "sp-application-crypto" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "parity-scale-codec", "serde", @@ -5545,12 +5635,13 @@ dependencies = [ [[package]] name = "sp-arithmetic" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "integer-sqrt", - "num-traits", + "num-traits 0.2.11", "parity-scale-codec", + "primitive-types 0.7.0", "serde", "sp-debug-derive", "sp-std", @@ -5558,8 +5649,8 @@ dependencies = [ [[package]] name = "sp-block-builder" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "parity-scale-codec", "sp-api", @@ -5570,8 +5661,8 @@ dependencies = [ [[package]] name = "sp-blockchain" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "derive_more", "log 0.4.8", @@ -5607,10 +5698,19 @@ dependencies = [ "triehash", ] +[[package]] +name = "sp-chain-spec" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "sp-consensus" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "derive_more", "futures 0.3.4", @@ -5626,13 +5726,14 @@ dependencies = [ "sp-runtime", "sp-state-machine", "sp-std", + "sp-utils", "sp-version", ] [[package]] name = "sp-consensus-aura" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "parity-scale-codec", "sp-api", @@ -5645,29 +5746,42 @@ dependencies = [ [[package]] name = "sp-consensus-babe" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "parity-scale-codec", - "schnorrkel", "sp-api", "sp-application-crypto", "sp-consensus", + "sp-consensus-vrf", "sp-inherents", "sp-runtime", "sp-std", "sp-timestamp", ] +[[package]] +name = "sp-consensus-vrf" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" +dependencies = [ + "parity-scale-codec", + "schnorrkel", + "sp-core", + "sp-runtime", + "sp-std", +] + [[package]] name = "sp-core" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "base58", "blake2-rfc", - "byteorder 1.3.4", + "byteorder", "ed25519-dalek", + "futures 0.3.4", "hash-db", "hash256-std-hasher", "hex", @@ -5675,14 +5789,14 @@ dependencies = [ "lazy_static", "libsecp256k1", "log 0.4.8", - "num-traits", + "merlin", + "num-traits 0.2.11", "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.2", - "primitive-types 0.6.2", + "primitive-types 0.7.0", "rand 0.7.3", "regex", - "rustc-hex", "schnorrkel", "serde", "sha2", @@ -5699,10 +5813,19 @@ dependencies = [ "zeroize 1.1.0", ] +[[package]] +name = "sp-database" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" +dependencies = [ + "kvdb", + "parking_lot 0.10.2", +] + [[package]] name = "sp-debug-derive" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "proc-macro2 1.0.10", "quote 1.0.3", @@ -5711,18 +5834,19 @@ dependencies = [ [[package]] name = "sp-externalities" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "environmental", + "parity-scale-codec", "sp-std", "sp-storage", ] [[package]] name = "sp-finality-grandpa" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "parity-scale-codec", "serde", @@ -5734,8 +5858,8 @@ dependencies = [ [[package]] name = "sp-finality-tracker" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "parity-scale-codec", "sp-inherents", @@ -5744,8 +5868,8 @@ dependencies = [ [[package]] name = "sp-inherents" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "derive_more", "parity-scale-codec", @@ -5756,13 +5880,15 @@ dependencies = [ [[package]] name = "sp-io" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ + "futures 0.3.4", "hash-db", "libsecp256k1", "log 0.4.8", "parity-scale-codec", + "parking_lot 0.10.2", "sp-core", "sp-externalities", "sp-runtime-interface", @@ -5774,8 +5900,8 @@ dependencies = [ [[package]] name = "sp-keyring" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "lazy_static", "sp-core", @@ -5785,17 +5911,18 @@ dependencies = [ [[package]] name = "sp-offchain" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "sp-api", + "sp-core", "sp-runtime", ] [[package]] name = "sp-panic-handler" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "backtrace", "log 0.4.8", @@ -5803,8 +5930,8 @@ dependencies = [ [[package]] name = "sp-rpc" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "serde", "sp-core", @@ -5812,9 +5939,10 @@ dependencies = [ [[package]] name = "sp-runtime" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ + "hash256-std-hasher", "impl-trait-for-tuples", "log 0.4.8", "parity-scale-codec", @@ -5832,22 +5960,23 @@ dependencies = [ [[package]] name = "sp-runtime-interface" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "parity-scale-codec", - "primitive-types 0.6.2", + "primitive-types 0.7.0", "sp-externalities", "sp-runtime-interface-proc-macro", "sp-std", + "sp-tracing", "sp-wasm-interface", "static_assertions", ] [[package]] name = "sp-runtime-interface-proc-macro" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "Inflector", "proc-macro-crate", @@ -5858,8 +5987,8 @@ dependencies = [ [[package]] name = "sp-serializer" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "serde", "serde_json", @@ -5867,8 +5996,8 @@ dependencies = [ [[package]] name = "sp-session" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "sp-api", "sp-core", @@ -5878,8 +6007,8 @@ dependencies = [ [[package]] name = "sp-staking" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "parity-scale-codec", "sp-runtime", @@ -5888,12 +6017,12 @@ dependencies = [ [[package]] name = "sp-state-machine" -version = "0.8.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "hash-db", "log 0.4.8", - "num-traits", + "num-traits 0.2.11", "parity-scale-codec", "parking_lot 0.10.2", "rand 0.7.3", @@ -5907,15 +6036,16 @@ dependencies = [ [[package]] name = "sp-std" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" [[package]] name = "sp-storage" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "impl-serde 0.2.3", + "ref-cast", "serde", "sp-debug-derive", "sp-std", @@ -5923,8 +6053,8 @@ dependencies = [ [[package]] name = "sp-timestamp" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -5935,10 +6065,18 @@ dependencies = [ "wasm-timer", ] +[[package]] +name = "sp-tracing" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" +dependencies = [ + "tracing", +] + [[package]] name = "sp-transaction-pool" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "derive_more", "futures 0.3.4", @@ -5947,12 +6085,13 @@ dependencies = [ "serde", "sp-api", "sp-runtime", + "sp-utils", ] [[package]] name = "sp-trie" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "hash-db", "memory-db", @@ -5963,10 +6102,21 @@ dependencies = [ "trie-root", ] +[[package]] +name = "sp-utils" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" +dependencies = [ + "futures 0.3.4", + "futures-core", + "lazy_static", + "prometheus", +] + [[package]] name = "sp-version" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "impl-serde 0.2.3", "parity-scale-codec", @@ -5977,8 +6127,8 @@ dependencies = [ [[package]] name = "sp-wasm-interface" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -6010,6 +6160,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "statrs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10102ac8d55e35db2b3fafc26f81ba8647da2e15879ab686a67e6d19af2685e8" +dependencies = [ + "rand 0.5.6", +] + [[package]] name = "stdweb" version = "0.4.20" @@ -6130,9 +6289,9 @@ dependencies = [ [[package]] name = "substrate-bip39" -version = "0.3.1" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be511be555a3633e71739a79e4ddff6a6aaa6579fa6114182a51d72c3eb93c5" +checksum = "c004e8166d6e0aa3a9d5fa673e5b7098ff25f930de1013a21341988151e681bb" dependencies = [ "hmac", "pbkdf2", @@ -6161,13 +6320,16 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" +dependencies = [ + "platforms", +] [[package]] name = "substrate-frame-rpc-system" -version = "2.0.0-alpha.2" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" dependencies = [ "frame-system-rpc-runtime-api", "futures 0.3.4", @@ -6185,10 +6347,24 @@ dependencies = [ "sp-transaction-pool", ] +[[package]] +name = "substrate-prometheus-endpoint" +version = "0.8.0-dev" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" +dependencies = [ + "async-std", + "derive_more", + "futures-util", + "hyper 0.13.4", + "log 0.4.8", + "prometheus", + "tokio 0.2.16", +] + [[package]] name = "substrate-wasm-builder-runner" version = "1.0.5" -source = "git+https://github.com/paritytech/substrate.git?rev=2afecf81ee19b8a6edb364b419190ea47c4a4a31#2afecf81ee19b8a6edb364b419190ea47c4a4a31" +source = "git+https://github.com/paritytech/substrate.git?rev=c13ad41634d0bd7cf07897c2aa062b917d520520#c13ad41634d0bd7cf07897c2aa062b917d520520" [[package]] name = "subtle" @@ -6202,6 +6378,17 @@ version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" +[[package]] +name = "syn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" +dependencies = [ + "quote 0.3.15", + "synom", + "unicode-xid 0.0.4", +] + [[package]] name = "syn" version = "0.15.44" @@ -6235,6 +6422,15 @@ dependencies = [ "syn 1.0.17", ] +[[package]] +name = "synom" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +dependencies = [ + "unicode-xid 0.0.4", +] + [[package]] name = "synstructure" version = "0.10.2" @@ -6261,13 +6457,15 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.9.6" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f4b2468c629cffba39c0a4425849ab3cdb03d9dfacba69684609aea04d08ff9" +checksum = "1cac193374347e7c263c5f547524f36ff8ec6702d56c8799c8331d26dffe8c1e" dependencies = [ "cfg-if", "doc-comment", "libc", + "ntapi", + "once_cell", "rayon", "winapi 0.3.8", ] @@ -6278,12 +6476,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" -[[package]] -name = "target_info" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" - [[package]] name = "tempfile" version = "3.1.0" @@ -6597,12 +6789,12 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.12.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "141afec0978abae6573065a48882c6bae44c5cc61db9b511ac4abf6a09bfd9cc" +checksum = "4adb8b3e5f86b707f1b54e7c15b6de52617a823608ccda98a15d3a24222f265a" dependencies = [ "futures-core", - "rustls", + "rustls 0.17.0", "tokio 0.2.16", "webpki", ] @@ -6809,9 +7001,9 @@ checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" [[package]] name = "trie-db" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de9222c50cc325855621271157c973da27a0dcd26fa06f8edf81020bd2333df0" +checksum = "bcc309f34008563989045a4c4dbcc5770467f3a3785ee80a9b5cc0d83362475f" dependencies = [ "hash-db", "hashbrown 0.6.3", @@ -6845,17 +7037,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" -[[package]] -name = "twofish" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712d261e83e727c8e2dbb75dacac67c36e35db36a958ee504f2164fc052434e1" -dependencies = [ - "block-cipher-trait", - "byteorder 1.3.4", - "opaque-debug", -] - [[package]] name = "twox-hash" version = "1.5.0" @@ -6883,7 +7064,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e75a4cdd7b87b28840dba13c483b9a88ee6bbf16ba5c951ee1ecfcf723078e0d" dependencies = [ - "byteorder 1.3.4", + "byteorder", "crunchy", "rustc-hex", "static_assertions", @@ -6937,6 +7118,12 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" +[[package]] +name = "unicode-xid" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" + [[package]] name = "unicode-xid" version = "0.1.0" @@ -6949,12 +7136,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" -[[package]] -name = "unsigned-varint" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f0023a96687fe169081e8adce3f65e3874426b7886e9234d490af2dc077959" - [[package]] name = "unsigned-varint" version = "0.3.2" @@ -7153,7 +7334,7 @@ dependencies = [ "libc", "memory_units", "num-rational", - "num-traits", + "num-traits 0.2.11", "parity-wasm", "wasmi-validation", ] @@ -7236,6 +7417,15 @@ dependencies = [ "webpki", ] +[[package]] +name = "webpki-roots" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8eff4b7516a57307f9349c64bf34caa34b940b66fed4b2fb3136cb7386e5739" +dependencies = [ + "webpki", +] + [[package]] name = "websocket" version = "0.21.1" @@ -7244,7 +7434,7 @@ checksum = "8c9faed2bff8af2ea6b9f8b917d3d00b467583f6781fe3def174a9e33c879703" dependencies = [ "base64 0.9.3", "bitflags 0.9.1", - "byteorder 1.3.4", + "byteorder", "bytes 0.4.12", "futures 0.1.29", "hyper 0.10.16", @@ -7316,7 +7506,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c51a2c47b5798ccc774ffb93ff536aec7c4275d722fd9c740c83cdd1af1f2d94" dependencies = [ - "byteorder 1.3.4", + "byteorder", "bytes 0.4.12", "httparse", "log 0.4.8", @@ -7344,7 +7534,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "637ff90c9540fa3073bb577e65033069e4bae7c79d49d74aa3ffdf5342a53217" dependencies = [ - "curve25519-dalek 2.0.0", + "curve25519-dalek", "rand_core 0.5.1", "zeroize 1.1.0", ] diff --git a/bin/node/node/Cargo.toml b/bin/node/node/Cargo.toml index 2b5c9775e1..a697e14ec4 100644 --- a/bin/node/node/Cargo.toml +++ b/bin/node/node/Cargo.toml @@ -20,94 +20,94 @@ sp-bridge-eth-poa = { version = "0.1.0", path = "../../../primitives/ethereum-po [dependencies.sc-cli] version = "0.8.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sc-rpc] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sp-core] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sc-executor] version = "0.8.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sc-service] version = "0.8.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sp-inherents] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sc-transaction-pool] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sp-transaction-pool] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sc-network] version = "0.8.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sc-consensus-aura] version = "0.8.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sp-consensus-aura] version = "0.8.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sp-consensus] version = "0.8.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.grandpa] package = "sc-finality-grandpa" version = "0.8.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.grandpa-primitives] package = "sp-finality-grandpa" version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sc-client] version = "0.8.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sp-runtime] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sc-basic-authorship] version = "0.8.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.substrate-frame-rpc-system] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [build-dependencies] @@ -116,5 +116,5 @@ vergen = "3.1.0" [build-dependencies.build-script-utils] package = "substrate-build-script-utils" version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 394db75e17..ffb8d13f16 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -21,13 +21,13 @@ features = ["derive"] [dependencies.pallet-aura] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.pallet-balances] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.pallet-bridge-eth-poa] @@ -38,74 +38,74 @@ path = "../../../modules/ethereum" [dependencies.frame-support] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.pallet-grandpa] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.pallet-randomness-collective-flip] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.pallet-sudo] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.pallet-session] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.frame-system] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.frame-system-rpc-runtime-api] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.pallet-timestamp] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.pallet-transaction-payment] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.frame-executive] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" # Substrate Primitives [dependencies.sp-api] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-block-builder] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-bridge-eth-poa] @@ -116,73 +116,73 @@ path = "../../../primitives/ethereum-poa" [dependencies.sp-consensus-aura] version = "0.8.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-core] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-inherents] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-io] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-offchain] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-runtime] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-session] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-staking] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-std] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-transaction-pool] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-version] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [build-dependencies.wasm-builder-runner] version = "1.0.5" package = "substrate-wasm-builder-runner" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [features] diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 0936f61cb9..8b5bb05f87 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -32,7 +32,7 @@ use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_core::OpaqueMetadata; use sp_runtime::traits::{BlakeTwo256, Block as BlockT, ConvertInto, IdentifyAccount, IdentityLookup, Verify, OpaqueKeys}; use sp_runtime::{ - create_runtime_str, generic, impl_opaque_keys, transaction_validity::TransactionValidity, ApplyExtrinsicResult, + create_runtime_str, generic, impl_opaque_keys, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, MultiSignature, }; use sp_std::prelude::*; @@ -41,7 +41,7 @@ use sp_version::NativeVersion; use sp_version::RuntimeVersion; // A few exports that help ease life for downstream crates. -pub use frame_support::{construct_runtime, parameter_types, traits::Randomness, weights::Weight, StorageValue}; +pub use frame_support::{construct_runtime, parameter_types, traits::Randomness, weights::{RuntimeDbWeight, Weight}, StorageValue}; pub use pallet_balances::Call as BalancesCall; pub use pallet_bridge_eth_poa::Call as BridgeEthPoACall; pub use pallet_timestamp::Call as TimestampCall; @@ -107,6 +107,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_version: 1, impl_version: 1, apis: RUNTIME_API_VERSIONS, + transaction_version: 1, }; pub const MILLISECS_PER_BLOCK: u64 = 6000; @@ -129,10 +130,15 @@ pub fn native_version() -> NativeVersion { parameter_types! { pub const BlockHashCount: BlockNumber = 250; - pub const MaximumBlockWeight: Weight = 1_000_000; + pub const MaximumBlockWeight: Weight = 2_000_000_000_000; + pub const ExtrinsicBaseWeight: Weight = 10_000_000; pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; pub const Version: RuntimeVersion = VERSION; + pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { + read: 60_000_000, // ~0.06 ms = ~60 µs + write: 200_000_000, // ~0.2 ms = 200 µs + }; } impl frame_system::Trait for Runtime { @@ -160,6 +166,14 @@ impl frame_system::Trait for Runtime { type BlockHashCount = BlockHashCount; /// Maximum weight of each block. type MaximumBlockWeight = MaximumBlockWeight; + /// The weight of database operations that the runtime can invoke. + type DbWeight = DbWeight; + /// The weight of the overhead invoked on the block import process, independent of the + /// extrinsics included in that block. + type BlockExecutionWeight = (); + /// The base weight of any extrinsic processed by the runtime, independent of the + /// logic of that extrinsic. (Signature verification, nonce increment, fee, etc...) + type ExtrinsicBaseWeight = ExtrinsicBaseWeight; /// Maximum size of all encoded transactions (in bytes) that are allowed in one block. type MaximumBlockLength = MaximumBlockLength; /// Portion of the block weight that is available to all normal transactions. @@ -223,7 +237,6 @@ parameter_types! { impl pallet_transaction_payment::Trait for Runtime { type Currency = pallet_balances::Module; type OnTransactionPayment = (); - type TransactionBaseFee = TransactionBaseFee; type TransactionByteFee = TransactionByteFee; type WeightToFee = ConvertInto; type FeeMultiplierUpdate = (); @@ -244,6 +257,7 @@ impl pallet_session::Trait for Runtime { type ValidatorId = ::AccountId; type ValidatorIdOf = (); type ShouldEndSession = pallet_session::PeriodicSessions; + type NextSessionRotation = pallet_session::PeriodicSessions; type SessionManager = ShiftSessionManager; type SessionHandler = ::KeyTypeIdProviders; type Keys = SessionKeys; @@ -277,6 +291,7 @@ impl ShiftSessionManager { impl pallet_session::SessionManager for ShiftSessionManager { fn end_session(_: sp_staking::SessionIndex) {} + fn start_session(_: sp_staking::SessionIndex) {} fn new_session(session_index: sp_staking::SessionIndex) -> Option> { // can't access genesis config here :/ if session_index == 0 || session_index == 1 { @@ -374,10 +389,6 @@ impl_runtime_apis! { Executive::apply_extrinsic(extrinsic) } - fn apply_trusted_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { - Executive::apply_trusted_extrinsic(extrinsic) - } - fn finalize_block() -> ::Header { Executive::finalize_block() } @@ -419,8 +430,11 @@ impl_runtime_apis! { } impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { - fn validate_transaction(tx: ::Extrinsic) -> TransactionValidity { - Executive::validate_transaction(tx) + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx) } } diff --git a/modules/ethereum-contract/builtin/Cargo.toml b/modules/ethereum-contract/builtin/Cargo.toml index 07f3d2b971..cd36767e98 100644 --- a/modules/ethereum-contract/builtin/Cargo.toml +++ b/modules/ethereum-contract/builtin/Cargo.toml @@ -11,10 +11,6 @@ edition = "2018" codec = { package = "parity-scale-codec", version = "1.0.0" } ethereum-types = "0.8.0" -finality-grandpa = { version = "0.11.2", features = ["derive-codec"] } -#sp-blockchain = "2.0.0-alpha.2" -#sp-finality-grandpa = "2.0.0-alpha.2" -#sp-runtime = "2.0.0-alpha.2" # Runtime/chain specific dependencies @@ -22,15 +18,20 @@ bridge-node-runtime = { path = "../../../bin/node/runtime" } [dependencies.sp-blockchain] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-finality-grandpa] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-runtime] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" +git = "https://github.com/paritytech/substrate/" + +[dependencies.sc-finality-grandpa] +version = "0.8.0-dev" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" \ No newline at end of file diff --git a/modules/ethereum-contract/builtin/src/lib.rs b/modules/ethereum-contract/builtin/src/lib.rs index 76e39e6d10..438ba2da23 100644 --- a/modules/ethereum-contract/builtin/src/lib.rs +++ b/modules/ethereum-contract/builtin/src/lib.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use bridge_node_runtime::{BlockNumber, Hash, Header as RuntimeHeader}; +use bridge_node_runtime::{Block, BlockNumber, Hash, Header as RuntimeHeader}; use codec::{Decode, Encode}; use ethereum_types::U256; use sp_blockchain::Error as ClientError; @@ -107,10 +107,8 @@ pub fn verify_substrate_finality_proof( raw_best_set: &[u8], raw_finality_proof: &[u8], ) -> Result<(), Error> { - // TODO: accept other types of finality proof (Commit) let best_set = AuthorityList::decode(&mut &raw_best_set[..]).map_err(Error::BestSetDecode)?; - - substrate::GrandpaJustification::decode_and_verify_finalizes( + sc_finality_grandpa::GrandpaJustification::::decode_and_verify_finalizes( &raw_finality_proof, (finality_target_hash, finality_target_number), best_set_id, @@ -119,146 +117,3 @@ pub fn verify_substrate_finality_proof( .map_err(Error::JustificationVerify) .map(|_| ()) } - -/// ================================================================================================================== -/// === Everything below should be (?) exposed by Substrate ========================================================== -/// ================================================================================================================== - -mod substrate { - use bridge_node_runtime::{BlockNumber, Hash, Header as RuntimeHeader}; - use codec::{Decode, Encode}; - use finality_grandpa::voter_set::VoterSet; - use sp_blockchain::Error as ClientError; - use sp_finality_grandpa::{AuthorityId, AuthoritySignature}; - use std::collections::HashMap; - - /// A commit message for this chain's block type. - pub type Commit = finality_grandpa::Commit; - - /// GRANDPA justification. - #[derive(Encode, Decode)] - pub struct GrandpaJustification { - pub round: u64, - pub commit: Commit, - pub votes_ancestries: Vec, - } - - impl GrandpaJustification { - /// Decode a GRANDPA justification and validate the commit and the votes' - /// ancestry proofs finalize the given block. - pub(crate) fn decode_and_verify_finalizes( - encoded: &[u8], - finalized_target: (Hash, BlockNumber), - set_id: u64, - voters: &VoterSet, - ) -> Result { - let justification = - GrandpaJustification::decode(&mut &*encoded).map_err(|_| ClientError::JustificationDecode)?; - - if (justification.commit.target_hash, justification.commit.target_number) != finalized_target { - let msg = format!("invalid commit target in grandpa justification: {:?} != {:?}", (justification.commit.target_hash, justification.commit.target_number), finalized_target); - Err(ClientError::BadJustification(msg)) - } else { - justification.verify(set_id, voters).map(|_| justification) - } - } - - /// Validate the commit and the votes' ancestry proofs. - pub(crate) fn verify(&self, _set_id: u64, voters: &VoterSet) -> Result<(), ClientError> { - // use finality_grandpa::Chain; - - let ancestry_chain = AncestryChain::new(&self.votes_ancestries); - - match finality_grandpa::validate_commit(&self.commit, voters, &ancestry_chain) { - Ok(ref result) if result.ghost().is_some() => {} - _ => { - let msg = "invalid commit in grandpa justification".to_string(); - return Err(ClientError::BadJustification(msg)); - } - } - /* TODO - let mut buf = Vec::new(); - let mut visited_hashes = HashSet::new(); - for signed in self.commit.precommits.iter() { - if let Err(_) = communication::check_message_sig_with_buffer::( - &finality_grandpa::Message::Precommit(signed.precommit.clone()), - &signed.id, - &signed.signature, - self.round, - set_id, - &mut buf, - ) { - return Err(ClientError::BadJustification( - "invalid signature for precommit in grandpa justification".to_string()).into()); - } - if self.commit.target_hash == signed.precommit.target_hash { - continue; - } - match ancestry_chain.ancestry(self.commit.target_hash, signed.precommit.target_hash) { - Ok(route) => { - // ancestry starts from parent hash but the precommit target hash has been visited - visited_hashes.insert(signed.precommit.target_hash); - for hash in route { - visited_hashes.insert(hash); - } - }, - _ => { - return Err(ClientError::BadJustification( - "invalid precommit ancestry proof in grandpa justification".to_string()).into()); - }, - } - } - let ancestry_hashes = self.votes_ancestries - .iter() - .map(|h: &Block::Header| h.hash()) - .collect(); - if visited_hashes != ancestry_hashes { - return Err(ClientError::BadJustification( - "invalid precommit ancestries in grandpa justification with unused headers".to_string()).into()); - } - */ - Ok(()) - } - } - - /// A utility trait implementing `finality_grandpa::Chain` using a given set of headers. - /// This is useful when validating commits, using the given set of headers to - /// verify a valid ancestry route to the target commit block. - struct AncestryChain { - ancestry: HashMap, - } - - impl AncestryChain { - fn new(ancestry: &[RuntimeHeader]) -> AncestryChain { - let ancestry: HashMap<_, _> = ancestry.iter().cloned().map(|h: RuntimeHeader| (h.hash(), h)).collect(); - - AncestryChain { ancestry } - } - } - - impl finality_grandpa::Chain for AncestryChain { - fn ancestry(&self, base: Hash, block: Hash) -> Result, finality_grandpa::Error> { - let mut route = Vec::new(); - let mut current_hash = block; - loop { - if current_hash == base { - break; - } - match self.ancestry.get(¤t_hash) { - Some(current_header) => { - current_hash = current_header.parent_hash; - route.push(current_hash); - } - _ => return Err(finality_grandpa::Error::NotDescendent), - } - } - route.pop(); // remove the base - - Ok(route) - } - - fn best_chain_containing(&self, _block: Hash) -> Option<(Hash, BlockNumber)> { - None - } - } -} diff --git a/modules/ethereum/Cargo.toml b/modules/ethereum/Cargo.toml index 3b752212ec..59cddcce39 100644 --- a/modules/ethereum/Cargo.toml +++ b/modules/ethereum/Cargo.toml @@ -14,31 +14,31 @@ primitives = { package = "sp-bridge-eth-poa", path = "../../primitives/ethereum- [dependencies.frame-support] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.frame-system] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-std] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-io] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-runtime] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" # Dev Dependencies diff --git a/modules/ethereum/src/lib.rs b/modules/ethereum/src/lib.rs index b7bdd066b2..97f06ea6b6 100644 --- a/modules/ethereum/src/lib.rs +++ b/modules/ethereum/src/lib.rs @@ -21,8 +21,8 @@ use frame_support::{decl_module, decl_storage}; use primitives::{Address, Header, Receipt, H256, U256}; use sp_runtime::{ transaction_validity::{ - InvalidTransaction, TransactionLongevity, TransactionPriority, TransactionValidity, UnknownTransaction, - ValidTransaction, + InvalidTransaction, TransactionLongevity, TransactionPriority, TransactionSource, + TransactionValidity, UnknownTransaction, ValidTransaction, }, RuntimeDebug, }; @@ -293,6 +293,7 @@ pub trait Trait: frame_system::Trait { decl_module! { pub struct Module for enum Call where origin: T::Origin { /// Import single Aura header. Requires transaction to be **UNSIGNED**. + #[weight = 0] pub fn import_unsigned_header(origin, header: Header, receipts: Option>) { frame_system::ensure_none(origin)?; @@ -313,6 +314,7 @@ decl_module! { /// /// This should be used with caution - passing too many headers could lead to /// enormous block production/import time. + #[weight = 0] pub fn import_signed_headers(origin, headers_with_receipts: Vec<(Header, Option>)>) { let submitter = frame_system::ensure_signed(origin)?; let mut finalized_headers = BTreeMap::new(); @@ -359,19 +361,19 @@ decl_storage! { /// Oldest unpruned block(s) number. OldestUnprunedBlock: u64; /// Map of imported headers by hash. - Headers: map hasher(blake2_256) H256 => Option>; + Headers: map hasher(blake2_128_concat) H256 => Option>; /// Map of imported header hashes by number. - HeadersByNumber: map hasher(blake2_256) u64 => Option>; + HeadersByNumber: map hasher(blake2_128_concat) u64 => Option>; /// The ID of next validator set. NextValidatorsSetId: u64; /// Map of validators sets by their id. - ValidatorsSets: map hasher(blake2_256) u64 => Option; + ValidatorsSets: map hasher(blake2_128_concat) u64 => Option; /// Validators sets reference count. Each header that is authored by this set increases /// the reference count. When we prune this header, we decrease the reference count. /// When it reaches zero, we are free to prune validator set as well. - ValidatorsSetsRc: map hasher(blake2_256) u64 => Option; + ValidatorsSetsRc: map hasher(blake2_128_concat) u64 => Option; /// Map of validators set changes scheduled by given header. - ScheduledChanges: map hasher(blake2_256) H256 => Option; + ScheduledChanges: map hasher(blake2_128_concat) H256 => Option; } add_extra_genesis { config(initial_header): Header; @@ -434,7 +436,7 @@ impl Module { impl frame_support::unsigned::ValidateUnsigned for Module { type Call = Call; - fn validate_unsigned(call: &Self::Call) -> TransactionValidity { + fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity { match *call { Self::Call::import_unsigned_header(ref header, ref receipts) => { let accept_result = verification::accept_aura_header_into_pool( diff --git a/modules/substrate/Cargo.toml b/modules/substrate/Cargo.toml index 2ac2269af4..06cc6ad2ea 100644 --- a/modules/substrate/Cargo.toml +++ b/modules/substrate/Cargo.toml @@ -15,55 +15,55 @@ hash-db = { version = "0.15.2", default-features = false } [dependencies.frame-support] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.frame-system] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.pallet-session] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-core] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-finality-grandpa] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-runtime] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-trie] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" # Dev Dependencies [dev-dependencies.sp-io] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dev-dependencies.sp-state-machine] version = "0.8.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [features] diff --git a/modules/substrate/src/lib.rs b/modules/substrate/src/lib.rs index 3a0f9a0db5..ff43948d35 100644 --- a/modules/substrate/src/lib.rs +++ b/modules/substrate/src/lib.rs @@ -96,11 +96,11 @@ pub trait Trait: system::Trait {} decl_storage! { trait Store for Module as Bridge { /// The number of current bridges managed by the module. - pub NumBridges get(num_bridges) config(): BridgeId; + pub NumBridges get(fn num_bridges) config(): BridgeId; /// Maps a bridge id to a bridge struct. Allows a single /// `bridge` module to manage multiple bridges. - pub TrackedBridges get(tracked_bridges): map hasher(blake2_256) BridgeId => Option>; + pub TrackedBridges get(fn tracked_bridges): map hasher(blake2_128_concat) BridgeId => Option>; } } @@ -108,6 +108,7 @@ decl_module! { pub struct Module for enum Call where origin: T::Origin { type Error = Error; + #[weight = 0] fn initialize_bridge( origin, block_header: T::Header, @@ -131,6 +132,7 @@ decl_module! { NumBridges::put(new_bridge_id); } + #[weight = 0] fn submit_finalized_headers(origin) { let _sender = ensure_signed(origin)?; } diff --git a/primitives/ethereum-poa/Cargo.toml b/primitives/ethereum-poa/Cargo.toml index 015cfacb4e..d6916a8e8d 100644 --- a/primitives/ethereum-poa/Cargo.toml +++ b/primitives/ethereum-poa/Cargo.toml @@ -24,25 +24,25 @@ plain_hasher = { version = "0.2.2", default-features = false } [dependencies.sp-api] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sp-std] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sp-runtime] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sp-io] version = "2.0.0-alpha.2" default-features = false -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [features] diff --git a/relays/ethereum/Cargo.toml b/relays/ethereum/Cargo.toml index 0eda57224f..2bbd013822 100644 --- a/relays/ethereum/Cargo.toml +++ b/relays/ethereum/Cargo.toml @@ -33,35 +33,35 @@ web3 = { git = "https://github.com/svyatonik/rust-web3.git", branch = "fix_recei # Substrate Based Dependencies [dependencies.frame-system] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.pallet-transaction-payment] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" # I think this is used for sr-io and stuff [dependencies.node-primitives] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" # Branch used for keccack256 hasher code # Could probably move the keccack hasher stuff to our own primitives [dependencies.sp-core] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sp-keyring] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" [dependencies.sp-runtime] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" # This should get moved to our `bin` folder diff --git a/relays/substrate/Cargo.toml b/relays/substrate/Cargo.toml index 51c197e7f5..3d8d838a3f 100644 --- a/relays/substrate/Cargo.toml +++ b/relays/substrate/Cargo.toml @@ -18,15 +18,15 @@ url = "2.1.0" [dependencies.sp-core] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.sp-rpc] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dependencies.node-primitives] version = "2.0.0-alpha.2" -rev = "2afecf81ee19b8a6edb364b419190ea47c4a4a31" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" From a67f2aa04ac28db26831e1b1e70a16da97a4962b Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 29 Apr 2020 10:18:37 +0300 Subject: [PATCH 56/92] intermediate cargo fmt --all --- bin/node/node/Cargo.toml | 1 + bin/node/node/src/chain_spec.rs | 4 +- bin/node/runtime/src/lib.rs | 14 +++-- modules/ethereum/src/lib.rs | 4 +- relays/ethereum/src/ethereum_client.rs | 18 +++--- relays/ethereum/src/ethereum_sync_loop.rs | 2 +- relays/ethereum/src/headers.rs | 73 +++++++++------------- relays/ethereum/src/substrate_client.rs | 18 +++--- relays/ethereum/src/substrate_sync_loop.rs | 17 +++-- relays/ethereum/src/sync_loop.rs | 13 +++- 10 files changed, 85 insertions(+), 79 deletions(-) diff --git a/bin/node/node/Cargo.toml b/bin/node/node/Cargo.toml index 0872642824..6dfaa6b58e 100644 --- a/bin/node/node/Cargo.toml +++ b/bin/node/node/Cargo.toml @@ -80,6 +80,7 @@ git = "https://github.com/paritytech/substrate.git" [dependencies.grandpa] package = "sc-finality-grandpa" +version = "0.8.0-alpha.6" rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate.git" diff --git a/bin/node/node/src/chain_spec.rs b/bin/node/node/src/chain_spec.rs index 7cf69dde0e..11a31c7ae1 100644 --- a/bin/node/node/src/chain_spec.rs +++ b/bin/node/node/src/chain_spec.rs @@ -15,8 +15,8 @@ // along with Parity Bridges Common. If not, see . use bridge_node_runtime::{ - AccountId, AuraConfig, BalancesConfig, BridgeEthPoAConfig, GenesisConfig, GrandpaConfig, Signature, SudoConfig, - SystemConfig, SessionConfig, SessionKeys, WASM_BINARY, + AccountId, AuraConfig, BalancesConfig, BridgeEthPoAConfig, GenesisConfig, GrandpaConfig, SessionConfig, + SessionKeys, Signature, SudoConfig, SystemConfig, WASM_BINARY, }; use grandpa_primitives::AuthorityId as GrandpaId; use sc_service; diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index d6c95582df..45db36476e 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -30,7 +30,9 @@ use pallet_grandpa::AuthorityList as GrandpaAuthorityList; use sp_api::impl_runtime_apis; use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_core::OpaqueMetadata; -use sp_runtime::traits::{BlakeTwo256, Block as BlockT, ConvertInto, IdentifyAccount, IdentityLookup, Verify, OpaqueKeys}; +use sp_runtime::traits::{ + BlakeTwo256, Block as BlockT, ConvertInto, IdentifyAccount, IdentityLookup, OpaqueKeys, Verify, +}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, transaction_validity::{TransactionSource, TransactionValidity}, @@ -283,11 +285,11 @@ impl ShiftSessionManager { let offset = session_index as usize % available_validators_count; let end = offset + count; let session_validators = match end.overflowing_sub(available_validators_count) { - (wrapped_end, false) if wrapped_end != 0 => - available_validators[offset..].iter() - .chain(available_validators[..wrapped_end].iter()) - .cloned() - .collect(), + (wrapped_end, false) if wrapped_end != 0 => available_validators[offset..] + .iter() + .chain(available_validators[..wrapped_end].iter()) + .cloned() + .collect(), _ => available_validators[offset..end].to_vec(), }; diff --git a/modules/ethereum/src/lib.rs b/modules/ethereum/src/lib.rs index 732966eb95..9f0b0cbd03 100644 --- a/modules/ethereum/src/lib.rs +++ b/modules/ethereum/src/lib.rs @@ -21,8 +21,8 @@ use frame_support::{decl_module, decl_storage}; use primitives::{Address, Header, Receipt, H256, U256}; use sp_runtime::{ transaction_validity::{ - InvalidTransaction, TransactionLongevity, TransactionPriority, TransactionSource, - TransactionValidity, UnknownTransaction, ValidTransaction, + InvalidTransaction, TransactionLongevity, TransactionPriority, TransactionSource, TransactionValidity, + UnknownTransaction, ValidTransaction, }, RuntimeDebug, }; diff --git a/relays/ethereum/src/ethereum_client.rs b/relays/ethereum/src/ethereum_client.rs index 1f4b8ba1fa..ac70c31044 100644 --- a/relays/ethereum/src/ethereum_client.rs +++ b/relays/ethereum/src/ethereum_client.rs @@ -15,7 +15,7 @@ // along with Parity Bridges Common. If not, see . use crate::ethereum_types::{Address, Bytes, EthereumHeaderId, Header, Receipt, TransactionHash, H256, U256, U64}; -use crate::substrate_types::{Hash as SubstrateHash, QueuedSubstrateHeader, SubstrateHeaderId, GrandpaJustification}; +use crate::substrate_types::{GrandpaJustification, Hash as SubstrateHash, QueuedSubstrateHeader, SubstrateHeaderId}; use crate::sync_types::{HeaderId, MaybeConnectionError}; use crate::{bail_on_arg_error, bail_on_error}; use codec::{Decode, Encode}; @@ -318,8 +318,10 @@ pub async fn incomplete_substrate_headers( let (client, call_result) = bail_on_error!(call_rpc::(client, "eth_call", Params::Array(vec![call_request]),).await); match call_decoder.decode(&call_result.0) { - Ok((incomplete_headers_numbers, incomplete_headers_hashes)) => (client, Ok( - incomplete_headers_numbers.into_iter() + Ok((incomplete_headers_numbers, incomplete_headers_hashes)) => ( + client, + Ok(incomplete_headers_numbers + .into_iter() .zip(incomplete_headers_hashes) .filter_map(|(number, hash)| { if number != number.low_u32().into() { @@ -328,8 +330,8 @@ pub async fn incomplete_substrate_headers( Some(HeaderId(number.low_u32(), hash)) }) - .collect(), - )), + .collect()), + ), Err(error) => (client, Err(Error::ResponseParseFailed(format!("{}", error)))), } } @@ -349,11 +351,7 @@ pub async fn complete_substrate_header( Some(contract_address), None, false, - bridge_contract::functions::import_finality_proof::encode_input( - id.0, - id.1, - justification, - ), + bridge_contract::functions::import_finality_proof::encode_input(id.0, id.1, justification,), ) .await ); diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index 2267868ba2..6a3530b046 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -21,7 +21,7 @@ use crate::ethereum_types::{EthereumHeaderId, EthereumHeadersSyncPipeline, Heade use crate::substrate_client::{self, SubstrateConnectionParams, SubstrateSigningParams}; use crate::sync::{HeadersSyncParams, TargetTransactionMode}; use crate::sync_loop::{SourceClient, TargetClient}; -use futures::future::{FutureExt, Ready, ready}; +use futures::future::{ready, FutureExt, Ready}; use std::{collections::HashSet, future::Future, pin::Pin}; use web3::types::H256; diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index 37559a1abd..196a2b4643 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -18,9 +18,7 @@ use crate::sync_types::{HeaderId, HeaderStatus, HeadersSyncPipeline, QueuedHeade use linked_hash_map::LinkedHashMap; use num_traits::{One, Zero}; use std::{ - collections::{ - btree_map::Entry as BTreeMapEntry, hash_map::Entry as HashMapEntry, BTreeMap, HashMap, HashSet, - }, + collections::{btree_map::Entry as BTreeMapEntry, hash_map::Entry as HashMapEntry, BTreeMap, HashMap, HashSet}, time::{Duration, Instant}, }; @@ -415,7 +413,9 @@ impl QueuedHeaders

{ // for all headers that were incompleted previously, but now are completed, we move // all descendants from incomplete to ready - let just_completed_headers = self.incomplete_headers.keys() + let just_completed_headers = self + .incomplete_headers + .keys() .chain(self.completion_data.keys()) .filter(|id| !ids.contains(id)) .cloned() @@ -442,40 +442,36 @@ impl QueuedHeaders

{ /// Returns id of the header for which we want to fetch completion data. pub fn incomplete_header(&mut self) -> Option> { - queued_incomplete_header( - &mut self.incomplete_headers, - |last_fetch_time| { - let retry = match *last_fetch_time { - Some(last_fetch_time) => last_fetch_time.elapsed() > RETRY_FETCH_COMPLETION_INTERVAL, - None => true, - }; + queued_incomplete_header(&mut self.incomplete_headers, |last_fetch_time| { + let retry = match *last_fetch_time { + Some(last_fetch_time) => last_fetch_time.elapsed() > RETRY_FETCH_COMPLETION_INTERVAL, + None => true, + }; - if retry { - *last_fetch_time = Some(Instant::now()); - } + if retry { + *last_fetch_time = Some(Instant::now()); + } - retry - }, - ).map(|(id, _)| id) + retry + }) + .map(|(id, _)| id) } /// Returns header completion data to upload to target node. pub fn header_to_complete(&mut self) -> Option<(HeaderId, &P::Completion)> { - queued_incomplete_header( - &mut self.completion_data, - |incomplete_header| { - let retry = match incomplete_header.last_upload_time { - Some(last_upload_time) => last_upload_time.elapsed() > RETRY_COMPLETION_INTERVAL, - None => true, - }; + queued_incomplete_header(&mut self.completion_data, |incomplete_header| { + let retry = match incomplete_header.last_upload_time { + Some(last_upload_time) => last_upload_time.elapsed() > RETRY_COMPLETION_INTERVAL, + None => true, + }; - if retry { - incomplete_header.last_upload_time = Some(Instant::now()); - } + if retry { + incomplete_header.last_upload_time = Some(Instant::now()); + } - retry - }, - ).map(|(id, data)| (id, &data.completion)) + retry + }) + .map(|(id, data)| (id, &data.completion)) } /// Prune and never accep headers before this block. @@ -530,7 +526,7 @@ impl QueuedHeaders

{ self.incomplete_headers.contains_key(&parent_id) || self.completion_data.contains_key(&parent_id) || self.status(&parent_id) == HeaderStatus::Incomplete - }, + } None => false, } } @@ -740,11 +736,7 @@ fn set_header_status( id, status, ); - *known_headers - .entry(id.0) - .or_default() - .entry(id.1) - .or_insert(status) = status; + *known_headers.entry(id.0).or_default().entry(id.1).or_insert(status) = status; } /// Returns queued imcomplete header with maximal elapsed time since last update. @@ -758,17 +750,12 @@ fn queued_incomplete_header( let retry_old_header = map .front() .map(|(key, _)| key.clone()) - .and_then(|key| map - .get_mut(&key) - .map(filter) - ) + .and_then(|key| map.get_mut(&key).map(filter)) .unwrap_or(false); if retry_old_header { let (header_key, header) = map.pop_front().expect("we have checked that front() exists; qed"); map.insert(header_key, header); - return map - .back() - .map(|(id, data)| (id.clone(), data)); + return map.back().map(|(id, data)| (id.clone(), data)); } None diff --git a/relays/ethereum/src/substrate_client.rs b/relays/ethereum/src/substrate_client.rs index e86b506305..e62c12e31b 100644 --- a/relays/ethereum/src/substrate_client.rs +++ b/relays/ethereum/src/substrate_client.rs @@ -16,8 +16,8 @@ use crate::ethereum_types::{Bytes, EthereumHeaderId, QueuedEthereumHeader, H256}; use crate::substrate_types::{ - into_substrate_ethereum_header, into_substrate_ethereum_receipts, Hash, Header as SubstrateHeader, Number, - GrandpaJustification, SubstrateHeaderId, SignedBlock as SignedSubstrateBlock, + into_substrate_ethereum_header, into_substrate_ethereum_receipts, GrandpaJustification, Hash, + Header as SubstrateHeader, Number, SignedBlock as SignedSubstrateBlock, SubstrateHeaderId, }; use crate::sync_types::{HeaderId, MaybeConnectionError, SourceHeader}; use crate::{bail_on_arg_error, bail_on_error}; @@ -276,16 +276,16 @@ pub async fn submit_unsigned_ethereum_headers( } /// Get GRANDPA justification for given block. -pub async fn grandpa_justification(client: Client, id: SubstrateHeaderId) -> (Client, Result<(SubstrateHeaderId, Option), Error>) { +pub async fn grandpa_justification( + client: Client, + id: SubstrateHeaderId, +) -> (Client, Result<(SubstrateHeaderId, Option), Error>) { let hash = bail_on_arg_error!(to_value(id.1).map_err(|e| Error::RequestSerialization(e)), client); - let (client, signed_block) = call_rpc( + let (client, signed_block) = call_rpc(client, "chain_getBlock", Params::Array(vec![hash]), rpc_returns_value).await; + ( client, - "chain_getBlock", - Params::Array(vec![hash]), - rpc_returns_value, + signed_block.map(|signed_block: SignedSubstrateBlock| (id, signed_block.justification)), ) - .await; - (client, signed_block.map(|signed_block: SignedSubstrateBlock| (id, signed_block.justification))) } /// Get GRANDPA authorities set at given block. diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index b5027eccd3..10530252ea 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -20,8 +20,7 @@ use crate::ethereum_client::{self, EthereumConnectionParams, EthereumSigningPara use crate::ethereum_types::Address; use crate::substrate_client::{self, SubstrateConnectionParams}; use crate::substrate_types::{ - Hash, Header, Number, QueuedSubstrateHeader, SubstrateHeaderId, SubstrateHeadersSyncPipeline, - GrandpaJustification, + GrandpaJustification, Hash, Header, Number, QueuedSubstrateHeader, SubstrateHeaderId, SubstrateHeadersSyncPipeline, }; use crate::sync::{HeadersSyncParams, TargetTransactionMode}; use crate::sync_loop::{SourceClient, TargetClient}; @@ -92,7 +91,16 @@ impl SourceClient for SubstrateHeadersSource { type HeaderByHashFuture = Pin)>>>; type HeaderByNumberFuture = Pin)>>>; type HeaderExtraFuture = Ready<(Self, Result<(SubstrateHeaderId, ()), Self::Error>)>; - type HeaderCompletionFuture = Pin), Self::Error>)>>>; + type HeaderCompletionFuture = Pin< + Box< + dyn Future< + Output = ( + Self, + Result<(SubstrateHeaderId, Option), Self::Error>, + ), + >, + >, + >; fn best_block_number(self) -> Self::BestBlockNumberFuture { substrate_client::best_header(self.client) @@ -139,7 +147,8 @@ impl TargetClient for EthereumHeadersTarget { type IsKnownHeaderFuture = Pin)>>>; type RequiresExtraFuture = Ready<(Self, Result<(SubstrateHeaderId, bool), Self::Error>)>; type SubmitHeadersFuture = Pin, Self::Error>)>>>; - type IncompleteHeadersFuture = Pin, Self::Error>)>>>; + type IncompleteHeadersFuture = + Pin, Self::Error>)>>>; type CompleteHeadersFuture = Pin)>>>; fn best_header_id(self) -> Self::BestHeaderIdFuture { diff --git a/relays/ethereum/src/sync_loop.rs b/relays/ethereum/src/sync_loop.rs index b6357a2900..5fd0f7c585 100644 --- a/relays/ethereum/src/sync_loop.rs +++ b/relays/ethereum/src/sync_loop.rs @@ -51,7 +51,12 @@ pub trait SourceClient: Sized { /// Future that returns extra data associated with header. type HeaderExtraFuture: Future, P::Extra), Self::Error>)>; /// Future that returns data required to 'complete' header. - type HeaderCompletionFuture: Future, Option), Self::Error>)>; + type HeaderCompletionFuture: Future< + Output = ( + Self, + Result<(HeaderId, Option), Self::Error>, + ), + >; /// Get best block number. fn best_block_number(self) -> Self::BestBlockNumberFuture; @@ -93,7 +98,11 @@ pub trait TargetClient: Sized { /// Returns ID of headers that require to be 'completed' before children can be submitted. fn incomplete_headers_ids(self) -> Self::IncompleteHeadersFuture; /// Submit completion data for header. - fn complete_header(self, id: HeaderId, completion: P::Completion) -> Self::CompleteHeadersFuture; + fn complete_header( + self, + id: HeaderId, + completion: P::Completion, + ) -> Self::CompleteHeadersFuture; } /// Run headers synchronization. From 694ab997f6b402b21345c68bfe74ae32c80dad17 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 29 Apr 2020 10:30:42 +0300 Subject: [PATCH 57/92] comments --- relays/ethereum/src/headers.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index 196a2b4643..553a2a3df9 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -27,10 +27,10 @@ type HeadersQueue

= type KnownHeaders

= BTreeMap<

::Number, HashMap<

::Hash, HeaderStatus>>; -/// TODO -const RETRY_FETCH_COMPLETION_INTERVAL: Duration = Duration::from_millis(60_000); -/// TODO -const RETRY_COMPLETION_INTERVAL: Duration = Duration::from_millis(60_000); +/// We're trying to fetch completion data for single header at this interval. +const RETRY_FETCH_COMPLETION_INTERVAL: Duration = Duration::from_millis(60 * 1_000); +/// We're trying to submit completion data for single header at this interval. +const RETRY_COMPLETION_INTERVAL: Duration = Duration::from_millis(10 * 60 * 1_000); /// Ethereum headers queue. #[derive(Debug)] From d1192214554bffb2065355bdd784f5df056fe558 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 29 Apr 2020 10:38:58 +0300 Subject: [PATCH 58/92] disable completion data resubmission --- relays/ethereum/src/headers.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index 553a2a3df9..41ca2fb090 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -29,8 +29,6 @@ type KnownHeaders

= /// We're trying to fetch completion data for single header at this interval. const RETRY_FETCH_COMPLETION_INTERVAL: Duration = Duration::from_millis(60 * 1_000); -/// We're trying to submit completion data for single header at this interval. -const RETRY_COMPLETION_INTERVAL: Duration = Duration::from_millis(10 * 60 * 1_000); /// Ethereum headers queue. #[derive(Debug)] @@ -139,7 +137,6 @@ impl QueuedHeaders

{ /// Returns number of best block in the queue. pub fn best_queued_number(&self) -> P::Number { - // TODO: move submitted headers back to ready/incomplete periodically std::cmp::max( self.maybe_orphan.keys().next_back().cloned().unwrap_or_else(Zero::zero), std::cmp::max( @@ -461,7 +458,7 @@ impl QueuedHeaders

{ pub fn header_to_complete(&mut self) -> Option<(HeaderId, &P::Completion)> { queued_incomplete_header(&mut self.completion_data, |incomplete_header| { let retry = match incomplete_header.last_upload_time { - Some(last_upload_time) => last_upload_time.elapsed() > RETRY_COMPLETION_INTERVAL, + Some(_) => false, None => true, }; From f5f180129c08d4d9a07f76d05bd2b2caec2ff8c3 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 29 Apr 2020 10:39:18 +0300 Subject: [PATCH 59/92] increased timeouts + _MS -> Duration --- relays/ethereum/src/sync_loop.rs | 57 ++++++++++++++++---------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/relays/ethereum/src/sync_loop.rs b/relays/ethereum/src/sync_loop.rs index 5fd0f7c585..260031bdb8 100644 --- a/relays/ethereum/src/sync_loop.rs +++ b/relays/ethereum/src/sync_loop.rs @@ -18,7 +18,7 @@ use crate::sync::HeadersSyncParams; use crate::sync_types::{HeaderId, HeaderStatus, HeadersSyncPipeline, MaybeConnectionError, QueuedHeader}; use futures::{future::FutureExt, stream::StreamExt}; use num_traits::{Saturating, Zero}; -use std::{collections::HashSet, future::Future}; +use std::{collections::HashSet, future::Future, time::{Duration, Instant}}; /// When we submit headers to target node, but see no updates of best /// source block known to target node during STALL_SYNC_TIMEOUT_MS milliseconds, @@ -30,13 +30,13 @@ use std::{collections::HashSet, future::Future}; /// direct child of previous best header. But: (1) subscription doesn't guarantee that /// the subscriber will receive every best header (2) reorg won't always lead to sync /// stall and restart is a heavy operation (we forget all in-memory headers). -const STALL_SYNC_TIMEOUT_MS: u64 = 30_000; +const STALL_SYNC_TIMEOUT: Duration = Duration::from_millis(5 * 60 * 1_000); /// Delay (in milliseconds) after we have seen update of best source header at target node, /// for us to treat sync stalled. ONLY when relay operates in backup mode. -const BACKUP_STALL_SYNC_TIMEOUT_MS: u64 = 5 * 60_000; +const BACKUP_STALL_SYNC_TIMEOUT: Duration = Duration::from_millis(10 * 60 * 1_000); /// Delay (in milliseconds) after connection-related error happened before we'll try /// reconnection again. -const CONNECTION_ERROR_DELAY_MS: u64 = 10_000; +const CONNECTION_ERROR_DELAY: Duration = Duration::from_millis(10 * 1_000); /// Source client trait. pub trait SourceClient: Sized { @@ -114,12 +114,12 @@ pub fn run( sync_params: HeadersSyncParams, ) { let mut local_pool = futures::executor::LocalPool::new(); - let mut progress_context = (std::time::Instant::now(), None, None); + let mut progress_context = (Instant::now(), None, None); local_pool.run_until(async move { let mut sync = crate::sync::HeadersSync::

::new(sync_params); let mut stall_countdown = None; - let mut last_update_time = std::time::Instant::now(); + let mut last_update_time = Instant::now(); let mut source_maybe_client = None; let mut source_best_block_number_required = false; @@ -172,7 +172,7 @@ pub fn run( source_best_block_number, |source_best_block_number| sync.source_best_header_number_response(source_best_block_number), &mut source_go_offline_future, - |source_client| delay(CONNECTION_ERROR_DELAY_MS, source_client), + |source_client| delay(CONNECTION_ERROR_DELAY, source_client), || format!("Error retrieving best header number from {}", P::SOURCE_NAME), ); }, @@ -183,7 +183,7 @@ pub fn run( source_new_header, |source_new_header| sync.headers_mut().header_response(source_new_header), &mut source_go_offline_future, - |source_client| delay(CONNECTION_ERROR_DELAY_MS, source_client), + |source_client| delay(CONNECTION_ERROR_DELAY, source_client), || format!("Error retrieving header from {} node", P::SOURCE_NAME), ); }, @@ -194,7 +194,7 @@ pub fn run( source_orphan_header, |source_orphan_header| sync.headers_mut().header_response(source_orphan_header), &mut source_go_offline_future, - |source_client| delay(CONNECTION_ERROR_DELAY_MS, source_client), + |source_client| delay(CONNECTION_ERROR_DELAY, source_client), || format!("Error retrieving orphan header from {} node", P::SOURCE_NAME), ); }, @@ -205,7 +205,7 @@ pub fn run( source_extra, |(header, extra)| sync.headers_mut().extra_response(&header, extra), &mut source_go_offline_future, - |source_client| delay(CONNECTION_ERROR_DELAY_MS, source_client), + |source_client| delay(CONNECTION_ERROR_DELAY, source_client), || format!("Error retrieving extra data from {} node", P::SOURCE_NAME), ); }, @@ -216,7 +216,7 @@ pub fn run( source_completion, |(header, completion)| sync.headers_mut().completion_response(&header, completion), &mut source_go_offline_future, - |source_client| delay(CONNECTION_ERROR_DELAY_MS, source_client), + |source_client| delay(CONNECTION_ERROR_DELAY, source_client), || format!("Error retrieving completion data from {} node", P::SOURCE_NAME), ); }, @@ -238,21 +238,20 @@ pub fn run( |target_best_block| { let head_updated = sync.target_best_header_response(target_best_block); if head_updated { - last_update_time = std::time::Instant::now(); + last_update_time = Instant::now(); } match head_updated { // IF head is updated AND there are still our transactions: // => restart stall countdown timer true if sync.headers().headers_in_status(HeaderStatus::Submitted) != 0 => - stall_countdown = Some(std::time::Instant::now()), + stall_countdown = Some(Instant::now()), // IF head is updated AND there are no our transactions: // => stop stall countdown timer true => stall_countdown = None, // IF head is not updated AND stall countdown is not yet completed // => do nothing false if stall_countdown - .map(|stall_countdown| std::time::Instant::now() - stall_countdown < - std::time::Duration::from_millis(STALL_SYNC_TIMEOUT_MS)) + .map(|stall_countdown| stall_countdown.elaped() < STALL_SYNC_TIMEOUT) .unwrap_or(true) => (), // IF head is not updated AND stall countdown has completed @@ -270,7 +269,7 @@ pub fn run( } }, &mut target_go_offline_future, - |target_client| delay(CONNECTION_ERROR_DELAY_MS, target_client), + |target_client| delay(CONNECTION_ERROR_DELAY, target_client), || format!("Error retrieving best known header from {} node", P::TARGET_NAME), ); }, @@ -283,7 +282,7 @@ pub fn run( incomplete_headers_ids, |incomplete_headers_ids| sync.headers_mut().incomplete_headers_response(incomplete_headers_ids), &mut target_go_offline_future, - |target_client| delay(CONNECTION_ERROR_DELAY_MS, target_client), + |target_client| delay(CONNECTION_ERROR_DELAY, target_client), || format!("Error retrieving incomplete headers from {} node", P::TARGET_NAME), ); }, @@ -296,7 +295,7 @@ pub fn run( .headers_mut() .maybe_orphan_response(&target_header, target_existence_status), &mut target_go_offline_future, - |target_client| delay(CONNECTION_ERROR_DELAY_MS, target_client), + |target_client| delay(CONNECTION_ERROR_DELAY, target_client), || format!("Error retrieving existence status from {} node", P::TARGET_NAME), ); }, @@ -307,7 +306,7 @@ pub fn run( target_submit_header_result, |submitted_headers| sync.headers_mut().headers_submitted(submitted_headers), &mut target_go_offline_future, - |target_client| delay(CONNECTION_ERROR_DELAY_MS, target_client), + |target_client| delay(CONNECTION_ERROR_DELAY, target_client), || format!("Error submitting headers to {} node", P::TARGET_NAME), ); }, @@ -318,7 +317,7 @@ pub fn run( target_complete_header_result, |completed_header| sync.headers_mut().header_completed(&completed_header), &mut target_go_offline_future, - |target_client| delay(CONNECTION_ERROR_DELAY_MS, target_client), + |target_client| delay(CONNECTION_ERROR_DELAY, target_client), || format!("Error completing headers at {}", P::TARGET_NAME), ); }, @@ -331,7 +330,7 @@ pub fn run( .headers_mut() .maybe_extra_response(&header, extra_check_result), &mut target_go_offline_future, - |target_client| delay(CONNECTION_ERROR_DELAY_MS, target_client), + |target_client| delay(CONNECTION_ERROR_DELAY, target_client), || format!("Error retrieving receipts requirement from {} node", P::TARGET_NAME), ); }, @@ -392,7 +391,7 @@ pub fn run( target_existence_status_future.set(target_client.is_known_header(parent_id).fuse()); } else if let Some(headers) = sync.select_headers_to_submit( - last_update_time.elapsed() > std::time::Duration::from_millis(BACKUP_STALL_SYNC_TIMEOUT_MS), + last_update_time.elapsed() > BACKUP_STALL_SYNC_TIMEOUT, ) { let ids = match headers.len() { 1 => format!("{:?}", headers[0].id()), @@ -412,7 +411,7 @@ pub fn run( // remember that we have submitted some headers if stall_countdown.is_none() { - stall_countdown = Some(std::time::Instant::now()); + stall_countdown = Some(Instant::now()); } } else { target_maybe_client = Some(target_client); @@ -487,8 +486,8 @@ pub fn run( } /// Future that resolves into given value after given timeout. -async fn delay(timeout_ms: u64, retval: T) -> T { - async_std::task::sleep(std::time::Duration::from_millis(timeout_ms)).await; +async fn delay(timeout: Duration, retval: T) -> T { + async_std::task::sleep(timeout).await; retval } @@ -532,14 +531,14 @@ fn process_future_result( /// Print synchronization progress. fn print_sync_progress( - progress_context: (std::time::Instant, Option, Option), + progress_context: (Instant, Option, Option), eth_sync: &crate::sync::HeadersSync

, -) -> (std::time::Instant, Option, Option) { +) -> (Instant, Option, Option) { let (prev_time, prev_best_header, prev_target_header) = progress_context; - let now_time = std::time::Instant::now(); + let now_time = Instant::now(); let (now_best_header, now_target_header) = eth_sync.status(); - let need_update = now_time - prev_time > std::time::Duration::from_secs(10) + let need_update = now_time - prev_time > Duration::from_secs(10) || match (prev_best_header, now_best_header) { (Some(prev_best_header), Some(now_best_header)) => { now_best_header.0.saturating_sub(prev_best_header) > 10.into() From d243ca43a8c38214a9b197eb65ccd1c85c166c32 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 1 May 2020 08:31:02 +0300 Subject: [PATCH 60/92] forget completion data after submission --- relays/ethereum/src/ethereum_sync_loop.rs | 10 +++--- relays/ethereum/src/headers.rs | 42 +++++++++------------- relays/ethereum/src/substrate_sync_loop.rs | 10 +++--- relays/ethereum/src/sync_loop.rs | 14 ++++---- 4 files changed, 34 insertions(+), 42 deletions(-) diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index 6a3530b046..71ef58ee20 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -22,13 +22,13 @@ use crate::substrate_client::{self, SubstrateConnectionParams, SubstrateSigningP use crate::sync::{HeadersSyncParams, TargetTransactionMode}; use crate::sync_loop::{SourceClient, TargetClient}; use futures::future::{ready, FutureExt, Ready}; -use std::{collections::HashSet, future::Future, pin::Pin}; +use std::{collections::HashSet, future::Future, pin::Pin, time::Duration}; use web3::types::H256; /// Interval (in ms) at which we check new Ethereum headers when we are synced/almost synced. -const ETHEREUM_TICK_INTERVAL_MS: u64 = 10_000; +const ETHEREUM_TICK_INTERVAL: Duration = Duration::from_millis(10 * 1_000); /// Interval (in ms) at which we check new Substrate blocks. -const SUBSTRATE_TICK_INTERVAL_MS: u64 = 5_000; +const SUBSTRATE_TICK_INTERVAL: Duration = Duration::from_millis(5 * 1_000); /// Max number of headers in single submit transaction. const MAX_HEADERS_IN_SINGLE_SUBMIT: usize = 32; /// Max total size of headers in single submit transaction. This only affects signed @@ -223,13 +223,13 @@ pub fn run(params: EthereumSyncParams) { crate::sync_loop::run( EthereumHeadersSource { client: eth_client }, - ETHEREUM_TICK_INTERVAL_MS, + ETHEREUM_TICK_INTERVAL, SubstrateHeadersTarget { client: sub_client, sign_transactions: sign_sub_transactions, sign_params: params.sub_sign, }, - SUBSTRATE_TICK_INTERVAL_MS, + SUBSTRATE_TICK_INTERVAL, params.sync_params, ); } diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index 41ca2fb090..3c34be9a6d 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -28,7 +28,7 @@ type KnownHeaders

= BTreeMap<

::Number, HashMap<

::Hash, HeaderStatus>>; /// We're trying to fetch completion data for single header at this interval. -const RETRY_FETCH_COMPLETION_INTERVAL: Duration = Duration::from_millis(60 * 1_000); +const RETRY_FETCH_COMPLETION_INTERVAL: Duration = Duration::from_millis(20 * 1_000); /// Ethereum headers queue. #[derive(Debug)] @@ -60,8 +60,8 @@ pub struct QueuedHeaders { /// Headers that are waiting for completion data from source node. Mapped (and auto-sorted /// by) to the last fetch time. incomplete_headers: LinkedHashMap, Option>, - /// Headers that are waiting to be completed at target node. Auto-sorted by last upload time. - completion_data: LinkedHashMap, HeaderCompletion>, + /// Headers that are waiting to be completed at target node. Auto-sorted by insertion time. + completion_data: LinkedHashMap, P::Completion>, /// Pruned blocks border. We do not store or accept any blocks with number less than /// this number. prune_border: P::Number, @@ -341,10 +341,7 @@ impl QueuedHeaders

{ self.completion_data.insert( id.clone(), - HeaderCompletion { - last_upload_time: None, - completion, - }, + completion, ); } } @@ -365,7 +362,7 @@ impl QueuedHeaders

{ /// When header completion data is sent to target node. pub fn header_completed(&mut self, id: &HeaderId) { - if let Some(mut incomplete_header) = self.completion_data.remove(id) { + if let Some(_) = self.completion_data.remove(id) { log::debug!( target: "bridge", "Sent completion data to {} for header: {:?}", @@ -373,10 +370,17 @@ impl QueuedHeaders

{ id, ); - incomplete_header.last_upload_time = Some(Instant::now()); - - // reinsert it to maintain sorting - self.completion_data.insert(id.clone(), incomplete_header); + // transaction can be dropped by target chain nodes => it would never be mined + // + // in current implementation the sync loop would wait for some time && if best + // **source** header won't change on **target** node, then the sync will be restarted + // => we'll resubmit the same completion data again (the same is true for submitted + // headers) + // + // the other option would be to track emitted transactions at least on target node, + // but it won't give us 100% guarantee anyway + // + // => we're just dropping completion data just after it has been submitted } } @@ -456,19 +460,7 @@ impl QueuedHeaders

{ /// Returns header completion data to upload to target node. pub fn header_to_complete(&mut self) -> Option<(HeaderId, &P::Completion)> { - queued_incomplete_header(&mut self.completion_data, |incomplete_header| { - let retry = match incomplete_header.last_upload_time { - Some(_) => false, - None => true, - }; - - if retry { - incomplete_header.last_upload_time = Some(Instant::now()); - } - - retry - }) - .map(|(id, data)| (id, &data.completion)) + queued_incomplete_header(&mut self.completion_data, |_| true) } /// Prune and never accep headers before this block. diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index 10530252ea..1d7bb46caf 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -26,12 +26,12 @@ use crate::sync::{HeadersSyncParams, TargetTransactionMode}; use crate::sync_loop::{SourceClient, TargetClient}; use crate::sync_types::SourceHeader; use futures::future::{ready, FutureExt, Ready}; -use std::{collections::HashSet, future::Future, pin::Pin}; +use std::{collections::HashSet, future::Future, pin::Pin, time::Duration}; /// Interval (in ms) at which we check new Substrate headers when we are synced/almost synced. -const SUBSTRATE_TICK_INTERVAL_MS: u64 = 10_000; +const SUBSTRATE_TICK_INTERVAL: Duration = Duration::from_millis(10 * 1_000); /// Interval (in ms) at which we check new Ethereum blocks. -const ETHEREUM_TICK_INTERVAL_MS: u64 = 5_000; +const ETHEREUM_TICK_INTERVAL: Duration = Duration::from_millis(5 * 1_000); /// Max Ethereum headers we want to have in all 'before-submitted' states. const MAX_FUTURE_HEADERS_TO_DOWNLOAD: usize = 8; /// Max Ethereum headers count we want to have in 'submitted' state. @@ -243,13 +243,13 @@ pub fn run(params: SubstrateSyncParams) { crate::sync_loop::run( SubstrateHeadersSource { client: sub_client }, - SUBSTRATE_TICK_INTERVAL_MS, + SUBSTRATE_TICK_INTERVAL, EthereumHeadersTarget { client: eth_client, contract: params.eth_contract_address, sign_params: params.eth_sign, }, - ETHEREUM_TICK_INTERVAL_MS, + ETHEREUM_TICK_INTERVAL, params.sync_params, ); } diff --git a/relays/ethereum/src/sync_loop.rs b/relays/ethereum/src/sync_loop.rs index 260031bdb8..bec35bba79 100644 --- a/relays/ethereum/src/sync_loop.rs +++ b/relays/ethereum/src/sync_loop.rs @@ -108,9 +108,9 @@ pub trait TargetClient: Sized { /// Run headers synchronization. pub fn run( source_client: impl SourceClient

, - source_tick_ms: u64, + source_tick: Duration, target_client: impl TargetClient

, - target_tick_ms: u64, + target_tick: Duration, sync_params: HeadersSyncParams, ) { let mut local_pool = futures::executor::LocalPool::new(); @@ -129,7 +129,7 @@ pub fn run( let source_extra_future = futures::future::Fuse::terminated(); let source_completion_future = futures::future::Fuse::terminated(); let source_go_offline_future = futures::future::Fuse::terminated(); - let source_tick_stream = interval(source_tick_ms).fuse(); + let source_tick_stream = interval(source_tick).fuse(); let mut target_maybe_client = None; let mut target_best_block_required = false; @@ -141,7 +141,7 @@ pub fn run( let target_submit_header_future = futures::future::Fuse::terminated(); let target_complete_header_future = futures::future::Fuse::terminated(); let target_go_offline_future = futures::future::Fuse::terminated(); - let target_tick_stream = interval(target_tick_ms).fuse(); + let target_tick_stream = interval(target_tick).fuse(); futures::pin_mut!( source_best_block_number_future, @@ -251,7 +251,7 @@ pub fn run( // IF head is not updated AND stall countdown is not yet completed // => do nothing false if stall_countdown - .map(|stall_countdown| stall_countdown.elaped() < STALL_SYNC_TIMEOUT) + .map(|stall_countdown| stall_countdown.elapsed() < STALL_SYNC_TIMEOUT) .unwrap_or(true) => (), // IF head is not updated AND stall countdown has completed @@ -492,9 +492,9 @@ async fn delay(timeout: Duration, retval: T) -> T { } /// Stream that emits item every `timeout_ms` milliseconds. -fn interval(timeout_ms: u64) -> impl futures::Stream { +fn interval(timeout: Duration) -> impl futures::Stream { futures::stream::unfold((), move |_| async move { - delay(timeout_ms, ()).await; + delay(timeout, ()).await; Some(((), ())) }) } From d45fcff28920c4362584c8df6d013e9d2efadf5b Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 1 May 2020 14:07:21 +0300 Subject: [PATCH 61/92] builtin tests --- Cargo.lock | 1 + modules/ethereum-contract/builtin/Cargo.toml | 3 + modules/ethereum-contract/builtin/src/lib.rs | 123 +++++++++++++++++- .../res/substrate-bridge-bytecode.hex | 2 +- 4 files changed, 126 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 66bc93a4ab..db368e5000 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1067,6 +1067,7 @@ version = "0.1.0" dependencies = [ "bridge-node-runtime", "ethereum-types", + "hex-literal", "parity-scale-codec", "sc-finality-grandpa", "sp-blockchain", diff --git a/modules/ethereum-contract/builtin/Cargo.toml b/modules/ethereum-contract/builtin/Cargo.toml index 0e54c1d7dc..6963846f13 100644 --- a/modules/ethereum-contract/builtin/Cargo.toml +++ b/modules/ethereum-contract/builtin/Cargo.toml @@ -35,3 +35,6 @@ git = "https://github.com/paritytech/substrate/" version = "0.8.0-dev" rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" + +[dev-dependencies] +hex-literal = "0.2" \ No newline at end of file diff --git a/modules/ethereum-contract/builtin/src/lib.rs b/modules/ethereum-contract/builtin/src/lib.rs index 438ba2da23..629ae0ecff 100644 --- a/modules/ethereum-contract/builtin/src/lib.rs +++ b/modules/ethereum-contract/builtin/src/lib.rs @@ -36,7 +36,7 @@ pub enum Error { } /// Substrate header. -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub struct Header { /// Header hash. pub hash: Hash, @@ -49,7 +49,7 @@ pub struct Header { } /// GRANDPA validators set change signal. -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub struct ValidatorsSetSignal { /// Signal delay. pub delay: BlockNumber, @@ -117,3 +117,122 @@ pub fn verify_substrate_finality_proof( .map_err(Error::JustificationVerify) .map(|_| ()) } + +#[cfg(test)] +mod tests { + use hex_literal::hex; + use super::*; + + #[test] + fn to_substrate_block_number_succeeds() { + assert_eq!(to_substrate_block_number(U256::zero()).unwrap(), 0); + assert_eq!(to_substrate_block_number(U256::from(std::u32::MAX as u64)).unwrap(), 0xFFFFFFFF); + } + + #[test] + fn to_substrate_block_number_fails() { + assert!(matches!( + to_substrate_block_number(U256::from(std::u32::MAX as u64 + 1)), + Err(Error::BlockNumberDecode) + )); + } + + #[test] + fn from_substrate_block_number_succeeds() { + assert_eq!(from_substrate_block_number(0).unwrap(), U256::zero()); + assert_eq!(from_substrate_block_number(std::u32::MAX).unwrap(), U256::from(std::u32::MAX)); + } + + #[test] + fn substrate_header_without_signal_parsed() { + assert_eq!( + parse_substrate_header(&hex!("000000000000000000000000000000000000000000000000000000000000000000b2fc47904df5e355c6ab476d89fbc0733aeddbe302f0b94ba4eea9283f7e89e703170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c11131400")).unwrap(), + Header { + hash: "afbbeb92bf6ff14f60bdef0aa89f043dd403659ae82665238810ace0d761f6d0".parse().unwrap(), + parent_hash: Default::default(), + number: 0, + signal: None, + }, + ); + } + + #[test] + fn substrate_header_with_signal_parsed() { + assert_eq!( + parse_substrate_header(&hex!("c0ac300d4005141ea690f3df593e049739c227316eb7f05052f3ee077388b68b20822d6b412033aa9ac8e1722918eec5f25633529225754b3d4149982f5cacd4aae7b07c0ce2799416ce7877b9cefc7f596bea5e8813bb2a0abf760414073ca92810066175726120ae54c70f0000000004617572618901010c90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e0446524e4bf901010c439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f01000000000000005e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d901000000000000001dfe3e22cc0d45c70779c1095f7489a8ef3cf52d62fbd8c2fa38c9f1723502b501000000000000000000000005617572610101acd5bb6f958101f460c5f86a1c45f6a28bc66fa436508e3db597ba76edefa5552c09b76850fd34328fa938b591cc1d59445d713b4ab59c750f5cdccd259d0383")).unwrap(), + Header { + hash: "4444c880757dc15aa0aa54b26a7738131ffb33a95fc2b7cea1c1f5e933157ebd".parse().unwrap(), + parent_hash: "c0ac300d4005141ea690f3df593e049739c227316eb7f05052f3ee077388b68b".parse().unwrap(), + number: 8, + signal: Some(ValidatorsSetSignal { + delay: 0, + validators: hex!("0c439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f01000000000000005e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d901000000000000001dfe3e22cc0d45c70779c1095f7489a8ef3cf52d62fbd8c2fa38c9f1723502b50100000000000000").to_vec(), + }), + }, + ); + } + + #[test] + fn substrate_header_parse_fails() { + assert!(matches!( + parse_substrate_header(&[]), + Err(_) + )); + } + + #[test] + fn verify_substrate_finality_proof_succeeds() { + verify_substrate_finality_proof( + 8, + "a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f343775".parse().unwrap(), + 0, + &hex!("1488dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee0100000000000000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690100000000000000439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f01000000000000005e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d901000000000000001dfe3e22cc0d45c70779c1095f7489a8ef3cf52d62fbd8c2fa38c9f1723502b50100000000000000"), + &hex!("2600000000000000a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000010a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000d66b4ceb57ef8bcbc955071b597c8c5d2adcfdbb009c73f8438d342670fdeca9ac60686cbd58105b10f51d0a64a8e73b2e5829b2eab3248a008c472852130b00439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234fa2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000f5730c14d3cd22b7661e2f5fcb3139dd5fef37f946314a441d01b40ce1200ef70d810525f23fd278b588cd67473c200bda83c338c407b479386aa83798e5970b5e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d9a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000c78d6ec463f476461a695b4791d30e7626d16fdf72d7c252c2cad387495a97e8c2827ed4d5af853d6e05d31cb6fb7438c9481a7e9c6990d60a9bfaf6a6e1930988dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eea2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000052b4fc52d430286b3e2d650aa6e01b6ff4fae8b968893a62be789209eb97ee6e23780d3f5af7042d85bb48f1b202890b22724dfebce138826f66a5e00324320fd17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae6900"), + ).unwrap(); + } + + #[test] + fn verify_substrate_finality_proof_fails_when_wrong_block_is_finalized() { + verify_substrate_finality_proof( + 4, + Default::default(), + 0, + &hex!("1488dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee0100000000000000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690100000000000000439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f01000000000000005e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d901000000000000001dfe3e22cc0d45c70779c1095f7489a8ef3cf52d62fbd8c2fa38c9f1723502b50100000000000000"), + &hex!("2600000000000000a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000010a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000d66b4ceb57ef8bcbc955071b597c8c5d2adcfdbb009c73f8438d342670fdeca9ac60686cbd58105b10f51d0a64a8e73b2e5829b2eab3248a008c472852130b00439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234fa2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000f5730c14d3cd22b7661e2f5fcb3139dd5fef37f946314a441d01b40ce1200ef70d810525f23fd278b588cd67473c200bda83c338c407b479386aa83798e5970b5e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d9a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000c78d6ec463f476461a695b4791d30e7626d16fdf72d7c252c2cad387495a97e8c2827ed4d5af853d6e05d31cb6fb7438c9481a7e9c6990d60a9bfaf6a6e1930988dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eea2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000052b4fc52d430286b3e2d650aa6e01b6ff4fae8b968893a62be789209eb97ee6e23780d3f5af7042d85bb48f1b202890b22724dfebce138826f66a5e00324320fd17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae6900"), + ).unwrap_err(); + } + + #[test] + fn verify_substrate_finality_proof_fails_when_wrong_set_is_provided() { + verify_substrate_finality_proof( + 8, + "a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f343775".parse().unwrap(), + 0, + &hex!("1488dc3417d5058ec4b4503e0c12ea"), + &hex!("2600000000000000a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000010a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000d66b4ceb57ef8bcbc955071b597c8c5d2adcfdbb009c73f8438d342670fdeca9ac60686cbd58105b10f51d0a64a8e73b2e5829b2eab3248a008c472852130b00439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234fa2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000f5730c14d3cd22b7661e2f5fcb3139dd5fef37f946314a441d01b40ce1200ef70d810525f23fd278b588cd67473c200bda83c338c407b479386aa83798e5970b5e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d9a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000c78d6ec463f476461a695b4791d30e7626d16fdf72d7c252c2cad387495a97e8c2827ed4d5af853d6e05d31cb6fb7438c9481a7e9c6990d60a9bfaf6a6e1930988dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eea2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000052b4fc52d430286b3e2d650aa6e01b6ff4fae8b968893a62be789209eb97ee6e23780d3f5af7042d85bb48f1b202890b22724dfebce138826f66a5e00324320fd17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae6900"), + ).unwrap_err(); + } + + #[test] + fn verify_substrate_finality_proof_fails_when_wrong_set_id_is_provided() { + verify_substrate_finality_proof( + 8, + "a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f343775".parse().unwrap(), + 42, + &hex!("1488dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee0100000000000000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690100000000000000439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f01000000000000005e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d901000000000000001dfe3e22cc0d45c70779c1095f7489a8ef3cf52d62fbd8c2fa38c9f1723502b50100000000000000"), + &hex!("2600000000000000a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000010a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000d66b4ceb57ef8bcbc955071b597c8c5d2adcfdbb009c73f8438d342670fdeca9ac60686cbd58105b10f51d0a64a8e73b2e5829b2eab3248a008c472852130b00439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234fa2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000f5730c14d3cd22b7661e2f5fcb3139dd5fef37f946314a441d01b40ce1200ef70d810525f23fd278b588cd67473c200bda83c338c407b479386aa83798e5970b5e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d9a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000c78d6ec463f476461a695b4791d30e7626d16fdf72d7c252c2cad387495a97e8c2827ed4d5af853d6e05d31cb6fb7438c9481a7e9c6990d60a9bfaf6a6e1930988dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eea2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000052b4fc52d430286b3e2d650aa6e01b6ff4fae8b968893a62be789209eb97ee6e23780d3f5af7042d85bb48f1b202890b22724dfebce138826f66a5e00324320fd17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae6900"), + ).unwrap_err(); + + } + + #[test] + fn verify_substrate_finality_proof_fails_when_wrong_proof_is_provided() { + verify_substrate_finality_proof( + 8, + "a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f343775".parse().unwrap(), + 0, + &hex!("1488dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee0100000000000000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690100000000000000439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f01000000000000005e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d901000000000000001dfe3e22cc0d45c70779c1095f7489a8ef3cf52d62fbd8c2fa38c9f1723502b50100000000000000"), + &hex!("2600000000000000a2f45892"), + ).unwrap_err(); + } +} diff --git a/relays/ethereum/res/substrate-bridge-bytecode.hex b/relays/ethereum/res/substrate-bridge-bytecode.hex index 54c252b65d..5cfe9b82de 100644 --- a/relays/ethereum/res/substrate-bridge-bytecode.hex +++ b/relays/ethereum/res/substrate-bridge-bytecode.hex @@ -1 +1 @@ -60806040523480156200001157600080fd5b5060405162000e6738038062000e67833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b506040818152602083015192018051929491939192846401000000008211156200010f57600080fd5b9083019060208201858111156200012557600080fd5b82516401000000008111828201881017156200014057600080fd5b82525081516020918201929091019080838360005b838110156200016f57818101518382015260200162000155565b50505050905090810190601f1680156200019d5780820380516001836020036101000a031916815260200191505b50604052505050620001ae620003d4565b620001c2846001600160e01b03620002dc16565b805160008181556002918255604080840180516001908155825160e08101845281815260208088015181830190815293518286019081526080808a0151606085019081526001600160401b038e169185019190915260a0840188905260c084018890528951885260058352959096208251815460ff191690151517815593519284019290925593519482019490945590518051949550919390926200026f92600385019291019062000409565b506080820151600482810180546001600160401b03199081166001600160401b039485161790915560a0850151600585015560c09094015160069093019290925560038054909316908616179091558251620002d19190602085019062000409565b5050505050620004ae565b620002e6620003d4565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa6200031e57600080fd5b93519251915190519351929b50909950975090955093505082159050620003a757816001600160401b03811180156200035657600080fd5b506040519080825280601f01601f19166020018201604052801562000382576020820181803683370190505b50905087516020890160208301848184846011600019fa620003a357600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200044c57805160ff19168380011785556200047c565b828001600101855582156200047c579182015b828111156200047c5782518255916020019190600101906200045f565b506200048a9291506200048e565b5090565b620004ab91905b808211156200048a576000815560010162000495565b90565b6109a980620004be6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063871ebe181461005c578063a98bfaad1461008d578063d96a2deb146100aa578063e7af0779146100cb578063fae71ae814610173575b600080fd5b6100796004803603602081101561007257600080fd5b5035610225565b604080519115158252519081900360200190f35b610079600480360360208110156100a357600080fd5b503561023a565b6100b2610297565b6040805192835260208301919091528051918290030190f35b610171600480360360208110156100e157600080fd5b8101906020810181356401000000008111156100fc57600080fd5b82018360208201111561010e57600080fd5b8035906020019184600183028401116401000000008311171561013057600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506102af945050505050565b005b6101716004803603606081101561018957600080fd5b8135916020810135918101906060810160408201356401000000008111156101b057600080fd5b8201836020820111156101c257600080fd5b803590602001918460018302840111640100000000831117156101e457600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061058e945050505050565b60009081526005602052604090205460ff1690565b6000818152600560205260408120805460ff16801561025e57506001548160020154115b8015610271575080600601548160020154145b80156102905750600354600482015467ffffffffffffffff9081169116145b9392505050565b60008054808252600560205260409091206002015491565b6102b76107a8565b6102c0826106ac565b805160009081526005602052604090205490915060ff1615610329576040805162461bcd60e51b815260206004820152601760248201527f48656164657220697320616c7265616479206b6e6f776e000000000000000000604482015290519081900360640190fd5b6020808201516000908152600590915260409020805460ff168015610358575060018260400151038160020154145b6103935760405162461bcd60e51b81526004018080602001828103825260268152602001806108ee6026913960400191505060405180910390fd5b6006810154158015906103ad575080600201548160060154145b156103f6578160200151600254146103f65760405162461bcd60e51b81526004018080602001828103825260318152602001806109436031913960400191505060405180910390fd5b60068101546080830151511561046b578260400151811061045e576040805162461bcd60e51b815260206004820152601960248201527f4f7665726c617070696e67207369676e616c7320666f756e6400000000000000604482015290519081900360640190fd5b5060608201516040830151015b60048201546005830154600384015467ffffffffffffffff9092169160026000196001831615610100020190911604156104ac575060208401516001909101905b6040805160e0810182526001808252602088810151818401908152898501518486019081526080808c01516060870190815267ffffffffffffffff8a169187019190915260a0860188905260c086018a90528b51600090815260058552969096208551815460ff191690151517815591519382019390935591516002830155925180519293919261054392600385019201906107dd565b50608082015160048201805467ffffffffffffffff191667ffffffffffffffff90921691909117905560a0820151600582015560c09091015160069091015550509151600055505050565b60008281526005602052604090206002015483146105dd5760405162461bcd60e51b815260040180806020018281038252602f815260200180610914602f913960400191505060405180910390fd5b60025460006105ed85858561079e565b600081815260056020526040902060028281558101546001559091505b8282146106a457506000908152600560205260409020600181015460068201546002830154919291141561069f576005818101546000908152602091909152604090206003805467ffffffffffffffff198116600167ffffffffffffffff9283168101909216178255908201805461069892600492916002610100928216159290920260001901160461085b565b50506106a4565b61060a565b505050505050565b6106b46107a8565b600080600080600060608751602089016040516020810160208101602081016020810160a08588886010600019fa6106eb57600080fd5b93519251915190519351929b50909950975090955093505082159050610771578167ffffffffffffffff8111801561072257600080fd5b506040519080825280601f01601f19166020018201604052801561074d576020820181803683370190505b50905087516020890160208301848184846011600019fa61076d57600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6002549392505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061081e57805160ff191683800117855561084b565b8280016001018555821561084b579182015b8281111561084b578251825591602001919060010190610830565b506108579291506108d0565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610894578054855561084b565b8280016001018555821561084b57600052602060002091601f016020900482015b8281111561084b5782548255916001019190600101906108b5565b6108ea91905b8082111561085757600081556001016108d6565b9056fe4d697373696e6720706172656e74206865616465722066726f6d207468652073746f726167654d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f726167654d697373696e672072657175697265642066696e616c6974792070726f6f6620666f7220706172656e7420686561646572a26469706673582212206cc35a10288e85e37e14250b2d4af37dc4fbcd59635965d9ac0421cb8db1f66c64736f6c63430006060033 \ No newline at end of file +60806040523480156200001157600080fd5b506040516200131938038062001319833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b506040818152602083015192018051929491939192846401000000008211156200010f57600080fd5b9083019060208201858111156200012557600080fd5b82516401000000008111828201881017156200014057600080fd5b82525081516020918201929091019080838360005b838110156200016f57818101518382015260200162000155565b50505050905090810190601f1680156200019d5780820380516001836020036101000a031916815260200191505b50604052505050620001ae620003d5565b620001c2846001600160e01b03620002dc16565b805160008181556002918255604080840180516001908155825160e08101845281815260208088015181830190815293518286019081526080808a0151606085019081526001600160401b038e169185019190915260a0840188905260c084018890528951885260078352959096208251815460ff191690151517815593519284019290925593519482019490945590518051949550919390926200026f9260038501929101906200040a565b506080820151600482810180546001600160401b03199081166001600160401b039485161790915560a0850151600585015560c09094015160069093019290925560038054909316908616179091558251620002d1919060208501906200040a565b5050505050620004af565b620002e6620003d5565b60008060008060008651602088016040516020810160208101602081016020810160a08588886010600019fa6200031c57600080fd5b84519b5083519a50825199508151985080519750505050505050506060816001600160401b03811180156200035057600080fd5b506040519080825280601f01601f1916602001820160405280156200037c576020820181803683370190505b5090508115620003a85787516020890160208301848184846011600019fa620003a457600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200044d57805160ff19168380011785556200047d565b828001600101855582156200047d579182015b828111156200047d57825182559160200191906001019062000460565b506200048b9291506200048f565b5090565b620004ac91905b808211156200048b576000815560010162000496565b90565b610e5a80620004bf6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063374c2c261461005c578063871ebe18146100fd578063d96a2deb1461012e578063e7af07791461014f578063fae71ae8146101f7575b600080fd5b6100646102a9565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156100a8578181015183820152602001610090565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156100e75781810151838201526020016100cf565b5050505090500194505050505060405180910390f35b61011a6004803603602081101561011357600080fd5b50356103ae565b604080519115158252519081900360200190f35b6101366103c3565b6040805192835260208301919091528051918290030190f35b6101f56004803603602081101561016557600080fd5b81019060208101813564010000000081111561018057600080fd5b82018360208201111561019257600080fd5b803590602001918460018302840111640100000000831117156101b457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506103db945050505050565b005b6101f56004803603606081101561020d57600080fd5b81359160208101359181019060608101604082013564010000000081111561023457600080fd5b82018360208201111561024657600080fd5b8035906020019184600183028401116401000000008311171561026857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610779945050505050565b6005546060908190818167ffffffffffffffff811180156102c957600080fd5b506040519080825280602002602001820160405280156102f3578160200160208202803683370190505b50905060005b8281101561034e57600760006005838154811061031257fe5b906000526020600020015481526020019081526020016000206002015482828151811061033b57fe5b60209081029190910101526001016102f9565b508060058080548060200260200160405190810160405280929190818152602001828054801561039d57602002820191906000526020600020905b815481526020019060010190808311610389575b505050505090509350935050509091565b60009081526007602052604090205460ff1690565b60008054808252600760205260409091206002015491565b6103e3610c13565b6103ec826109de565b805160009081526007602052604090205490915060ff1615610455576040805162461bcd60e51b815260206004820152601760248201527f48656164657220697320616c7265616479206b6e6f776e000000000000000000604482015290519081900360640190fd5b6001548160400151116104995760405162461bcd60e51b8152600401808060200182810382526025815260200180610d596025913960400191505060405180910390fd5b6020808201516000908152600790915260409020805460ff1680156104c8575060018260400151038160020154145b6105035760405162461bcd60e51b8152600401808060200182810382526026815260200180610d7e6026913960400191505060405180910390fd5b60068101541580159061051d575080600201548160060154145b15610566578160200151600254146105665760405162461bcd60e51b8152600401808060200182810382526031815260200180610df46031913960400191505060405180910390fd5b60048101546005820154600683015460808501515167ffffffffffffffff90931692156106445767ffffffffffffffff83811614156105d65760405162461bcd60e51b8152600401808060200182810382526021815260200180610da46021913960400191505060405180910390fd5b8460400151811061062e576040805162461bcd60e51b815260206004820152601960248201527f4f7665726c617070696e67207369676e616c7320666f756e6400000000000000604482015290519081900360640190fd5b5050825160608401516040850151600190930192015b8460400151811415610697576005805486516001820180845560009384527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0909201558651825260066020526040909120555b6040805160e0810182526001808252602088810151818401908152898501518486019081526080808c01516060870190815267ffffffffffffffff8b169187019190915260a0860189905260c086018890528b51600090815260078552969096208551815460ff191690151517815591519382019390935591516002830155925180519293919261072e9260038501920190610c48565b50608082015160048201805467ffffffffffffffff191667ffffffffffffffff90921691909117905560a0820151600582015560c09091015160069091015550509151600055505050565b60008281526007602052604090206002015483146107c85760405162461bcd60e51b815260040180806020018281038252602f815260200180610dc5602f913960400191505060405180910390fd5b60028054600354600480546040805160206101006001851615026000190190931696909604601f81018390048302870183019091528086529394600094610879948a948a9467ffffffffffffffff9092169392909183018282801561086e5780601f106108435761010080835404028352916020019161086e565b820191906000526020600020905b81548152906001019060200180831161085157829003601f168201915b505050505087610ad1565b600081815260076020526040902060028281558101546001559091505b8282146109d657506000818152600760209081526040808320600181015460069093529220549092908015610958576005546000199182019181018214610924576000600560018303815481106108e957fe5b90600052602060002001549050806005848154811061090457fe5b600091825260208083209091019290925591825260069052604090208290555b600580548061092f57fe5b600082815260208082208301600019908101839055909201909255848252600690526040812055505b8260060154836002015414156109cf57600583015460009081526007602052604090206003805467ffffffffffffffff198116600167ffffffffffffffff928316810190921617825590820180546109c6926004929160026101009282161592909202600019011604610cc6565b505050506109d6565b5050610896565b505050505050565b6109e6610c13565b60008060008060008651602088016040516020810160208101602081016020810160a08588886010600019fa610a1b57600080fd5b84519b5083519a508251995081519850805197505050505050505060608167ffffffffffffffff81118015610a4f57600080fd5b506040519080825280601f01601f191660200182016040528015610a7a576020820181803683370190505b5090508115610aa45787516020890160208301848184846011600019fa610aa057600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b600060608686868686604051602001808681526020018581526020018467ffffffffffffffff1667ffffffffffffffff1681526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015610b44578181015183820152602001610b2c565b50505050905090810190601f168015610b715780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015610ba4578181015183820152602001610b8c565b50505050905090810190601f168015610bd15780820380516001836020036101000a031916815260200191505b50975050505050505050604051602081830303815290604052905080516020820160008083836012600019fa610c0657600080fd5b5095979650505050505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610c8957805160ff1916838001178555610cb6565b82800160010185558215610cb6579182015b82811115610cb6578251825591602001919060010190610c9b565b50610cc2929150610d3b565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610cff5780548555610cb6565b82800160010185558215610cb657600052602060002091601f016020900482015b82811115610cb6578254825591600101919060010190610d20565b610d5591905b80821115610cc25760008155600101610d41565b9056fe547279696e6720746f20696d706f7274206e6f6e2d63616e6f6e6963616c206865616465724d697373696e6720706172656e74206865616465722066726f6d207468652073746f7261676552656163686564206d6178696d616c2076616c696461746f7273207365742069644d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f726167654d697373696e672072657175697265642066696e616c6974792070726f6f6620666f7220706172656e7420686561646572a2646970667358221220d0503056a44ea3cd035299ca78b667561caa71d66f52f3cfbab986a008eb79bc64736f6c63430006060033 \ No newline at end of file From 92d781d39e6be1096c50c2a58808016447dec5d2 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 1 May 2020 14:49:04 +0300 Subject: [PATCH 62/92] headers tests --- relays/ethereum/src/headers.rs | 189 ++++++++++++++++++++++++++++++++- 1 file changed, 186 insertions(+), 3 deletions(-) diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index 3c34be9a6d..d03b5d8b1f 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -475,7 +475,7 @@ impl QueuedHeaders

{ prune_queue(&mut self.extra, prune_border); prune_queue(&mut self.ready, prune_border); prune_queue(&mut self.submitted, prune_border); - prune_queue(&mut self.submitted, prune_border); + prune_queue(&mut self.incomplete, prune_border); prune_known_headers::

(&mut self.known_headers, prune_border); self.prune_border = prune_border; } @@ -801,7 +801,11 @@ pub(crate) mod tests { hash(6), QueuedHeader::::new(Default::default()), ); - assert_eq!(queue.total_headers(), 6); + queue.incomplete.entry(6).or_default().insert( + hash(7), + QueuedHeader::::new(Default::default()), + ); + assert_eq!(queue.total_headers(), 7); } #[test] @@ -845,6 +849,12 @@ pub(crate) mod tests { QueuedHeader::::new(Default::default()), ); assert_eq!(queue.best_queued_number(), 40); + // and then there's some header in Incomplete + queue.incomplete.entry(50).or_default().insert( + hash(50), + QueuedHeader::::new(Default::default()), + ); + assert_eq!(queue.best_queued_number(), 50); } #[test] @@ -1152,6 +1162,7 @@ pub(crate) mod tests { #[test] fn negative_maybe_extra_response_works() { + // when parent header is complete let mut queue = QueuedHeaders::::new(); queue .known_headers @@ -1163,10 +1174,24 @@ pub(crate) mod tests { assert!(queue.maybe_extra.is_empty()); assert_eq!(queue.ready.len(), 1); assert_eq!(queue.known_headers[&100][&hash(100)], HeaderStatus::Ready); + + // when parent header is incomplete + queue.incomplete_headers.insert(id(200), None); + queue + .known_headers + .entry(201) + .or_default() + .insert(hash(201), HeaderStatus::MaybeExtra); + queue.maybe_extra.entry(201).or_default().insert(hash(201), header(201)); + queue.maybe_extra_response(&id(201), false); + assert!(queue.maybe_extra.is_empty()); + assert_eq!(queue.incomplete.len(), 1); + assert_eq!(queue.known_headers[&201][&hash(201)], HeaderStatus::Incomplete); } #[test] fn receipts_response_works() { + // when parent header is complete let mut queue = QueuedHeaders::::new(); queue .known_headers @@ -1178,6 +1203,19 @@ pub(crate) mod tests { assert!(queue.extra.is_empty()); assert_eq!(queue.ready.len(), 1); assert_eq!(queue.known_headers[&100][&hash(100)], HeaderStatus::Ready); + + // when parent header is incomplete + queue.incomplete_headers.insert(id(200), None); + queue + .known_headers + .entry(201) + .or_default() + .insert(hash(201), HeaderStatus::Extra); + queue.extra.entry(201).or_default().insert(hash(201), header(201)); + queue.extra_response(&id(201), Vec::new()); + assert!(queue.extra.is_empty()); + assert_eq!(queue.incomplete.len(), 1); + assert_eq!(queue.known_headers[&201][&hash(201)], HeaderStatus::Incomplete); } #[test] @@ -1194,9 +1232,152 @@ pub(crate) mod tests { assert_eq!(queue.known_headers[&100][&hash(100)], HeaderStatus::Submitted); } + #[test] + fn incomplete_header_works() { + let mut queue = QueuedHeaders::::new(); + + // nothing to complete if queue is empty + assert_eq!(queue.incomplete_header(), None); + + // when there's new header to complete => ask for completion data + queue.incomplete_headers.insert(id(100), None); + assert_eq!(queue.incomplete_header(), Some(id(100))); + + // we have just asked for completion data => nothing to request + assert_eq!(queue.incomplete_header(), None); + + // enough time have passed => ask again + queue.incomplete_headers.clear(); + queue.incomplete_headers.insert( + id(100), + Some(Instant::now() - RETRY_FETCH_COMPLETION_INTERVAL - RETRY_FETCH_COMPLETION_INTERVAL), + ); + assert_eq!(queue.incomplete_header(), Some(id(100))); + } + + #[test] + fn completion_response_works() { + let mut queue = QueuedHeaders::::new(); + queue.incomplete_headers.insert(id(100), None); + queue.incomplete_headers.insert(id(200), Some(Instant::now())); + + // when headers isn't incompete, nothing changes + queue.completion_response(&id(300), None); + assert_eq!(queue.incomplete_headers.len(), 2); + assert_eq!(queue.completion_data.len(), 0); + assert_eq!(queue.header_to_complete(), None); + + // when response is None, nothing changes + queue.completion_response(&id(100), None); + assert_eq!(queue.incomplete_headers.len(), 2); + assert_eq!(queue.completion_data.len(), 0); + assert_eq!(queue.header_to_complete(), None); + + // when response is Some, we're scheduling completion + queue.completion_response(&id(200), Some(())); + assert_eq!(queue.incomplete_headers.len(), 1); + assert_eq!(queue.completion_data.len(), 1); + assert!(queue.incomplete_headers.contains_key(&id(100))); + assert!(queue.completion_data.contains_key(&id(200))); + assert_eq!(queue.header_to_complete(), Some((id(200), &()))); + } + + #[test] + fn header_completed_works() { + let mut queue = QueuedHeaders::::new(); + queue.completion_data.insert(id(100), ()); + + // when unknown header is completed + queue.header_completed(&id(200)); + assert_eq!(queue.completion_data.len(), 1); + + // when known header is completed + queue.header_completed(&id(100)); + assert_eq!(queue.completion_data.len(), 0); + } + + #[test] + fn incomplete_headers_response_works() { + let mut queue = QueuedHeaders::::new(); + + // when we have already submitted #101 and #102 is ready + queue.known_headers.entry(101).or_default().insert(hash(101), HeaderStatus::Submitted); + queue.submitted.entry(101).or_default().insert(hash(101), header(101)); + queue.known_headers.entry(102).or_default().insert(hash(102), HeaderStatus::Ready); + queue.submitted.entry(102).or_default().insert(hash(102), header(102)); + + // AND now we know that the #100 is incomplete + queue.incomplete_headers_response(vec![id(100)].into_iter().collect()); + + // => #101 and #102 are moved to the Incomplete and #100 is now synced + assert_eq!(queue.status(&id(100)), HeaderStatus::Synced); + assert_eq!(queue.status(&id(101)), HeaderStatus::Incomplete); + assert_eq!(queue.status(&id(102)), HeaderStatus::Incomplete); + assert_eq!(queue.submitted.len(), 0); + assert_eq!(queue.ready.len(), 0); + assert!(queue.incomplete.entry(101).or_default().contains_key(&hash(101))); + assert!(queue.incomplete.entry(102).or_default().contains_key(&hash(102))); + assert!(queue.incomplete_headers.contains_key(&id(100))); + assert!(queue.completion_data.is_empty()); + + // and then header #100 is no longer incomplete + queue.incomplete_headers_response(vec![].into_iter().collect()); + + // => #101 and #102 are moved to the Ready queue and #100 if now forgotten + assert_eq!(queue.status(&id(100)), HeaderStatus::Synced); + assert_eq!(queue.status(&id(101)), HeaderStatus::Ready); + assert_eq!(queue.status(&id(102)), HeaderStatus::Ready); + assert_eq!(queue.incomplete.len(), 0); + assert_eq!(queue.submitted.len(), 0); + assert!(queue.ready.entry(101).or_default().contains_key(&hash(101))); + assert!(queue.ready.entry(102).or_default().contains_key(&hash(102))); + assert!(queue.incomplete_headers.is_empty()); + assert!(queue.completion_data.is_empty()); + } + + #[test] + fn is_parent_incomplete_works() { + let mut queue = QueuedHeaders::::new(); + + // when we do not know header itself + assert_eq!(queue.is_parent_incomplete(&id(50)), false); + + // when we do not know parent + queue.known_headers.entry(100).or_default().insert(hash(100), HeaderStatus::Incomplete); + queue.incomplete.entry(100).or_default().insert(hash(100), header(100)); + assert_eq!(queue.is_parent_incomplete(&id(100)), false); + + // when parent is inside incomplete queue (i.e. some other ancestor is actually incomplete) + queue.known_headers.entry(101).or_default().insert(hash(101), HeaderStatus::Submitted); + queue.submitted.entry(101).or_default().insert(hash(101), header(101)); + assert_eq!(queue.is_parent_incomplete(&id(101)), true); + + // when parent is the incomplete header and we do not have completion data + queue.incomplete_headers.insert(id(199), None); + queue.known_headers.entry(200).or_default().insert(hash(200), HeaderStatus::Submitted); + queue.submitted.entry(200).or_default().insert(hash(200), header(200)); + assert_eq!(queue.is_parent_incomplete(&id(200)), true); + + // when parent is the incomplete header and we have completion data + queue.completion_data.insert(id(299), ()); + queue.known_headers.entry(300).or_default().insert(hash(300), HeaderStatus::Submitted); + queue.submitted.entry(300).or_default().insert(hash(300), header(300)); + assert_eq!(queue.is_parent_incomplete(&id(300)), true); + } + #[test] fn prune_works() { let mut queue = QueuedHeaders::::new(); + queue + .known_headers + .entry(105) + .or_default() + .insert(hash(105), HeaderStatus::Incomplete); + queue + .incomplete + .entry(105) + .or_default() + .insert(hash(105), header(105)); queue .known_headers .entry(104) @@ -1239,7 +1420,8 @@ pub(crate) mod tests { assert_eq!(queue.maybe_extra.len(), 1); assert_eq!(queue.orphan.len(), 1); assert_eq!(queue.maybe_orphan.len(), 1); - assert_eq!(queue.known_headers.len(), 3); + assert_eq!(queue.incomplete.len(), 1); + assert_eq!(queue.known_headers.len(), 4); queue.prune(110); @@ -1248,6 +1430,7 @@ pub(crate) mod tests { assert_eq!(queue.maybe_extra.len(), 0); assert_eq!(queue.orphan.len(), 0); assert_eq!(queue.maybe_orphan.len(), 0); + assert_eq!(queue.incomplete.len(), 0); assert_eq!(queue.known_headers.len(), 0); queue.header_response(header(109).header().clone()); From 295abdf9a3f9bbb895e8025bf4d39778a18beaaa Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 1 May 2020 14:49:46 +0300 Subject: [PATCH 63/92] cargo fmt --all --- modules/ethereum-contract/builtin/src/lib.rs | 18 ++++---- relays/ethereum/src/headers.rs | 47 +++++++++++++------- relays/ethereum/src/sync_loop.rs | 12 +++-- 3 files changed, 50 insertions(+), 27 deletions(-) diff --git a/modules/ethereum-contract/builtin/src/lib.rs b/modules/ethereum-contract/builtin/src/lib.rs index 629ae0ecff..de48d6ba6f 100644 --- a/modules/ethereum-contract/builtin/src/lib.rs +++ b/modules/ethereum-contract/builtin/src/lib.rs @@ -120,13 +120,16 @@ pub fn verify_substrate_finality_proof( #[cfg(test)] mod tests { - use hex_literal::hex; use super::*; + use hex_literal::hex; #[test] fn to_substrate_block_number_succeeds() { assert_eq!(to_substrate_block_number(U256::zero()).unwrap(), 0); - assert_eq!(to_substrate_block_number(U256::from(std::u32::MAX as u64)).unwrap(), 0xFFFFFFFF); + assert_eq!( + to_substrate_block_number(U256::from(std::u32::MAX as u64)).unwrap(), + 0xFFFFFFFF + ); } #[test] @@ -140,7 +143,10 @@ mod tests { #[test] fn from_substrate_block_number_succeeds() { assert_eq!(from_substrate_block_number(0).unwrap(), U256::zero()); - assert_eq!(from_substrate_block_number(std::u32::MAX).unwrap(), U256::from(std::u32::MAX)); + assert_eq!( + from_substrate_block_number(std::u32::MAX).unwrap(), + U256::from(std::u32::MAX) + ); } #[test] @@ -174,10 +180,7 @@ mod tests { #[test] fn substrate_header_parse_fails() { - assert!(matches!( - parse_substrate_header(&[]), - Err(_) - )); + assert!(matches!(parse_substrate_header(&[]), Err(_))); } #[test] @@ -222,7 +225,6 @@ mod tests { &hex!("1488dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee0100000000000000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690100000000000000439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f01000000000000005e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d901000000000000001dfe3e22cc0d45c70779c1095f7489a8ef3cf52d62fbd8c2fa38c9f1723502b50100000000000000"), &hex!("2600000000000000a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000010a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000d66b4ceb57ef8bcbc955071b597c8c5d2adcfdbb009c73f8438d342670fdeca9ac60686cbd58105b10f51d0a64a8e73b2e5829b2eab3248a008c472852130b00439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234fa2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000f5730c14d3cd22b7661e2f5fcb3139dd5fef37f946314a441d01b40ce1200ef70d810525f23fd278b588cd67473c200bda83c338c407b479386aa83798e5970b5e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d9a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000c78d6ec463f476461a695b4791d30e7626d16fdf72d7c252c2cad387495a97e8c2827ed4d5af853d6e05d31cb6fb7438c9481a7e9c6990d60a9bfaf6a6e1930988dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eea2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000052b4fc52d430286b3e2d650aa6e01b6ff4fae8b968893a62be789209eb97ee6e23780d3f5af7042d85bb48f1b202890b22724dfebce138826f66a5e00324320fd17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae6900"), ).unwrap_err(); - } #[test] diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index d03b5d8b1f..86ea0219f8 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -339,10 +339,7 @@ impl QueuedHeaders

{ id, ); - self.completion_data.insert( - id.clone(), - completion, - ); + self.completion_data.insert(id.clone(), completion); } } @@ -1301,9 +1298,17 @@ pub(crate) mod tests { let mut queue = QueuedHeaders::::new(); // when we have already submitted #101 and #102 is ready - queue.known_headers.entry(101).or_default().insert(hash(101), HeaderStatus::Submitted); + queue + .known_headers + .entry(101) + .or_default() + .insert(hash(101), HeaderStatus::Submitted); queue.submitted.entry(101).or_default().insert(hash(101), header(101)); - queue.known_headers.entry(102).or_default().insert(hash(102), HeaderStatus::Ready); + queue + .known_headers + .entry(102) + .or_default() + .insert(hash(102), HeaderStatus::Ready); queue.submitted.entry(102).or_default().insert(hash(102), header(102)); // AND now we know that the #100 is incomplete @@ -1343,24 +1348,40 @@ pub(crate) mod tests { assert_eq!(queue.is_parent_incomplete(&id(50)), false); // when we do not know parent - queue.known_headers.entry(100).or_default().insert(hash(100), HeaderStatus::Incomplete); + queue + .known_headers + .entry(100) + .or_default() + .insert(hash(100), HeaderStatus::Incomplete); queue.incomplete.entry(100).or_default().insert(hash(100), header(100)); assert_eq!(queue.is_parent_incomplete(&id(100)), false); // when parent is inside incomplete queue (i.e. some other ancestor is actually incomplete) - queue.known_headers.entry(101).or_default().insert(hash(101), HeaderStatus::Submitted); + queue + .known_headers + .entry(101) + .or_default() + .insert(hash(101), HeaderStatus::Submitted); queue.submitted.entry(101).or_default().insert(hash(101), header(101)); assert_eq!(queue.is_parent_incomplete(&id(101)), true); // when parent is the incomplete header and we do not have completion data queue.incomplete_headers.insert(id(199), None); - queue.known_headers.entry(200).or_default().insert(hash(200), HeaderStatus::Submitted); + queue + .known_headers + .entry(200) + .or_default() + .insert(hash(200), HeaderStatus::Submitted); queue.submitted.entry(200).or_default().insert(hash(200), header(200)); assert_eq!(queue.is_parent_incomplete(&id(200)), true); // when parent is the incomplete header and we have completion data queue.completion_data.insert(id(299), ()); - queue.known_headers.entry(300).or_default().insert(hash(300), HeaderStatus::Submitted); + queue + .known_headers + .entry(300) + .or_default() + .insert(hash(300), HeaderStatus::Submitted); queue.submitted.entry(300).or_default().insert(hash(300), header(300)); assert_eq!(queue.is_parent_incomplete(&id(300)), true); } @@ -1373,11 +1394,7 @@ pub(crate) mod tests { .entry(105) .or_default() .insert(hash(105), HeaderStatus::Incomplete); - queue - .incomplete - .entry(105) - .or_default() - .insert(hash(105), header(105)); + queue.incomplete.entry(105).or_default().insert(hash(105), header(105)); queue .known_headers .entry(104) diff --git a/relays/ethereum/src/sync_loop.rs b/relays/ethereum/src/sync_loop.rs index bec35bba79..44397371c3 100644 --- a/relays/ethereum/src/sync_loop.rs +++ b/relays/ethereum/src/sync_loop.rs @@ -18,7 +18,11 @@ use crate::sync::HeadersSyncParams; use crate::sync_types::{HeaderId, HeaderStatus, HeadersSyncPipeline, MaybeConnectionError, QueuedHeader}; use futures::{future::FutureExt, stream::StreamExt}; use num_traits::{Saturating, Zero}; -use std::{collections::HashSet, future::Future, time::{Duration, Instant}}; +use std::{ + collections::HashSet, + future::Future, + time::{Duration, Instant}, +}; /// When we submit headers to target node, but see no updates of best /// source block known to target node during STALL_SYNC_TIMEOUT_MS milliseconds, @@ -390,9 +394,9 @@ pub fn run( ); target_existence_status_future.set(target_client.is_known_header(parent_id).fuse()); - } else if let Some(headers) = sync.select_headers_to_submit( - last_update_time.elapsed() > BACKUP_STALL_SYNC_TIMEOUT, - ) { + } else if let Some(headers) = + sync.select_headers_to_submit(last_update_time.elapsed() > BACKUP_STALL_SYNC_TIMEOUT) + { let ids = match headers.len() { 1 => format!("{:?}", headers[0].id()), 2 => format!("[{:?}, {:?}]", headers[0].id(), headers[1].id()), From 455e2fda5de7df951e8ff2d634a6c09f0da5f352 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 1 May 2020 15:14:24 +0300 Subject: [PATCH 64/92] update contract --- relays/ethereum/res/substrate-bridge-bytecode.hex | 2 +- relays/ethereum/res/substrate-bridge-metadata.txt | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/relays/ethereum/res/substrate-bridge-bytecode.hex b/relays/ethereum/res/substrate-bridge-bytecode.hex index 5cfe9b82de..6b3b74df48 100644 --- a/relays/ethereum/res/substrate-bridge-bytecode.hex +++ b/relays/ethereum/res/substrate-bridge-bytecode.hex @@ -1 +1 @@ -60806040523480156200001157600080fd5b506040516200131938038062001319833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b506040818152602083015192018051929491939192846401000000008211156200010f57600080fd5b9083019060208201858111156200012557600080fd5b82516401000000008111828201881017156200014057600080fd5b82525081516020918201929091019080838360005b838110156200016f57818101518382015260200162000155565b50505050905090810190601f1680156200019d5780820380516001836020036101000a031916815260200191505b50604052505050620001ae620003d5565b620001c2846001600160e01b03620002dc16565b805160008181556002918255604080840180516001908155825160e08101845281815260208088015181830190815293518286019081526080808a0151606085019081526001600160401b038e169185019190915260a0840188905260c084018890528951885260078352959096208251815460ff191690151517815593519284019290925593519482019490945590518051949550919390926200026f9260038501929101906200040a565b506080820151600482810180546001600160401b03199081166001600160401b039485161790915560a0850151600585015560c09094015160069093019290925560038054909316908616179091558251620002d1919060208501906200040a565b5050505050620004af565b620002e6620003d5565b60008060008060008651602088016040516020810160208101602081016020810160a08588886010600019fa6200031c57600080fd5b84519b5083519a50825199508151985080519750505050505050506060816001600160401b03811180156200035057600080fd5b506040519080825280601f01601f1916602001820160405280156200037c576020820181803683370190505b5090508115620003a85787516020890160208301848184846011600019fa620003a457600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200044d57805160ff19168380011785556200047d565b828001600101855582156200047d579182015b828111156200047d57825182559160200191906001019062000460565b506200048b9291506200048f565b5090565b620004ac91905b808211156200048b576000815560010162000496565b90565b610e5a80620004bf6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063374c2c261461005c578063871ebe18146100fd578063d96a2deb1461012e578063e7af07791461014f578063fae71ae8146101f7575b600080fd5b6100646102a9565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156100a8578181015183820152602001610090565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156100e75781810151838201526020016100cf565b5050505090500194505050505060405180910390f35b61011a6004803603602081101561011357600080fd5b50356103ae565b604080519115158252519081900360200190f35b6101366103c3565b6040805192835260208301919091528051918290030190f35b6101f56004803603602081101561016557600080fd5b81019060208101813564010000000081111561018057600080fd5b82018360208201111561019257600080fd5b803590602001918460018302840111640100000000831117156101b457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506103db945050505050565b005b6101f56004803603606081101561020d57600080fd5b81359160208101359181019060608101604082013564010000000081111561023457600080fd5b82018360208201111561024657600080fd5b8035906020019184600183028401116401000000008311171561026857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610779945050505050565b6005546060908190818167ffffffffffffffff811180156102c957600080fd5b506040519080825280602002602001820160405280156102f3578160200160208202803683370190505b50905060005b8281101561034e57600760006005838154811061031257fe5b906000526020600020015481526020019081526020016000206002015482828151811061033b57fe5b60209081029190910101526001016102f9565b508060058080548060200260200160405190810160405280929190818152602001828054801561039d57602002820191906000526020600020905b815481526020019060010190808311610389575b505050505090509350935050509091565b60009081526007602052604090205460ff1690565b60008054808252600760205260409091206002015491565b6103e3610c13565b6103ec826109de565b805160009081526007602052604090205490915060ff1615610455576040805162461bcd60e51b815260206004820152601760248201527f48656164657220697320616c7265616479206b6e6f776e000000000000000000604482015290519081900360640190fd5b6001548160400151116104995760405162461bcd60e51b8152600401808060200182810382526025815260200180610d596025913960400191505060405180910390fd5b6020808201516000908152600790915260409020805460ff1680156104c8575060018260400151038160020154145b6105035760405162461bcd60e51b8152600401808060200182810382526026815260200180610d7e6026913960400191505060405180910390fd5b60068101541580159061051d575080600201548160060154145b15610566578160200151600254146105665760405162461bcd60e51b8152600401808060200182810382526031815260200180610df46031913960400191505060405180910390fd5b60048101546005820154600683015460808501515167ffffffffffffffff90931692156106445767ffffffffffffffff83811614156105d65760405162461bcd60e51b8152600401808060200182810382526021815260200180610da46021913960400191505060405180910390fd5b8460400151811061062e576040805162461bcd60e51b815260206004820152601960248201527f4f7665726c617070696e67207369676e616c7320666f756e6400000000000000604482015290519081900360640190fd5b5050825160608401516040850151600190930192015b8460400151811415610697576005805486516001820180845560009384527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0909201558651825260066020526040909120555b6040805160e0810182526001808252602088810151818401908152898501518486019081526080808c01516060870190815267ffffffffffffffff8b169187019190915260a0860189905260c086018890528b51600090815260078552969096208551815460ff191690151517815591519382019390935591516002830155925180519293919261072e9260038501920190610c48565b50608082015160048201805467ffffffffffffffff191667ffffffffffffffff90921691909117905560a0820151600582015560c09091015160069091015550509151600055505050565b60008281526007602052604090206002015483146107c85760405162461bcd60e51b815260040180806020018281038252602f815260200180610dc5602f913960400191505060405180910390fd5b60028054600354600480546040805160206101006001851615026000190190931696909604601f81018390048302870183019091528086529394600094610879948a948a9467ffffffffffffffff9092169392909183018282801561086e5780601f106108435761010080835404028352916020019161086e565b820191906000526020600020905b81548152906001019060200180831161085157829003601f168201915b505050505087610ad1565b600081815260076020526040902060028281558101546001559091505b8282146109d657506000818152600760209081526040808320600181015460069093529220549092908015610958576005546000199182019181018214610924576000600560018303815481106108e957fe5b90600052602060002001549050806005848154811061090457fe5b600091825260208083209091019290925591825260069052604090208290555b600580548061092f57fe5b600082815260208082208301600019908101839055909201909255848252600690526040812055505b8260060154836002015414156109cf57600583015460009081526007602052604090206003805467ffffffffffffffff198116600167ffffffffffffffff928316810190921617825590820180546109c6926004929160026101009282161592909202600019011604610cc6565b505050506109d6565b5050610896565b505050505050565b6109e6610c13565b60008060008060008651602088016040516020810160208101602081016020810160a08588886010600019fa610a1b57600080fd5b84519b5083519a508251995081519850805197505050505050505060608167ffffffffffffffff81118015610a4f57600080fd5b506040519080825280601f01601f191660200182016040528015610a7a576020820181803683370190505b5090508115610aa45787516020890160208301848184846011600019fa610aa057600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b600060608686868686604051602001808681526020018581526020018467ffffffffffffffff1667ffffffffffffffff1681526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015610b44578181015183820152602001610b2c565b50505050905090810190601f168015610b715780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015610ba4578181015183820152602001610b8c565b50505050905090810190601f168015610bd15780820380516001836020036101000a031916815260200191505b50975050505050505050604051602081830303815290604052905080516020820160008083836012600019fa610c0657600080fd5b5095979650505050505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610c8957805160ff1916838001178555610cb6565b82800160010185558215610cb6579182015b82811115610cb6578251825591602001919060010190610c9b565b50610cc2929150610d3b565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610cff5780548555610cb6565b82800160010185558215610cb657600052602060002091601f016020900482015b82811115610cb6578254825591600101919060010190610d20565b610d5591905b80821115610cc25760008155600101610d41565b9056fe547279696e6720746f20696d706f7274206e6f6e2d63616e6f6e6963616c206865616465724d697373696e6720706172656e74206865616465722066726f6d207468652073746f7261676552656163686564206d6178696d616c2076616c696461746f7273207365742069644d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f726167654d697373696e672072657175697265642066696e616c6974792070726f6f6620666f7220706172656e7420686561646572a2646970667358221220d0503056a44ea3cd035299ca78b667561caa71d66f52f3cfbab986a008eb79bc64736f6c63430006060033 \ No newline at end of file +60806040523480156200001157600080fd5b506040516200131938038062001319833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b506040818152602083015192018051929491939192846401000000008211156200010f57600080fd5b9083019060208201858111156200012557600080fd5b82516401000000008111828201881017156200014057600080fd5b82525081516020918201929091019080838360005b838110156200016f57818101518382015260200162000155565b50505050905090810190601f1680156200019d5780820380516001836020036101000a031916815260200191505b50604052505050620001ae620003d5565b620001c2846001600160e01b03620002dc16565b805160008181556002918255604080840180516001908155825160e08101845281815260208088015181830190815293518286019081526080808a0151606085019081526001600160401b038e169185019190915260a0840188905260c084018890528951885260078352959096208251815460ff191690151517815593519284019290925593519482019490945590518051949550919390926200026f9260038501929101906200040a565b506080820151600482810180546001600160401b03199081166001600160401b039485161790915560a0850151600585015560c09094015160069093019290925560038054909316908616179091558251620002d1919060208501906200040a565b5050505050620004af565b620002e6620003d5565b60008060008060008651602088016040516020810160208101602081016020810160a08588886010600019fa6200031c57600080fd5b84519b5083519a50825199508151985080519750505050505050506060816001600160401b03811180156200035057600080fd5b506040519080825280601f01601f1916602001820160405280156200037c576020820181803683370190505b5090508115620003a85787516020890160208301848184846011600019fa620003a457600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200044d57805160ff19168380011785556200047d565b828001600101855582156200047d579182015b828111156200047d57825182559160200191906001019062000460565b506200048b9291506200048f565b5090565b620004ac91905b808211156200048b576000815560010162000496565b90565b610e5a80620004bf6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063374c2c261461005c578063871ebe18146100fd578063d96a2deb1461012e578063e7af07791461014f578063fae71ae8146101f7575b600080fd5b6100646102a9565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156100a8578181015183820152602001610090565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156100e75781810151838201526020016100cf565b5050505090500194505050505060405180910390f35b61011a6004803603602081101561011357600080fd5b50356103ae565b604080519115158252519081900360200190f35b6101366103c3565b6040805192835260208301919091528051918290030190f35b6101f56004803603602081101561016557600080fd5b81019060208101813564010000000081111561018057600080fd5b82018360208201111561019257600080fd5b803590602001918460018302840111640100000000831117156101b457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506103db945050505050565b005b6101f56004803603606081101561020d57600080fd5b81359160208101359181019060608101604082013564010000000081111561023457600080fd5b82018360208201111561024657600080fd5b8035906020019184600183028401116401000000008311171561026857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610779945050505050565b6005546060908190818167ffffffffffffffff811180156102c957600080fd5b506040519080825280602002602001820160405280156102f3578160200160208202803683370190505b50905060005b8281101561034e57600760006005838154811061031257fe5b906000526020600020015481526020019081526020016000206002015482828151811061033b57fe5b60209081029190910101526001016102f9565b508060058080548060200260200160405190810160405280929190818152602001828054801561039d57602002820191906000526020600020905b815481526020019060010190808311610389575b505050505090509350935050509091565b60009081526007602052604090205460ff1690565b60008054808252600760205260409091206002015491565b6103e3610c13565b6103ec826109de565b805160009081526007602052604090205490915060ff1615610455576040805162461bcd60e51b815260206004820152601760248201527f48656164657220697320616c7265616479206b6e6f776e000000000000000000604482015290519081900360640190fd5b6001548160400151116104995760405162461bcd60e51b8152600401808060200182810382526025815260200180610d596025913960400191505060405180910390fd5b6020808201516000908152600790915260409020805460ff1680156104c8575060018260400151038160020154145b6105035760405162461bcd60e51b8152600401808060200182810382526026815260200180610d7e6026913960400191505060405180910390fd5b60068101541580159061051d575080600201548160060154145b15610566578160200151600254146105665760405162461bcd60e51b8152600401808060200182810382526031815260200180610df46031913960400191505060405180910390fd5b60048101546005820154600683015460808501515167ffffffffffffffff90931692156106445767ffffffffffffffff83811614156105d65760405162461bcd60e51b8152600401808060200182810382526021815260200180610da46021913960400191505060405180910390fd5b8460400151811061062e576040805162461bcd60e51b815260206004820152601960248201527f4f7665726c617070696e67207369676e616c7320666f756e6400000000000000604482015290519081900360640190fd5b5050825160608401516040850151600190930192015b8460400151811415610697576005805486516001820180845560009384527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0909201558651825260066020526040909120555b6040805160e0810182526001808252602088810151818401908152898501518486019081526080808c01516060870190815267ffffffffffffffff8b169187019190915260a0860189905260c086018890528b51600090815260078552969096208551815460ff191690151517815591519382019390935591516002830155925180519293919261072e9260038501920190610c48565b50608082015160048201805467ffffffffffffffff191667ffffffffffffffff90921691909117905560a0820151600582015560c09091015160069091015550509151600055505050565b60008281526007602052604090206002015483146107c85760405162461bcd60e51b815260040180806020018281038252602f815260200180610dc5602f913960400191505060405180910390fd5b60028054600354600480546040805160206101006001851615026000190190931696909604601f81018390048302870183019091528086529394600094610879948a948a9467ffffffffffffffff9092169392909183018282801561086e5780601f106108435761010080835404028352916020019161086e565b820191906000526020600020905b81548152906001019060200180831161085157829003601f168201915b505050505087610ad1565b600081815260076020526040902060028281558101546001559091505b8282146109d657506000818152600760209081526040808320600181015460069093529220549092908015610958576005546000199182019181018214610924576000600560018303815481106108e957fe5b90600052602060002001549050806005848154811061090457fe5b600091825260208083209091019290925591825260069052604090208290555b600580548061092f57fe5b600082815260208082208301600019908101839055909201909255848252600690526040812055505b8260060154836002015414156109cf57600583015460009081526007602052604090206003805467ffffffffffffffff198116600167ffffffffffffffff928316810190921617825590820180546109c6926004929160026101009282161592909202600019011604610cc6565b505050506109d6565b5050610896565b505050505050565b6109e6610c13565b60008060008060008651602088016040516020810160208101602081016020810160a08588886010600019fa610a1b57600080fd5b84519b5083519a508251995081519850805197505050505050505060608167ffffffffffffffff81118015610a4f57600080fd5b506040519080825280601f01601f191660200182016040528015610a7a576020820181803683370190505b5090508115610aa45787516020890160208301848184846011600019fa610aa057600080fd5b5050505b6040805160a081018252968752602087019590955293850192909252606084015250608082015292915050565b600060608686868686604051602001808681526020018581526020018467ffffffffffffffff1667ffffffffffffffff1681526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015610b44578181015183820152602001610b2c565b50505050905090810190601f168015610b715780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015610ba4578181015183820152602001610b8c565b50505050905090810190601f168015610bd15780820380516001836020036101000a031916815260200191505b50975050505050505050604051602081830303815290604052905080516020820160008083836012600019fa610c0657600080fd5b5095979650505050505050565b6040518060a0016040528060008019168152602001600080191681526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610c8957805160ff1916838001178555610cb6565b82800160010185558215610cb6579182015b82811115610cb6578251825591602001919060010190610c9b565b50610cc2929150610d3b565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610cff5780548555610cb6565b82800160010185558215610cb657600052602060002091601f016020900482015b82811115610cb6578254825591600101919060010190610d20565b610d5591905b80821115610cc25760008155600101610d41565b9056fe547279696e6720746f20696d706f7274206e6f6e2d63616e6f6e6963616c206865616465724d697373696e6720706172656e74206865616465722066726f6d207468652073746f7261676552656163686564206d6178696d616c2076616c696461746f7273207365742069644d697373696e672066696e616c69747920746172676574206865616465722066726f6d207468652073746f726167654d697373696e672072657175697265642066696e616c6974792070726f6f6620666f7220706172656e7420686561646572a26469706673582212206a13d7fad990f5ff64cfe638f258f1cf2a4c72a3161a28ec200db444a3d61c2e64736f6c63430006060033 \ No newline at end of file diff --git a/relays/ethereum/res/substrate-bridge-metadata.txt b/relays/ethereum/res/substrate-bridge-metadata.txt index 0dc5d853f2..dcf50c5cfa 100644 --- a/relays/ethereum/res/substrate-bridge-metadata.txt +++ b/relays/ethereum/res/substrate-bridge-metadata.txt @@ -1,5 +1,5 @@ -Last Change Date: 2020-04-28 +Last Change Date: 2020-05-01 Solc version: 0.6.6+commit.6c089d02 -Source hash (keccak256): 0xdc46aff04e37129265223e507d17f1407a70cb1ecea3230e1eaa77a17586724d -Source gist: https://gist.github.com/svyatonik/876b388f9507a8de242cb2db9547c4f0 +Source hash (keccak256): 0x36403636ad41082ca6c937c60ab06446cd9ef7036c178fa2f04d7c8286544d39 +Source gist: https://github.com/svyatonik/substrate-bridge-sol/blob/8b54f5f648f8685fecd52b7af1deb277922b0fc3/substrate-bridge.sol Compiler flags used (command to produce the file): `docker run -i ethereum/solc:0.6.6 --optimize --bin - < substrate-bridge.sol` \ No newline at end of file From cb7669849fac67c90f32c279d59ed272eb80914c Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 5 May 2020 17:17:48 +0300 Subject: [PATCH 65/92] Update relays/ethereum/src/ethereum_sync_loop.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tomasz Drwięga --- relays/ethereum/src/ethereum_sync_loop.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index 71ef58ee20..f1288ec0de 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -25,7 +25,7 @@ use futures::future::{ready, FutureExt, Ready}; use std::{collections::HashSet, future::Future, pin::Pin, time::Duration}; use web3::types::H256; -/// Interval (in ms) at which we check new Ethereum headers when we are synced/almost synced. +/// Interval at which we check new Ethereum headers when we are synced/almost synced. const ETHEREUM_TICK_INTERVAL: Duration = Duration::from_millis(10 * 1_000); /// Interval (in ms) at which we check new Substrate blocks. const SUBSTRATE_TICK_INTERVAL: Duration = Duration::from_millis(5 * 1_000); From 9e19787f34c71c250c6a232ba506e4877a87daa0 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 5 May 2020 17:18:01 +0300 Subject: [PATCH 66/92] Update relays/ethereum/src/ethereum_sync_loop.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tomasz Drwięga --- relays/ethereum/src/ethereum_sync_loop.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index f1288ec0de..d9ad5c3656 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -27,7 +27,7 @@ use web3::types::H256; /// Interval at which we check new Ethereum headers when we are synced/almost synced. const ETHEREUM_TICK_INTERVAL: Duration = Duration::from_millis(10 * 1_000); -/// Interval (in ms) at which we check new Substrate blocks. +/// Interval at which we check new Substrate blocks. const SUBSTRATE_TICK_INTERVAL: Duration = Duration::from_millis(5 * 1_000); /// Max number of headers in single submit transaction. const MAX_HEADERS_IN_SINGLE_SUBMIT: usize = 32; From 097313780469070c88d7157d54f2937ab0bd15c4 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 5 May 2020 17:25:55 +0300 Subject: [PATCH 67/92] added docs --- modules/ethereum-contract/builtin/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/ethereum-contract/builtin/src/lib.rs b/modules/ethereum-contract/builtin/src/lib.rs index de48d6ba6f..059c536e53 100644 --- a/modules/ethereum-contract/builtin/src/lib.rs +++ b/modules/ethereum-contract/builtin/src/lib.rs @@ -57,7 +57,8 @@ pub struct ValidatorsSetSignal { pub validators: Vec, } -/// Convert from U256 to BlockNumber. +/// Convert from U256 to BlockNumber. Fails if `U256` value isn't fitting within `BlockNumber` +/// limits (the runtime referenced by this module uses u32 as `BlockNumber`). pub fn to_substrate_block_number(number: U256) -> Result { match number == number.low_u32().into() { true => Ok(number.low_u32()), From 27809da2395e9a16840db1931319cef4fa829ae7 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 5 May 2020 17:26:02 +0300 Subject: [PATCH 68/92] OwnedFutureOutput --- relays/ethereum/src/substrate_sync_loop.rs | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index 1d7bb46caf..1732bbf54e 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -85,22 +85,15 @@ struct SubstrateHeadersSource { client: substrate_client::Client, } +type OwnedFutureOutput = (SubstrateHeadersSource, Result); + impl SourceClient for SubstrateHeadersSource { type Error = substrate_client::Error; - type BestBlockNumberFuture = Pin)>>>; - type HeaderByHashFuture = Pin)>>>; - type HeaderByNumberFuture = Pin)>>>; - type HeaderExtraFuture = Ready<(Self, Result<(SubstrateHeaderId, ()), Self::Error>)>; - type HeaderCompletionFuture = Pin< - Box< - dyn Future< - Output = ( - Self, - Result<(SubstrateHeaderId, Option), Self::Error>, - ), - >, - >, - >; + type BestBlockNumberFuture = Pin>>>; + type HeaderByHashFuture = Pin>>>; + type HeaderByNumberFuture = Pin>>>; + type HeaderExtraFuture = Ready>; + type HeaderCompletionFuture = Pin)>>>>; fn best_block_number(self) -> Self::BestBlockNumberFuture { substrate_client::best_header(self.client) From 0b3789c7484cdf28eaafccb1dbd0ddbaf9818862 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 5 May 2020 17:26:35 +0300 Subject: [PATCH 69/92] more docs fixes --- relays/ethereum/src/sync_loop.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/relays/ethereum/src/sync_loop.rs b/relays/ethereum/src/sync_loop.rs index 44397371c3..968c786121 100644 --- a/relays/ethereum/src/sync_loop.rs +++ b/relays/ethereum/src/sync_loop.rs @@ -35,10 +35,10 @@ use std::{ /// the subscriber will receive every best header (2) reorg won't always lead to sync /// stall and restart is a heavy operation (we forget all in-memory headers). const STALL_SYNC_TIMEOUT: Duration = Duration::from_millis(5 * 60 * 1_000); -/// Delay (in milliseconds) after we have seen update of best source header at target node, +/// Delay after we have seen update of best source header at target node, /// for us to treat sync stalled. ONLY when relay operates in backup mode. const BACKUP_STALL_SYNC_TIMEOUT: Duration = Duration::from_millis(10 * 60 * 1_000); -/// Delay (in milliseconds) after connection-related error happened before we'll try +/// Delay after connection-related error happened before we'll try /// reconnection again. const CONNECTION_ERROR_DELAY: Duration = Duration::from_millis(10 * 1_000); From a187bef83041b430d16e45c2bf38bc0cfdcd11c1 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 5 May 2020 17:28:51 +0300 Subject: [PATCH 70/92] cargo fmt --all --- relays/ethereum/src/substrate_sync_loop.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index 1732bbf54e..93fe9eae87 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -93,7 +93,8 @@ impl SourceClient for SubstrateHeadersSource { type HeaderByHashFuture = Pin>>>; type HeaderByNumberFuture = Pin>>>; type HeaderExtraFuture = Ready>; - type HeaderCompletionFuture = Pin)>>>>; + type HeaderCompletionFuture = + Pin)>>>>; fn best_block_number(self) -> Self::BestBlockNumberFuture { substrate_client::best_header(self.client) From 5913b019e5f4b9afc17b1a4b80110ee2f1b301f1 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 5 May 2020 17:48:58 +0300 Subject: [PATCH 71/92] encode headers --- Cargo.lock | 1 + modules/ethereum-contract/builtin/Cargo.toml | 7 +++- modules/ethereum-contract/builtin/src/lib.rs | 39 +++++++++++++++++--- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index db368e5000..9a2a8ba64d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1071,6 +1071,7 @@ dependencies = [ "parity-scale-codec", "sc-finality-grandpa", "sp-blockchain", + "sp-core", "sp-finality-grandpa", "sp-runtime", ] diff --git a/modules/ethereum-contract/builtin/Cargo.toml b/modules/ethereum-contract/builtin/Cargo.toml index 6963846f13..46be27cea1 100644 --- a/modules/ethereum-contract/builtin/Cargo.toml +++ b/modules/ethereum-contract/builtin/Cargo.toml @@ -37,4 +37,9 @@ rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dev-dependencies] -hex-literal = "0.2" \ No newline at end of file +hex-literal = "0.2" + +[dev-dependencies.sp-core] +version = "2.0.0-alpha.6" +rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" +git = "https://github.com/paritytech/substrate/" diff --git a/modules/ethereum-contract/builtin/src/lib.rs b/modules/ethereum-contract/builtin/src/lib.rs index 059c536e53..f7fdcaf96a 100644 --- a/modules/ethereum-contract/builtin/src/lib.rs +++ b/modules/ethereum-contract/builtin/src/lib.rs @@ -122,7 +122,11 @@ pub fn verify_substrate_finality_proof( #[cfg(test)] mod tests { use super::*; + use bridge_node_runtime::DigestItem; use hex_literal::hex; + use sp_core::crypto::Public; + use sp_finality_grandpa::{AuthorityId, ScheduledChange}; + use sp_runtime::generic::Digest; #[test] fn to_substrate_block_number_succeeds() { @@ -153,7 +157,13 @@ mod tests { #[test] fn substrate_header_without_signal_parsed() { assert_eq!( - parse_substrate_header(&hex!("000000000000000000000000000000000000000000000000000000000000000000b2fc47904df5e355c6ab476d89fbc0733aeddbe302f0b94ba4eea9283f7e89e703170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c11131400")).unwrap(), + parse_substrate_header(&RuntimeHeader { + parent_hash: [0u8; 32].into(), + number: 0, + state_root: "b2fc47904df5e355c6ab476d89fbc0733aeddbe302f0b94ba4eea9283f7e89e7".parse().unwrap(), + extrinsics_root: "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314".parse().unwrap(), + digest: Default::default(), + }.encode()).unwrap(), Header { hash: "afbbeb92bf6ff14f60bdef0aa89f043dd403659ae82665238810ace0d761f6d0".parse().unwrap(), parent_hash: Default::default(), @@ -165,15 +175,34 @@ mod tests { #[test] fn substrate_header_with_signal_parsed() { + let authorities = vec![ + (AuthorityId::from_slice(&[1; 32]), 101), + (AuthorityId::from_slice(&[3; 32]), 103), + ]; + let mut digest = Digest::default(); + digest.push(DigestItem::Consensus( + GRANDPA_ENGINE_ID, + ConsensusLog::ScheduledChange(ScheduledChange { + next_authorities: authorities.clone(), + delay: 8, + }).encode(), + )); + assert_eq!( - parse_substrate_header(&hex!("c0ac300d4005141ea690f3df593e049739c227316eb7f05052f3ee077388b68b20822d6b412033aa9ac8e1722918eec5f25633529225754b3d4149982f5cacd4aae7b07c0ce2799416ce7877b9cefc7f596bea5e8813bb2a0abf760414073ca92810066175726120ae54c70f0000000004617572618901010c90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e0446524e4bf901010c439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f01000000000000005e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d901000000000000001dfe3e22cc0d45c70779c1095f7489a8ef3cf52d62fbd8c2fa38c9f1723502b501000000000000000000000005617572610101acd5bb6f958101f460c5f86a1c45f6a28bc66fa436508e3db597ba76edefa5552c09b76850fd34328fa938b591cc1d59445d713b4ab59c750f5cdccd259d0383")).unwrap(), + parse_substrate_header(&RuntimeHeader { + parent_hash: "c0ac300d4005141ea690f3df593e049739c227316eb7f05052f3ee077388b68b".parse().unwrap(), + number: 8, + state_root: "822d6b412033aa9ac8e1722918eec5f25633529225754b3d4149982f5cacd4aa".parse().unwrap(), + extrinsics_root: "e7b07c0ce2799416ce7877b9cefc7f596bea5e8813bb2a0abf760414073ca928".parse().unwrap(), + digest, + }.encode()).unwrap(), Header { - hash: "4444c880757dc15aa0aa54b26a7738131ffb33a95fc2b7cea1c1f5e933157ebd".parse().unwrap(), + hash: "3dfebb280bd87a4640f89d7f2adecd62b88148747bff5b63af6e1634ee37a56e".parse().unwrap(), parent_hash: "c0ac300d4005141ea690f3df593e049739c227316eb7f05052f3ee077388b68b".parse().unwrap(), number: 8, signal: Some(ValidatorsSetSignal { - delay: 0, - validators: hex!("0c439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f01000000000000005e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d901000000000000001dfe3e22cc0d45c70779c1095f7489a8ef3cf52d62fbd8c2fa38c9f1723502b50100000000000000").to_vec(), + delay: 8, + validators: authorities.encode(), }), }, ); From d055941f4278e70d0b72e6514aeaeb4f28e9f39f Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 5 May 2020 18:03:49 +0300 Subject: [PATCH 72/92] consts + docs --- Cargo.lock | 2 +- modules/ethereum-contract/builtin/Cargo.toml | 2 +- modules/ethereum-contract/builtin/src/lib.rs | 57 ++++++++++++-------- 3 files changed, 37 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9a2a8ba64d..80555c9406 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1067,7 +1067,7 @@ version = "0.1.0" dependencies = [ "bridge-node-runtime", "ethereum-types", - "hex-literal", + "hex", "parity-scale-codec", "sc-finality-grandpa", "sp-blockchain", diff --git a/modules/ethereum-contract/builtin/Cargo.toml b/modules/ethereum-contract/builtin/Cargo.toml index 46be27cea1..7a38e4497f 100644 --- a/modules/ethereum-contract/builtin/Cargo.toml +++ b/modules/ethereum-contract/builtin/Cargo.toml @@ -37,7 +37,7 @@ rev = "c13ad41634d0bd7cf07897c2aa062b917d520520" git = "https://github.com/paritytech/substrate/" [dev-dependencies] -hex-literal = "0.2" +hex = "0.4" [dev-dependencies.sp-core] version = "2.0.0-alpha.6" diff --git a/modules/ethereum-contract/builtin/src/lib.rs b/modules/ethereum-contract/builtin/src/lib.rs index f7fdcaf96a..407f07dbee 100644 --- a/modules/ethereum-contract/builtin/src/lib.rs +++ b/modules/ethereum-contract/builtin/src/lib.rs @@ -123,7 +123,6 @@ pub fn verify_substrate_finality_proof( mod tests { use super::*; use bridge_node_runtime::DigestItem; - use hex_literal::hex; use sp_core::crypto::Public; use sp_finality_grandpa::{AuthorityId, ScheduledChange}; use sp_runtime::generic::Digest; @@ -208,6 +207,20 @@ mod tests { ); } + /// Number of the example block with justification. + const EXAMPLE_JUSTIFIED_BLOCK_NUMBER: u32 = 8; + /// Hash of the example block with justification. + const EXAMPLE_JUSTIFIED_BLOCK_HASH: &'static str = "a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f343775"; + /// Id of authorities set that have generated example justification. Could be computed by tracking + /// every set change in canonized headers. + const EXAMPLE_AUTHORITIES_SET_ID: u64 = 0; + /// Encoded authorities set that has generated example justification. Could be fetched from `ScheduledChange` + /// digest of the block that has scheduled this set OR by calling `GrandpaApi::grandpa_authorities()` at + /// appropriate block. + const EXAMPLE_AUTHORITIES_SET: &'static str = "1488dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee0100000000000000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690100000000000000439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f01000000000000005e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d901000000000000001dfe3e22cc0d45c70779c1095f7489a8ef3cf52d62fbd8c2fa38c9f1723502b50100000000000000"; + /// Example justification. Could be fetched by calling 'chain_getBlock' RPC. + const EXAMPLE_JUSTIFICATION: &'static str = "2600000000000000a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000010a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000d66b4ceb57ef8bcbc955071b597c8c5d2adcfdbb009c73f8438d342670fdeca9ac60686cbd58105b10f51d0a64a8e73b2e5829b2eab3248a008c472852130b00439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234fa2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000f5730c14d3cd22b7661e2f5fcb3139dd5fef37f946314a441d01b40ce1200ef70d810525f23fd278b588cd67473c200bda83c338c407b479386aa83798e5970b5e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d9a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000c78d6ec463f476461a695b4791d30e7626d16fdf72d7c252c2cad387495a97e8c2827ed4d5af853d6e05d31cb6fb7438c9481a7e9c6990d60a9bfaf6a6e1930988dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eea2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000052b4fc52d430286b3e2d650aa6e01b6ff4fae8b968893a62be789209eb97ee6e23780d3f5af7042d85bb48f1b202890b22724dfebce138826f66a5e00324320fd17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae6900"; + #[test] fn substrate_header_parse_fails() { assert!(matches!(parse_substrate_header(&[]), Err(_))); @@ -216,11 +229,11 @@ mod tests { #[test] fn verify_substrate_finality_proof_succeeds() { verify_substrate_finality_proof( - 8, - "a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f343775".parse().unwrap(), - 0, - &hex!("1488dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee0100000000000000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690100000000000000439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f01000000000000005e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d901000000000000001dfe3e22cc0d45c70779c1095f7489a8ef3cf52d62fbd8c2fa38c9f1723502b50100000000000000"), - &hex!("2600000000000000a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000010a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000d66b4ceb57ef8bcbc955071b597c8c5d2adcfdbb009c73f8438d342670fdeca9ac60686cbd58105b10f51d0a64a8e73b2e5829b2eab3248a008c472852130b00439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234fa2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000f5730c14d3cd22b7661e2f5fcb3139dd5fef37f946314a441d01b40ce1200ef70d810525f23fd278b588cd67473c200bda83c338c407b479386aa83798e5970b5e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d9a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000c78d6ec463f476461a695b4791d30e7626d16fdf72d7c252c2cad387495a97e8c2827ed4d5af853d6e05d31cb6fb7438c9481a7e9c6990d60a9bfaf6a6e1930988dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eea2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000052b4fc52d430286b3e2d650aa6e01b6ff4fae8b968893a62be789209eb97ee6e23780d3f5af7042d85bb48f1b202890b22724dfebce138826f66a5e00324320fd17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae6900"), + EXAMPLE_JUSTIFIED_BLOCK_NUMBER, + EXAMPLE_JUSTIFIED_BLOCK_HASH.parse().unwrap(), + EXAMPLE_AUTHORITIES_SET_ID, + &hex::decode(EXAMPLE_AUTHORITIES_SET).unwrap(), + &hex::decode(EXAMPLE_JUSTIFICATION).unwrap(), ).unwrap(); } @@ -229,42 +242,42 @@ mod tests { verify_substrate_finality_proof( 4, Default::default(), - 0, - &hex!("1488dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee0100000000000000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690100000000000000439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f01000000000000005e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d901000000000000001dfe3e22cc0d45c70779c1095f7489a8ef3cf52d62fbd8c2fa38c9f1723502b50100000000000000"), - &hex!("2600000000000000a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000010a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000d66b4ceb57ef8bcbc955071b597c8c5d2adcfdbb009c73f8438d342670fdeca9ac60686cbd58105b10f51d0a64a8e73b2e5829b2eab3248a008c472852130b00439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234fa2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000f5730c14d3cd22b7661e2f5fcb3139dd5fef37f946314a441d01b40ce1200ef70d810525f23fd278b588cd67473c200bda83c338c407b479386aa83798e5970b5e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d9a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000c78d6ec463f476461a695b4791d30e7626d16fdf72d7c252c2cad387495a97e8c2827ed4d5af853d6e05d31cb6fb7438c9481a7e9c6990d60a9bfaf6a6e1930988dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eea2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000052b4fc52d430286b3e2d650aa6e01b6ff4fae8b968893a62be789209eb97ee6e23780d3f5af7042d85bb48f1b202890b22724dfebce138826f66a5e00324320fd17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae6900"), + EXAMPLE_AUTHORITIES_SET_ID, + &hex::decode(EXAMPLE_AUTHORITIES_SET).unwrap(), + &hex::decode(EXAMPLE_JUSTIFICATION).unwrap(), ).unwrap_err(); } #[test] fn verify_substrate_finality_proof_fails_when_wrong_set_is_provided() { verify_substrate_finality_proof( - 8, - "a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f343775".parse().unwrap(), - 0, - &hex!("1488dc3417d5058ec4b4503e0c12ea"), - &hex!("2600000000000000a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000010a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000d66b4ceb57ef8bcbc955071b597c8c5d2adcfdbb009c73f8438d342670fdeca9ac60686cbd58105b10f51d0a64a8e73b2e5829b2eab3248a008c472852130b00439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234fa2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000f5730c14d3cd22b7661e2f5fcb3139dd5fef37f946314a441d01b40ce1200ef70d810525f23fd278b588cd67473c200bda83c338c407b479386aa83798e5970b5e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d9a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000c78d6ec463f476461a695b4791d30e7626d16fdf72d7c252c2cad387495a97e8c2827ed4d5af853d6e05d31cb6fb7438c9481a7e9c6990d60a9bfaf6a6e1930988dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eea2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000052b4fc52d430286b3e2d650aa6e01b6ff4fae8b968893a62be789209eb97ee6e23780d3f5af7042d85bb48f1b202890b22724dfebce138826f66a5e00324320fd17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae6900"), + EXAMPLE_JUSTIFIED_BLOCK_NUMBER, + EXAMPLE_JUSTIFIED_BLOCK_HASH.parse().unwrap(), + EXAMPLE_AUTHORITIES_SET_ID, + &hex::decode("deadbeef").unwrap(), + &hex::decode(EXAMPLE_JUSTIFICATION).unwrap(), ).unwrap_err(); } #[test] fn verify_substrate_finality_proof_fails_when_wrong_set_id_is_provided() { verify_substrate_finality_proof( - 8, - "a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f343775".parse().unwrap(), + EXAMPLE_JUSTIFIED_BLOCK_NUMBER, + EXAMPLE_JUSTIFIED_BLOCK_HASH.parse().unwrap(), 42, - &hex!("1488dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee0100000000000000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690100000000000000439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f01000000000000005e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d901000000000000001dfe3e22cc0d45c70779c1095f7489a8ef3cf52d62fbd8c2fa38c9f1723502b50100000000000000"), - &hex!("2600000000000000a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000010a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000d66b4ceb57ef8bcbc955071b597c8c5d2adcfdbb009c73f8438d342670fdeca9ac60686cbd58105b10f51d0a64a8e73b2e5829b2eab3248a008c472852130b00439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234fa2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000f5730c14d3cd22b7661e2f5fcb3139dd5fef37f946314a441d01b40ce1200ef70d810525f23fd278b588cd67473c200bda83c338c407b479386aa83798e5970b5e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d9a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f34377508000000c78d6ec463f476461a695b4791d30e7626d16fdf72d7c252c2cad387495a97e8c2827ed4d5af853d6e05d31cb6fb7438c9481a7e9c6990d60a9bfaf6a6e1930988dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eea2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f3437750800000052b4fc52d430286b3e2d650aa6e01b6ff4fae8b968893a62be789209eb97ee6e23780d3f5af7042d85bb48f1b202890b22724dfebce138826f66a5e00324320fd17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae6900"), + &hex::decode(EXAMPLE_AUTHORITIES_SET).unwrap(), + &hex::decode(EXAMPLE_JUSTIFICATION).unwrap(), ).unwrap_err(); } #[test] fn verify_substrate_finality_proof_fails_when_wrong_proof_is_provided() { verify_substrate_finality_proof( - 8, - "a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f343775".parse().unwrap(), + EXAMPLE_JUSTIFIED_BLOCK_NUMBER, + EXAMPLE_JUSTIFIED_BLOCK_HASH.parse().unwrap(), 0, - &hex!("1488dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee0100000000000000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690100000000000000439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f01000000000000005e639b43e0052c47447dac87d6fd2b6ec50bdd4d0f614e4299c665249bbd09d901000000000000001dfe3e22cc0d45c70779c1095f7489a8ef3cf52d62fbd8c2fa38c9f1723502b50100000000000000"), - &hex!("2600000000000000a2f45892"), + &hex::decode(EXAMPLE_AUTHORITIES_SET).unwrap(), + &hex::decode("deadbeef").unwrap(), ).unwrap_err(); } } From 6d5a37cc136acc9d421b7a4851b05fc5585b5118 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 5 May 2020 18:32:54 +0300 Subject: [PATCH 73/92] aliases again --- relays/ethereum/src/ethereum_sync_loop.rs | 28 +++++++++++--------- relays/ethereum/src/substrate_sync_loop.rs | 28 ++++++++++---------- relays/ethereum/src/sync_loop.rs | 30 ++++++++++++---------- 3 files changed, 47 insertions(+), 39 deletions(-) diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index d9ad5c3656..3f6acc0191 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -20,7 +20,7 @@ use crate::ethereum_client::{self, EthereumConnectionParams}; use crate::ethereum_types::{EthereumHeaderId, EthereumHeadersSyncPipeline, Header, QueuedEthereumHeader, Receipt}; use crate::substrate_client::{self, SubstrateConnectionParams, SubstrateSigningParams}; use crate::sync::{HeadersSyncParams, TargetTransactionMode}; -use crate::sync_loop::{SourceClient, TargetClient}; +use crate::sync_loop::{SourceClient, OwnedSourceFutureOutput, OwnedTargetFutureOutput, TargetClient}; use futures::future::{ready, FutureExt, Ready}; use std::{collections::HashSet, future::Future, pin::Pin, time::Duration}; use web3::types::H256; @@ -78,14 +78,16 @@ struct EthereumHeadersSource { client: ethereum_client::Client, } +type EthereumFutureOutput = OwnedSourceFutureOutput; + impl SourceClient for EthereumHeadersSource { type Error = ethereum_client::Error; - type BestBlockNumberFuture = Pin)>>>; - type HeaderByHashFuture = Pin)>>>; - type HeaderByNumberFuture = Pin)>>>; + type BestBlockNumberFuture = Pin>>>; + type HeaderByHashFuture = Pin>>>; + type HeaderByNumberFuture = Pin>>>; type HeaderExtraFuture = - Pin), Self::Error>)>>>; - type HeaderCompletionFuture = Ready<(Self, Result<(EthereumHeaderId, Option<()>), Self::Error>)>; + Pin)>>>>; + type HeaderCompletionFuture = Ready)>>; fn best_block_number(self) -> Self::BestBlockNumberFuture { ethereum_client::best_block_number(self.client) @@ -126,14 +128,16 @@ struct SubstrateHeadersTarget { sign_params: SubstrateSigningParams, } +type SubstrateFutureOutput = OwnedTargetFutureOutput; + impl TargetClient for SubstrateHeadersTarget { type Error = substrate_client::Error; - type BestHeaderIdFuture = Pin)>>>; - type IsKnownHeaderFuture = Pin)>>>; - type RequiresExtraFuture = Pin)>>>; - type SubmitHeadersFuture = Pin, Self::Error>)>>>; - type IncompleteHeadersFuture = Ready<(Self, Result, Self::Error>)>; - type CompleteHeadersFuture = Ready<(Self, Result)>; + type BestHeaderIdFuture = Pin>>>; + type IsKnownHeaderFuture = Pin>>>; + type RequiresExtraFuture = Pin>>>; + type SubmitHeadersFuture = Pin>>>>; + type IncompleteHeadersFuture = Ready>>; + type CompleteHeadersFuture = Ready>; fn best_header_id(self) -> Self::BestHeaderIdFuture { let (sign_transactions, sign_params) = (self.sign_transactions, self.sign_params); diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index 93fe9eae87..eea0230795 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -23,7 +23,7 @@ use crate::substrate_types::{ GrandpaJustification, Hash, Header, Number, QueuedSubstrateHeader, SubstrateHeaderId, SubstrateHeadersSyncPipeline, }; use crate::sync::{HeadersSyncParams, TargetTransactionMode}; -use crate::sync_loop::{SourceClient, TargetClient}; +use crate::sync_loop::{SourceClient, OwnedSourceFutureOutput, OwnedTargetFutureOutput, TargetClient}; use crate::sync_types::SourceHeader; use futures::future::{ready, FutureExt, Ready}; use std::{collections::HashSet, future::Future, pin::Pin, time::Duration}; @@ -85,16 +85,16 @@ struct SubstrateHeadersSource { client: substrate_client::Client, } -type OwnedFutureOutput = (SubstrateHeadersSource, Result); +type SubstrateFutureOutput = OwnedSourceFutureOutput; impl SourceClient for SubstrateHeadersSource { type Error = substrate_client::Error; - type BestBlockNumberFuture = Pin>>>; - type HeaderByHashFuture = Pin>>>; - type HeaderByNumberFuture = Pin>>>; - type HeaderExtraFuture = Ready>; + type BestBlockNumberFuture = Pin>>>; + type HeaderByHashFuture = Pin>>>; + type HeaderByNumberFuture = Pin>>>; + type HeaderExtraFuture = Ready>; type HeaderCompletionFuture = - Pin)>>>>; + Pin)>>>>; fn best_block_number(self) -> Self::BestBlockNumberFuture { substrate_client::best_header(self.client) @@ -135,15 +135,17 @@ struct EthereumHeadersTarget { sign_params: EthereumSigningParams, } +type EthereumFutureOutput = OwnedTargetFutureOutput; + impl TargetClient for EthereumHeadersTarget { type Error = ethereum_client::Error; - type BestHeaderIdFuture = Pin)>>>; - type IsKnownHeaderFuture = Pin)>>>; - type RequiresExtraFuture = Ready<(Self, Result<(SubstrateHeaderId, bool), Self::Error>)>; - type SubmitHeadersFuture = Pin, Self::Error>)>>>; + type BestHeaderIdFuture = Pin>>>; + type IsKnownHeaderFuture = Pin>>>; + type RequiresExtraFuture = Ready>; + type SubmitHeadersFuture = Pin>>>>; type IncompleteHeadersFuture = - Pin, Self::Error>)>>>; - type CompleteHeadersFuture = Pin)>>>; + Pin>>>>; + type CompleteHeadersFuture = Pin>>>; fn best_header_id(self) -> Self::BestHeaderIdFuture { let (contract, sign_params) = (self.contract, self.sign_params); diff --git a/relays/ethereum/src/sync_loop.rs b/relays/ethereum/src/sync_loop.rs index 968c786121..63b58c3a18 100644 --- a/relays/ethereum/src/sync_loop.rs +++ b/relays/ethereum/src/sync_loop.rs @@ -42,24 +42,26 @@ const BACKUP_STALL_SYNC_TIMEOUT: Duration = Duration::from_millis(10 * 60 * 1_00 /// reconnection again. const CONNECTION_ERROR_DELAY: Duration = Duration::from_millis(10 * 1_000); +/// Type alias for all SourceClient futures. +pub type OwnedSourceFutureOutput = (Client, Result>::Error>); +/// Type alias for all TargetClient futures. +pub type OwnedTargetFutureOutput = (Client, Result>::Error>); + /// Source client trait. pub trait SourceClient: Sized { /// Type of error this clients returns. type Error: std::fmt::Debug + MaybeConnectionError; /// Future that returns best block number. - type BestBlockNumberFuture: Future)>; + type BestBlockNumberFuture: Future>; /// Future that returns header by hash. - type HeaderByHashFuture: Future)>; + type HeaderByHashFuture: Future>; /// Future that returns header by number. - type HeaderByNumberFuture: Future)>; + type HeaderByNumberFuture: Future>; /// Future that returns extra data associated with header. - type HeaderExtraFuture: Future, P::Extra), Self::Error>)>; + type HeaderExtraFuture: Future, P::Extra)>>; /// Future that returns data required to 'complete' header. type HeaderCompletionFuture: Future< - Output = ( - Self, - Result<(HeaderId, Option), Self::Error>, - ), + Output = OwnedSourceFutureOutput, Option)> >; /// Get best block number. @@ -79,17 +81,17 @@ pub trait TargetClient: Sized { /// Type of error this clients returns. type Error: std::fmt::Debug + MaybeConnectionError; /// Future that returns best header id. - type BestHeaderIdFuture: Future, Self::Error>)>; + type BestHeaderIdFuture: Future>>; /// Future that returns known header check result. - type IsKnownHeaderFuture: Future, bool), Self::Error>)>; + type IsKnownHeaderFuture: Future, bool)>>; /// Future that returns extra check result. - type RequiresExtraFuture: Future, bool), Self::Error>)>; + type RequiresExtraFuture: Future, bool)>>; /// Future that returns header submission result. - type SubmitHeadersFuture: Future>, Self::Error>)>; + type SubmitHeadersFuture: Future>>>; /// Future that returns incomplete headers ids. - type IncompleteHeadersFuture: Future>, Self::Error>)>; + type IncompleteHeadersFuture: Future>>>; /// Future that returns header completion result. - type CompleteHeadersFuture: Future, Self::Error>)>; + type CompleteHeadersFuture: Future>>; /// Returns ID of best header known to the target node. fn best_header_id(self) -> Self::BestHeaderIdFuture; From 585cd332ab1664e470a85c4fa87b982efc8eaa09 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 5 May 2020 18:33:10 +0300 Subject: [PATCH 74/92] cargo fmt --all --- modules/ethereum-contract/builtin/src/lib.rs | 79 ++++++++++++++------ relays/ethereum/src/ethereum_sync_loop.rs | 5 +- relays/ethereum/src/substrate_sync_loop.rs | 5 +- relays/ethereum/src/sync_loop.rs | 6 +- 4 files changed, 63 insertions(+), 32 deletions(-) diff --git a/modules/ethereum-contract/builtin/src/lib.rs b/modules/ethereum-contract/builtin/src/lib.rs index 407f07dbee..1bb69c81df 100644 --- a/modules/ethereum-contract/builtin/src/lib.rs +++ b/modules/ethereum-contract/builtin/src/lib.rs @@ -156,15 +156,25 @@ mod tests { #[test] fn substrate_header_without_signal_parsed() { assert_eq!( - parse_substrate_header(&RuntimeHeader { - parent_hash: [0u8; 32].into(), - number: 0, - state_root: "b2fc47904df5e355c6ab476d89fbc0733aeddbe302f0b94ba4eea9283f7e89e7".parse().unwrap(), - extrinsics_root: "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314".parse().unwrap(), - digest: Default::default(), - }.encode()).unwrap(), + parse_substrate_header( + &RuntimeHeader { + parent_hash: [0u8; 32].into(), + number: 0, + state_root: "b2fc47904df5e355c6ab476d89fbc0733aeddbe302f0b94ba4eea9283f7e89e7" + .parse() + .unwrap(), + extrinsics_root: "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314" + .parse() + .unwrap(), + digest: Default::default(), + } + .encode() + ) + .unwrap(), Header { - hash: "afbbeb92bf6ff14f60bdef0aa89f043dd403659ae82665238810ace0d761f6d0".parse().unwrap(), + hash: "afbbeb92bf6ff14f60bdef0aa89f043dd403659ae82665238810ace0d761f6d0" + .parse() + .unwrap(), parent_hash: Default::default(), number: 0, signal: None, @@ -184,20 +194,35 @@ mod tests { ConsensusLog::ScheduledChange(ScheduledChange { next_authorities: authorities.clone(), delay: 8, - }).encode(), + }) + .encode(), )); assert_eq!( - parse_substrate_header(&RuntimeHeader { - parent_hash: "c0ac300d4005141ea690f3df593e049739c227316eb7f05052f3ee077388b68b".parse().unwrap(), - number: 8, - state_root: "822d6b412033aa9ac8e1722918eec5f25633529225754b3d4149982f5cacd4aa".parse().unwrap(), - extrinsics_root: "e7b07c0ce2799416ce7877b9cefc7f596bea5e8813bb2a0abf760414073ca928".parse().unwrap(), - digest, - }.encode()).unwrap(), + parse_substrate_header( + &RuntimeHeader { + parent_hash: "c0ac300d4005141ea690f3df593e049739c227316eb7f05052f3ee077388b68b" + .parse() + .unwrap(), + number: 8, + state_root: "822d6b412033aa9ac8e1722918eec5f25633529225754b3d4149982f5cacd4aa" + .parse() + .unwrap(), + extrinsics_root: "e7b07c0ce2799416ce7877b9cefc7f596bea5e8813bb2a0abf760414073ca928" + .parse() + .unwrap(), + digest, + } + .encode() + ) + .unwrap(), Header { - hash: "3dfebb280bd87a4640f89d7f2adecd62b88148747bff5b63af6e1634ee37a56e".parse().unwrap(), - parent_hash: "c0ac300d4005141ea690f3df593e049739c227316eb7f05052f3ee077388b68b".parse().unwrap(), + hash: "3dfebb280bd87a4640f89d7f2adecd62b88148747bff5b63af6e1634ee37a56e" + .parse() + .unwrap(), + parent_hash: "c0ac300d4005141ea690f3df593e049739c227316eb7f05052f3ee077388b68b" + .parse() + .unwrap(), number: 8, signal: Some(ValidatorsSetSignal { delay: 8, @@ -210,7 +235,8 @@ mod tests { /// Number of the example block with justification. const EXAMPLE_JUSTIFIED_BLOCK_NUMBER: u32 = 8; /// Hash of the example block with justification. - const EXAMPLE_JUSTIFIED_BLOCK_HASH: &'static str = "a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f343775"; + const EXAMPLE_JUSTIFIED_BLOCK_HASH: &'static str = + "a2f45892db86b2ad133ce57d81b7e4375bb7035ce9883e6b68c358164f343775"; /// Id of authorities set that have generated example justification. Could be computed by tracking /// every set change in canonized headers. const EXAMPLE_AUTHORITIES_SET_ID: u64 = 0; @@ -234,7 +260,8 @@ mod tests { EXAMPLE_AUTHORITIES_SET_ID, &hex::decode(EXAMPLE_AUTHORITIES_SET).unwrap(), &hex::decode(EXAMPLE_JUSTIFICATION).unwrap(), - ).unwrap(); + ) + .unwrap(); } #[test] @@ -245,7 +272,8 @@ mod tests { EXAMPLE_AUTHORITIES_SET_ID, &hex::decode(EXAMPLE_AUTHORITIES_SET).unwrap(), &hex::decode(EXAMPLE_JUSTIFICATION).unwrap(), - ).unwrap_err(); + ) + .unwrap_err(); } #[test] @@ -256,7 +284,8 @@ mod tests { EXAMPLE_AUTHORITIES_SET_ID, &hex::decode("deadbeef").unwrap(), &hex::decode(EXAMPLE_JUSTIFICATION).unwrap(), - ).unwrap_err(); + ) + .unwrap_err(); } #[test] @@ -267,7 +296,8 @@ mod tests { 42, &hex::decode(EXAMPLE_AUTHORITIES_SET).unwrap(), &hex::decode(EXAMPLE_JUSTIFICATION).unwrap(), - ).unwrap_err(); + ) + .unwrap_err(); } #[test] @@ -278,6 +308,7 @@ mod tests { 0, &hex::decode(EXAMPLE_AUTHORITIES_SET).unwrap(), &hex::decode("deadbeef").unwrap(), - ).unwrap_err(); + ) + .unwrap_err(); } } diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index 3f6acc0191..cf7e2dec24 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -20,7 +20,7 @@ use crate::ethereum_client::{self, EthereumConnectionParams}; use crate::ethereum_types::{EthereumHeaderId, EthereumHeadersSyncPipeline, Header, QueuedEthereumHeader, Receipt}; use crate::substrate_client::{self, SubstrateConnectionParams, SubstrateSigningParams}; use crate::sync::{HeadersSyncParams, TargetTransactionMode}; -use crate::sync_loop::{SourceClient, OwnedSourceFutureOutput, OwnedTargetFutureOutput, TargetClient}; +use crate::sync_loop::{OwnedSourceFutureOutput, OwnedTargetFutureOutput, SourceClient, TargetClient}; use futures::future::{ready, FutureExt, Ready}; use std::{collections::HashSet, future::Future, pin::Pin, time::Duration}; use web3::types::H256; @@ -85,8 +85,7 @@ impl SourceClient for EthereumHeadersSource { type BestBlockNumberFuture = Pin>>>; type HeaderByHashFuture = Pin>>>; type HeaderByNumberFuture = Pin>>>; - type HeaderExtraFuture = - Pin)>>>>; + type HeaderExtraFuture = Pin)>>>>; type HeaderCompletionFuture = Ready)>>; fn best_block_number(self) -> Self::BestBlockNumberFuture { diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index eea0230795..55bd61cc7c 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -23,7 +23,7 @@ use crate::substrate_types::{ GrandpaJustification, Hash, Header, Number, QueuedSubstrateHeader, SubstrateHeaderId, SubstrateHeadersSyncPipeline, }; use crate::sync::{HeadersSyncParams, TargetTransactionMode}; -use crate::sync_loop::{SourceClient, OwnedSourceFutureOutput, OwnedTargetFutureOutput, TargetClient}; +use crate::sync_loop::{OwnedSourceFutureOutput, OwnedTargetFutureOutput, SourceClient, TargetClient}; use crate::sync_types::SourceHeader; use futures::future::{ready, FutureExt, Ready}; use std::{collections::HashSet, future::Future, pin::Pin, time::Duration}; @@ -143,8 +143,7 @@ impl TargetClient for EthereumHeadersTarget { type IsKnownHeaderFuture = Pin>>>; type RequiresExtraFuture = Ready>; type SubmitHeadersFuture = Pin>>>>; - type IncompleteHeadersFuture = - Pin>>>>; + type IncompleteHeadersFuture = Pin>>>>; type CompleteHeadersFuture = Pin>>>; fn best_header_id(self) -> Self::BestHeaderIdFuture { diff --git a/relays/ethereum/src/sync_loop.rs b/relays/ethereum/src/sync_loop.rs index 63b58c3a18..ebf97d46a0 100644 --- a/relays/ethereum/src/sync_loop.rs +++ b/relays/ethereum/src/sync_loop.rs @@ -61,7 +61,7 @@ pub trait SourceClient: Sized { type HeaderExtraFuture: Future, P::Extra)>>; /// Future that returns data required to 'complete' header. type HeaderCompletionFuture: Future< - Output = OwnedSourceFutureOutput, Option)> + Output = OwnedSourceFutureOutput, Option)>, >; /// Get best block number. @@ -89,7 +89,9 @@ pub trait TargetClient: Sized { /// Future that returns header submission result. type SubmitHeadersFuture: Future>>>; /// Future that returns incomplete headers ids. - type IncompleteHeadersFuture: Future>>>; + type IncompleteHeadersFuture: Future< + Output = OwnedTargetFutureOutput>>, + >; /// Future that returns header completion result. type CompleteHeadersFuture: Future>>; From 06c0fdf541530696ca4f4e47d5cd426ad4724ef6 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Wed, 6 May 2020 00:09:41 -0400 Subject: [PATCH 75/92] Update relays/ethereum/src/ethereum_sync_loop.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tomasz Drwięga --- relays/ethereum/src/ethereum_sync_loop.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index cf7e2dec24..729e7826dc 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -26,7 +26,7 @@ use std::{collections::HashSet, future::Future, pin::Pin, time::Duration}; use web3::types::H256; /// Interval at which we check new Ethereum headers when we are synced/almost synced. -const ETHEREUM_TICK_INTERVAL: Duration = Duration::from_millis(10 * 1_000); +const ETHEREUM_TICK_INTERVAL: Duration = Duration::from_secs(10); /// Interval at which we check new Substrate blocks. const SUBSTRATE_TICK_INTERVAL: Duration = Duration::from_millis(5 * 1_000); /// Max number of headers in single submit transaction. From acdf98057c360c46a8074f700500f842cf272448 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Wed, 6 May 2020 00:09:56 -0400 Subject: [PATCH 76/92] Update relays/ethereum/src/ethereum_sync_loop.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tomasz Drwięga --- relays/ethereum/src/ethereum_sync_loop.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/ethereum_sync_loop.rs b/relays/ethereum/src/ethereum_sync_loop.rs index 729e7826dc..c9e8a987f0 100644 --- a/relays/ethereum/src/ethereum_sync_loop.rs +++ b/relays/ethereum/src/ethereum_sync_loop.rs @@ -28,7 +28,7 @@ use web3::types::H256; /// Interval at which we check new Ethereum headers when we are synced/almost synced. const ETHEREUM_TICK_INTERVAL: Duration = Duration::from_secs(10); /// Interval at which we check new Substrate blocks. -const SUBSTRATE_TICK_INTERVAL: Duration = Duration::from_millis(5 * 1_000); +const SUBSTRATE_TICK_INTERVAL: Duration = Duration::from_secs(5); /// Max number of headers in single submit transaction. const MAX_HEADERS_IN_SINGLE_SUBMIT: usize = 32; /// Max total size of headers in single submit transaction. This only affects signed From bd04d7f5c3f9c6d31fa214762b9cd2a70a78a7f0 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Wed, 6 May 2020 00:43:49 -0400 Subject: [PATCH 77/92] Use Duration::from_secs() instead of from_millis() --- relays/ethereum/src/substrate_sync_loop.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/relays/ethereum/src/substrate_sync_loop.rs b/relays/ethereum/src/substrate_sync_loop.rs index 55bd61cc7c..88dc4b6276 100644 --- a/relays/ethereum/src/substrate_sync_loop.rs +++ b/relays/ethereum/src/substrate_sync_loop.rs @@ -28,10 +28,10 @@ use crate::sync_types::SourceHeader; use futures::future::{ready, FutureExt, Ready}; use std::{collections::HashSet, future::Future, pin::Pin, time::Duration}; -/// Interval (in ms) at which we check new Substrate headers when we are synced/almost synced. -const SUBSTRATE_TICK_INTERVAL: Duration = Duration::from_millis(10 * 1_000); -/// Interval (in ms) at which we check new Ethereum blocks. -const ETHEREUM_TICK_INTERVAL: Duration = Duration::from_millis(5 * 1_000); +/// Interval at which we check new Substrate headers when we are synced/almost synced. +const SUBSTRATE_TICK_INTERVAL: Duration = Duration::from_secs(10); +/// Interval at which we check new Ethereum blocks. +const ETHEREUM_TICK_INTERVAL: Duration = Duration::from_secs(5); /// Max Ethereum headers we want to have in all 'before-submitted' states. const MAX_FUTURE_HEADERS_TO_DOWNLOAD: usize = 8; /// Max Ethereum headers count we want to have in 'submitted' state. From d9bae159e63136c00494e2a0e07d7f46c9468bf0 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 6 May 2020 09:35:03 +0300 Subject: [PATCH 78/92] grumbles --- relays/ethereum/src/headers.rs | 2 +- relays/ethereum/src/sync_loop.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index 86ea0219f8..c6c3e8e983 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -28,7 +28,7 @@ type KnownHeaders

= BTreeMap<

::Number, HashMap<

::Hash, HeaderStatus>>; /// We're trying to fetch completion data for single header at this interval. -const RETRY_FETCH_COMPLETION_INTERVAL: Duration = Duration::from_millis(20 * 1_000); +const RETRY_FETCH_COMPLETION_INTERVAL: Duration = Duration::from_secs(20); /// Ethereum headers queue. #[derive(Debug)] diff --git a/relays/ethereum/src/sync_loop.rs b/relays/ethereum/src/sync_loop.rs index ebf97d46a0..9d1576f821 100644 --- a/relays/ethereum/src/sync_loop.rs +++ b/relays/ethereum/src/sync_loop.rs @@ -34,13 +34,13 @@ use std::{ /// direct child of previous best header. But: (1) subscription doesn't guarantee that /// the subscriber will receive every best header (2) reorg won't always lead to sync /// stall and restart is a heavy operation (we forget all in-memory headers). -const STALL_SYNC_TIMEOUT: Duration = Duration::from_millis(5 * 60 * 1_000); +const STALL_SYNC_TIMEOUT: Duration = Duration::from_secs(5 * 60); /// Delay after we have seen update of best source header at target node, /// for us to treat sync stalled. ONLY when relay operates in backup mode. -const BACKUP_STALL_SYNC_TIMEOUT: Duration = Duration::from_millis(10 * 60 * 1_000); +const BACKUP_STALL_SYNC_TIMEOUT: Duration = Duration::from_secs(10 * 60); /// Delay after connection-related error happened before we'll try /// reconnection again. -const CONNECTION_ERROR_DELAY: Duration = Duration::from_millis(10 * 1_000); +const CONNECTION_ERROR_DELAY: Duration = Duration::from_secs(10); /// Type alias for all SourceClient futures. pub type OwnedSourceFutureOutput = (Client, Result>::Error>); From 085ff2f2a338fc215f8cddc030d617820af43b69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 6 May 2020 12:55:58 +0200 Subject: [PATCH 79/92] Update relays/ethereum/src/headers.rs Co-authored-by: Hernando Castano --- relays/ethereum/src/headers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index c6c3e8e983..0d7808c2bd 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -331,7 +331,7 @@ impl QueuedHeaders

{ None => return, // we'll try refetch later }; - if let Some(_) = self.incomplete_headers.remove(id) { + if self.incomplete_headers.remove(id).is_some() { log::debug!( target: "bridge", "Received completion data from {} for header: {:?}", From a5a060c2fa258dabb8c70a6bad0bdb7fb0c367b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 6 May 2020 12:56:51 +0200 Subject: [PATCH 80/92] Update relays/ethereum/src/headers.rs Co-authored-by: Hernando Castano --- relays/ethereum/src/headers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index 0d7808c2bd..2844afd1d6 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -359,7 +359,7 @@ impl QueuedHeaders

{ /// When header completion data is sent to target node. pub fn header_completed(&mut self, id: &HeaderId) { - if let Some(_) = self.completion_data.remove(id) { + if self.completion_data.remove(id).is_some() { log::debug!( target: "bridge", "Sent completion data to {} for header: {:?}", From a074d0e094591675d2316126b7889cac015861a9 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 6 May 2020 17:40:18 +0300 Subject: [PATCH 81/92] incomplete_headers_are_still_incomplete_after_advance --- relays/ethereum/src/headers.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index c6c3e8e983..654143c0bc 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -1456,4 +1456,31 @@ pub(crate) mod tests { queue.header_response(header(110).header().clone()); assert_eq!(queue.known_headers.len(), 1); } + + #[test] + fn incomplete_headers_are_still_incomplete_after_advance() { + let mut queue = QueuedHeaders::::new(); + + // relay#1 knows that header#100 is incomplete && it has headers 101..104 in inomplete queue + queue.incomplete_headers.insert(id(100), None); + queue.incomplete.entry(101).or_default().insert(hash(101), header(101)); + queue.incomplete.entry(102).or_default().insert(hash(102), header(102)); + queue.incomplete.entry(103).or_default().insert(hash(103), header(103)); + queue.incomplete.entry(104).or_default().insert(hash(104), header(104)); + queue.known_headers.entry(100).or_default().insert(hash(100), HeaderStatus::Synced); + queue.known_headers.entry(101).or_default().insert(hash(101), HeaderStatus::Incomplete); + queue.known_headers.entry(102).or_default().insert(hash(102), HeaderStatus::Incomplete); + queue.known_headers.entry(103).or_default().insert(hash(103), HeaderStatus::Incomplete); + queue.known_headers.entry(104).or_default().insert(hash(104), HeaderStatus::Incomplete); + + // let's say relay#2 completes header#100 and then submits header#101+header#102 and it turns + // that header#102 is also incomplete + queue.incomplete_headers_response(vec![id(102)].into_iter().collect()); + + // then the header#103 and the header#104 must have Incomplete status + assert_eq!(queue.status(&id(101)), HeaderStatus::Synced); + assert_eq!(queue.status(&id(102)), HeaderStatus::Synced); + assert_eq!(queue.status(&id(103)), HeaderStatus::Incomplete); + assert_eq!(queue.status(&id(104)), HeaderStatus::Incomplete); + } } From b80972d53aaf80e05f3d52abbd375f2ad9d7bd73 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 6 May 2020 17:46:54 +0300 Subject: [PATCH 82/92] add hex-encoded headers to substrate_header_without_signal_parsed --- modules/ethereum-contract/builtin/src/lib.rs | 70 +++++++++++--------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/modules/ethereum-contract/builtin/src/lib.rs b/modules/ethereum-contract/builtin/src/lib.rs index 1bb69c81df..1f92557ba9 100644 --- a/modules/ethereum-contract/builtin/src/lib.rs +++ b/modules/ethereum-contract/builtin/src/lib.rs @@ -155,22 +155,25 @@ mod tests { #[test] fn substrate_header_without_signal_parsed() { + let raw_header = RuntimeHeader { + parent_hash: [0u8; 32].into(), + number: 0, + state_root: "b2fc47904df5e355c6ab476d89fbc0733aeddbe302f0b94ba4eea9283f7e89e7" + .parse() + .unwrap(), + extrinsics_root: "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314" + .parse() + .unwrap(), + digest: Default::default(), + } + .encode(); assert_eq!( - parse_substrate_header( - &RuntimeHeader { - parent_hash: [0u8; 32].into(), - number: 0, - state_root: "b2fc47904df5e355c6ab476d89fbc0733aeddbe302f0b94ba4eea9283f7e89e7" - .parse() - .unwrap(), - extrinsics_root: "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314" - .parse() - .unwrap(), - digest: Default::default(), - } - .encode() - ) - .unwrap(), + raw_header, + hex::decode("000000000000000000000000000000000000000000000000000000000000000000b2fc47904df5e355c6ab476d89fbc0733aeddbe302f0b94ba4eea9283f7e89e703170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c11131400").unwrap(), + ); + + assert_eq!( + parse_substrate_header(&raw_header).unwrap(), Header { hash: "afbbeb92bf6ff14f60bdef0aa89f043dd403659ae82665238810ace0d761f6d0" .parse() @@ -198,24 +201,27 @@ mod tests { .encode(), )); + let raw_header = RuntimeHeader { + parent_hash: "c0ac300d4005141ea690f3df593e049739c227316eb7f05052f3ee077388b68b" + .parse() + .unwrap(), + number: 8, + state_root: "822d6b412033aa9ac8e1722918eec5f25633529225754b3d4149982f5cacd4aa" + .parse() + .unwrap(), + extrinsics_root: "e7b07c0ce2799416ce7877b9cefc7f596bea5e8813bb2a0abf760414073ca928" + .parse() + .unwrap(), + digest, + } + .encode(); + assert_eq!( + raw_header, + hex::decode("c0ac300d4005141ea690f3df593e049739c227316eb7f05052f3ee077388b68b20822d6b412033aa9ac8e1722918eec5f25633529225754b3d4149982f5cacd4aae7b07c0ce2799416ce7877b9cefc7f596bea5e8813bb2a0abf760414073ca928040446524e4b59010108010101010101010101010101010101010101010101010101010101010101010165000000000000000303030303030303030303030303030303030303030303030303030303030303670000000000000008000000").unwrap(), + ); + assert_eq!( - parse_substrate_header( - &RuntimeHeader { - parent_hash: "c0ac300d4005141ea690f3df593e049739c227316eb7f05052f3ee077388b68b" - .parse() - .unwrap(), - number: 8, - state_root: "822d6b412033aa9ac8e1722918eec5f25633529225754b3d4149982f5cacd4aa" - .parse() - .unwrap(), - extrinsics_root: "e7b07c0ce2799416ce7877b9cefc7f596bea5e8813bb2a0abf760414073ca928" - .parse() - .unwrap(), - digest, - } - .encode() - ) - .unwrap(), + parse_substrate_header(&raw_header).unwrap(), Header { hash: "3dfebb280bd87a4640f89d7f2adecd62b88148747bff5b63af6e1634ee37a56e" .parse() From 79c8345b27b187fa4d173e64b5992cb142dcd927 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 6 May 2020 17:51:17 +0300 Subject: [PATCH 83/92] cargo fmt --all --- modules/ethereum-contract/builtin/src/lib.rs | 2 +- relays/ethereum/src/headers.rs | 30 ++++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/modules/ethereum-contract/builtin/src/lib.rs b/modules/ethereum-contract/builtin/src/lib.rs index 1f92557ba9..739e14d69e 100644 --- a/modules/ethereum-contract/builtin/src/lib.rs +++ b/modules/ethereum-contract/builtin/src/lib.rs @@ -171,7 +171,7 @@ mod tests { raw_header, hex::decode("000000000000000000000000000000000000000000000000000000000000000000b2fc47904df5e355c6ab476d89fbc0733aeddbe302f0b94ba4eea9283f7e89e703170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c11131400").unwrap(), ); - + assert_eq!( parse_substrate_header(&raw_header).unwrap(), Header { diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index 73f8dc6727..52621d9b80 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -1467,11 +1467,31 @@ pub(crate) mod tests { queue.incomplete.entry(102).or_default().insert(hash(102), header(102)); queue.incomplete.entry(103).or_default().insert(hash(103), header(103)); queue.incomplete.entry(104).or_default().insert(hash(104), header(104)); - queue.known_headers.entry(100).or_default().insert(hash(100), HeaderStatus::Synced); - queue.known_headers.entry(101).or_default().insert(hash(101), HeaderStatus::Incomplete); - queue.known_headers.entry(102).or_default().insert(hash(102), HeaderStatus::Incomplete); - queue.known_headers.entry(103).or_default().insert(hash(103), HeaderStatus::Incomplete); - queue.known_headers.entry(104).or_default().insert(hash(104), HeaderStatus::Incomplete); + queue + .known_headers + .entry(100) + .or_default() + .insert(hash(100), HeaderStatus::Synced); + queue + .known_headers + .entry(101) + .or_default() + .insert(hash(101), HeaderStatus::Incomplete); + queue + .known_headers + .entry(102) + .or_default() + .insert(hash(102), HeaderStatus::Incomplete); + queue + .known_headers + .entry(103) + .or_default() + .insert(hash(103), HeaderStatus::Incomplete); + queue + .known_headers + .entry(104) + .or_default() + .insert(hash(104), HeaderStatus::Incomplete); // let's say relay#2 completes header#100 and then submits header#101+header#102 and it turns // that header#102 is also incomplete From 0798757508448d9b00f6b2de05f0a47a02cf28d5 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 8 May 2020 11:09:35 +0300 Subject: [PATCH 84/92] Update relays/ethereum/src/sync_loop.rs Co-authored-by: Hernando Castano --- relays/ethereum/src/sync_loop.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/sync_loop.rs b/relays/ethereum/src/sync_loop.rs index 9d1576f821..ce89a846a0 100644 --- a/relays/ethereum/src/sync_loop.rs +++ b/relays/ethereum/src/sync_loop.rs @@ -25,7 +25,7 @@ use std::{ }; /// When we submit headers to target node, but see no updates of best -/// source block known to target node during STALL_SYNC_TIMEOUT_MS milliseconds, +/// source block known to target node during STALL_SYNC_TIMEOUT seconds, /// we consider that our headers are rejected because there has been reorg in target chain. /// This reorg could invalidate our knowledge about sync process (i.e. we have asked if /// HeaderA is known to target, but then reorg happened and the answer is different From 75e8c291aca2606a91c712f472cfb44ee28bfd84 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 11 May 2020 11:10:16 +0300 Subject: [PATCH 85/92] Update relays/ethereum/src/headers.rs Co-authored-by: Hernando Castano --- relays/ethereum/src/headers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index 52621d9b80..e9b3abc440 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -1494,7 +1494,7 @@ pub(crate) mod tests { .insert(hash(104), HeaderStatus::Incomplete); // let's say relay#2 completes header#100 and then submits header#101+header#102 and it turns - // that header#102 is also incomplete + // out that header#102 is also incomplete queue.incomplete_headers_response(vec![id(102)].into_iter().collect()); // then the header#103 and the header#104 must have Incomplete status From 77180d766f484d4bb0af5d1817f61809136138ed Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 11 May 2020 11:10:41 +0300 Subject: [PATCH 86/92] Update relays/ethereum/src/headers.rs Co-authored-by: Hernando Castano --- relays/ethereum/src/headers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index e9b3abc440..38b81a0b0c 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -1461,7 +1461,7 @@ pub(crate) mod tests { fn incomplete_headers_are_still_incomplete_after_advance() { let mut queue = QueuedHeaders::::new(); - // relay#1 knows that header#100 is incomplete && it has headers 101..104 in inomplete queue + // relay#1 knows that header#100 is incomplete && it has headers 101..104 in incomplete queue queue.incomplete_headers.insert(id(100), None); queue.incomplete.entry(101).or_default().insert(hash(101), header(101)); queue.incomplete.entry(102).or_default().insert(hash(102), header(102)); From 23c254f39843e3c77bc0aa1d342c82dd3fb28bbf Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 11 May 2020 11:10:50 +0300 Subject: [PATCH 87/92] Update relays/ethereum/src/headers.rs Co-authored-by: Hernando Castano --- relays/ethereum/src/headers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index 38b81a0b0c..4d752962dc 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -730,7 +730,7 @@ fn queued_incomplete_header( map: &mut LinkedHashMap, filter: impl FnMut(&mut T) -> bool, ) -> Option<(Id, &T)> { - // TODO: headers that have been just appended to the end of the queue would have to wait until + // TODO (#84): headers that have been just appended to the end of the queue would have to wait until // all previous headers will be retried let retry_old_header = map From 8e627827a1d39a0300ceed3e6224953391e545f5 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 11 May 2020 11:11:00 +0300 Subject: [PATCH 88/92] Update relays/ethereum/src/headers.rs Co-authored-by: Hernando Castano --- relays/ethereum/src/headers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index 4d752962dc..2030e8d62a 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -725,7 +725,7 @@ fn set_header_status( *known_headers.entry(id.0).or_default().entry(id.1).or_insert(status) = status; } -/// Returns queued imcomplete header with maximal elapsed time since last update. +/// Returns queued incomplete header with maximal elapsed time since last update. fn queued_incomplete_header( map: &mut LinkedHashMap, filter: impl FnMut(&mut T) -> bool, From 83725c05e170dc10c9c1d904d65cbb616474527c Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 11 May 2020 11:11:16 +0300 Subject: [PATCH 89/92] Update relays/ethereum/src/headers.rs Co-authored-by: Hernando Castano --- relays/ethereum/src/headers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index 2030e8d62a..46f20eb02b 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -587,7 +587,7 @@ fn remove_header( header } -/// Get header from the qeueue. +/// Get header from the queue. fn header<'a, P: HeadersSyncPipeline>( queue: &'a HeadersQueue

, id: &HeaderId, From 2812db14045363959033877af08dabb2cbc61c12 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 11 May 2020 11:11:27 +0300 Subject: [PATCH 90/92] Update relays/ethereum/src/headers.rs Co-authored-by: Hernando Castano --- relays/ethereum/src/headers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index 46f20eb02b..1cdfacd9d1 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -460,7 +460,7 @@ impl QueuedHeaders

{ queued_incomplete_header(&mut self.completion_data, |_| true) } - /// Prune and never accep headers before this block. + /// Prune and never accept headers before this block. pub fn prune(&mut self, prune_border: P::Number) { if prune_border <= self.prune_border { return; From 16c4845c21122d711cde3d95aebb255742411d95 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 11 May 2020 11:11:37 +0300 Subject: [PATCH 91/92] Update relays/ethereum/src/headers.rs Co-authored-by: Hernando Castano --- relays/ethereum/src/headers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relays/ethereum/src/headers.rs b/relays/ethereum/src/headers.rs index 1cdfacd9d1..a75937da8c 100644 --- a/relays/ethereum/src/headers.rs +++ b/relays/ethereum/src/headers.rs @@ -429,7 +429,7 @@ impl QueuedHeaders

{ log::debug!( target: "bridge", - "Completion data is no more required for header: {:?}", + "Completion data is no longer required for header: {:?}", just_completed_header, ); From 16f1f29c76b11f4cd93562580d7eb0997e0b2885 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 11 May 2020 11:32:21 +0300 Subject: [PATCH 92/92] added comments on Extra and Completion --- relays/ethereum/src/sync_types.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/relays/ethereum/src/sync_types.rs b/relays/ethereum/src/sync_types.rs index 4767a5daac..8d68bd8759 100644 --- a/relays/ethereum/src/sync_types.rs +++ b/relays/ethereum/src/sync_types.rs @@ -71,9 +71,21 @@ pub trait HeadersSyncPipeline: Clone + Copy { + num_traits::One; /// Type of header that we're syncing. type Header: Clone + std::fmt::Debug + SourceHeader; - /// Type of extra data for the header that we're receiving from the source node. + /// Type of extra data for the header that we're receiving from the source node: + /// 1) extra data is required for some headers; + /// 2) target node may answer if it'll require extra data before header is submitted; + /// 3) extra data available since the header creation time; + /// 4) header and extra data are submitted in single transaction. + /// + /// Example: Ethereum transactions receipts. type Extra: Clone + std::fmt::Debug; - /// Type of data required to 'complete' header that we're receiving from the source node. + /// Type of data required to 'complete' header that we're receiving from the source node: + /// 1) completion data is required for some headers; + /// 2) target node can't answer if it'll require completion data before header is accepted; + /// 3) completion data may be generated after header generation; + /// 4) header and completion data are submitted in separate transactions. + /// + /// Example: Substrate GRANDPA justifications. type Completion: Clone + std::fmt::Debug; /// Function used to estimate size of target-encoded header.