diff --git a/Cargo.lock b/Cargo.lock index 5d3e97004772..ccf4a52e1d4e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,11 +2,11 @@ # It is not intended for manual editing. [[package]] name = "adder" -version = "0.6.2" +version = "0.6.3" dependencies = [ "dlmalloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "polkadot-parachain 0.6.2", + "polkadot-parachain 0.6.3", "sr-std 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-wasm-builder-runner 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -16,14 +16,15 @@ dependencies = [ name = "adder-collator" version = "0.1.0" dependencies = [ - "adder 0.6.2", + "adder 0.6.3", "ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "polkadot-collator 0.6.2", - "polkadot-parachain 0.6.2", - "polkadot-primitives 0.6.2", + "polkadot-collator 0.6.3", + "polkadot-parachain 0.6.3", + "polkadot-primitives 0.6.3", + "substrate-client 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", ] @@ -848,7 +849,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "fork-tree" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1057,7 +1058,7 @@ dependencies = [ [[package]] name = "halt" -version = "0.6.2" +version = "0.6.3" dependencies = [ "substrate-wasm-builder-runner 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2642,18 +2643,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "polkadot" -version = "0.6.2" +version = "0.6.3" dependencies = [ "ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "polkadot-cli 0.6.2", - "polkadot-service 0.6.2", + "polkadot-cli 0.6.3", + "polkadot-service 0.6.3", "vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "polkadot-availability-store" -version = "0.6.2" +version = "0.6.3" dependencies = [ "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=616b40150ded71f57f650067fcbc5c99d7c343e6)", "kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=616b40150ded71f57f650067fcbc5c99d7c343e6)", @@ -2661,18 +2662,18 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "polkadot-primitives 0.6.2", + "polkadot-primitives 0.6.3", "substrate-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", ] [[package]] name = "polkadot-cli" -version = "0.6.2" +version = "0.6.3" dependencies = [ "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "polkadot-service 0.6.2", + "polkadot-service 0.6.3", "structopt 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-cli 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2680,17 +2681,17 @@ dependencies = [ [[package]] name = "polkadot-collator" -version = "0.6.2" +version = "0.6.3" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "polkadot-cli 0.6.2", - "polkadot-network 0.6.2", - "polkadot-primitives 0.6.2", - "polkadot-runtime 0.6.2", - "polkadot-service 0.6.2", - "polkadot-validation 0.6.2", + "polkadot-cli 0.6.3", + "polkadot-network 0.6.3", + "polkadot-primitives 0.6.3", + "polkadot-runtime 0.6.3", + "polkadot-service 0.6.3", + "polkadot-validation 0.6.3", "substrate-client 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-consensus-common 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-keyring 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -2701,10 +2702,10 @@ dependencies = [ [[package]] name = "polkadot-erasure-coding" -version = "0.6.2" +version = "0.6.3" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "polkadot-primitives 0.6.2", + "polkadot-primitives 0.6.3", "reed-solomon-erasure 4.0.0 (git+https://github.com/paritytech/reed-solomon-erasure)", "substrate-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-trie 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -2712,15 +2713,15 @@ dependencies = [ [[package]] name = "polkadot-executor" -version = "0.6.2" +version = "0.6.3" dependencies = [ - "polkadot-runtime 0.6.2", + "polkadot-runtime 0.6.3", "substrate-executor 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", ] [[package]] name = "polkadot-network" -version = "0.6.2" +version = "0.6.3" dependencies = [ "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2729,9 +2730,9 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "polkadot-availability-store 0.6.2", - "polkadot-primitives 0.6.2", - "polkadot-validation 0.6.2", + "polkadot-availability-store 0.6.3", + "polkadot-primitives 0.6.3", + "polkadot-validation 0.6.3", "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-client 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-keyring 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -2741,11 +2742,11 @@ dependencies = [ [[package]] name = "polkadot-parachain" -version = "0.6.2" +version = "0.6.3" dependencies = [ - "adder 0.6.2", + "adder 0.6.3", "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "halt 0.6.2", + "halt 0.6.3", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2760,11 +2761,11 @@ dependencies = [ [[package]] name = "polkadot-primitives" -version = "0.6.2" +version = "0.6.3" dependencies = [ "bitvec 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "polkadot-parachain 0.6.2", + "polkadot-parachain 0.6.3", "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -2779,10 +2780,10 @@ dependencies = [ [[package]] name = "polkadot-rpc" -version = "0.6.0" +version = "0.6.3" dependencies = [ "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "polkadot-primitives 0.6.2", + "polkadot-primitives 0.6.3", "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "srml-system-rpc 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-client 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -2792,14 +2793,15 @@ dependencies = [ [[package]] name = "polkadot-runtime" -version = "0.6.2" +version = "0.6.3" dependencies = [ "bitvec 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "libsecp256k1 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "polkadot-primitives 0.6.2", + "polkadot-parachain 0.6.3", + "polkadot-primitives 0.6.3", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2810,12 +2812,13 @@ dependencies = [ "sr-staking-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "sr-std 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "sr-version 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", + "srml-authority-discovery 0.1.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "srml-authorship 0.1.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "srml-babe 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "srml-balances 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "srml-collective 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "srml-democracy 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", - "srml-elections 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", + "srml-elections-phragmen 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "srml-executive 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "srml-finality-tracker 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "srml-grandpa 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -2834,6 +2837,7 @@ dependencies = [ "srml-timestamp 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "srml-transaction-payment 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "srml-treasury 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", + "substrate-authority-discovery-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-client 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-consensus-babe-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-inherents 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -2850,7 +2854,7 @@ dependencies = [ [[package]] name = "polkadot-service" -version = "0.6.2" +version = "0.6.3" dependencies = [ "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2858,19 +2862,20 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "polkadot-availability-store 0.6.2", - "polkadot-executor 0.6.2", - "polkadot-network 0.6.2", - "polkadot-primitives 0.6.2", - "polkadot-rpc 0.6.0", - "polkadot-runtime 0.6.2", - "polkadot-validation 0.6.2", + "polkadot-availability-store 0.6.3", + "polkadot-executor 0.6.3", + "polkadot-network 0.6.3", + "polkadot-primitives 0.6.3", + "polkadot-rpc 0.6.3", + "polkadot-runtime 0.6.3", + "polkadot-validation 0.6.3", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "srml-babe 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "srml-im-online 0.1.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "srml-staking 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", + "substrate-authority-discovery 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-client 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-client-db 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-consensus-babe 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -2890,16 +2895,16 @@ dependencies = [ [[package]] name = "polkadot-statement-table" -version = "0.6.2" +version = "0.6.3" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "polkadot-primitives 0.6.2", + "polkadot-primitives 0.6.3", "substrate-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", ] [[package]] name = "polkadot-validation" -version = "0.6.2" +version = "0.6.3" dependencies = [ "bitvec 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2910,11 +2915,11 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "polkadot-availability-store 0.6.2", - "polkadot-parachain 0.6.2", - "polkadot-primitives 0.6.2", - "polkadot-runtime 0.6.2", - "polkadot-statement-table 0.6.2", + "polkadot-availability-store 0.6.3", + "polkadot-parachain 0.6.3", + "polkadot-primitives 0.6.3", + "polkadot-runtime 0.6.3", + "polkadot-statement-table 0.6.3", "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "srml-babe 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-client 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -3699,7 +3704,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "sr-api-macros" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3711,7 +3716,7 @@ dependencies = [ [[package]] name = "sr-arithmetic" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3724,7 +3729,7 @@ dependencies = [ [[package]] name = "sr-io" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "libsecp256k1 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3742,7 +3747,7 @@ dependencies = [ [[package]] name = "sr-primitives" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3760,7 +3765,7 @@ dependencies = [ [[package]] name = "sr-staking-primitives" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -3770,7 +3775,7 @@ dependencies = [ [[package]] name = "sr-std" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3778,7 +3783,7 @@ dependencies = [ [[package]] name = "sr-version" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3787,10 +3792,27 @@ dependencies = [ "sr-std 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", ] +[[package]] +name = "srml-authority-discovery" +version = "0.1.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" +dependencies = [ + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", + "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", + "sr-std 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", + "srml-session 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", + "srml-support 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", + "srml-system 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", + "substrate-application-crypto 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", + "substrate-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", +] + [[package]] name = "srml-authorship" version = "0.1.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3806,7 +3828,7 @@ dependencies = [ [[package]] name = "srml-babe" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3826,7 +3848,7 @@ dependencies = [ [[package]] name = "srml-balances" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3841,7 +3863,7 @@ dependencies = [ [[package]] name = "srml-collective" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3857,7 +3879,7 @@ dependencies = [ [[package]] name = "srml-democracy" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3870,25 +3892,25 @@ dependencies = [ ] [[package]] -name = "srml-elections" +name = "srml-elections-phragmen" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "sr-std 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "srml-support 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "srml-system 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", + "substrate-phragmen 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", ] [[package]] name = "srml-executive" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3902,7 +3924,7 @@ dependencies = [ [[package]] name = "srml-finality-tracker" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3917,7 +3939,7 @@ dependencies = [ [[package]] name = "srml-grandpa" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3935,7 +3957,7 @@ dependencies = [ [[package]] name = "srml-im-online" version = "0.1.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3953,7 +3975,7 @@ dependencies = [ [[package]] name = "srml-indices" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3970,7 +3992,7 @@ dependencies = [ [[package]] name = "srml-membership" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3984,7 +4006,7 @@ dependencies = [ [[package]] name = "srml-metadata" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3995,7 +4017,7 @@ dependencies = [ [[package]] name = "srml-offences" version = "1.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4010,7 +4032,7 @@ dependencies = [ [[package]] name = "srml-randomness-collective-flip" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4023,7 +4045,7 @@ dependencies = [ [[package]] name = "srml-session" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4042,7 +4064,7 @@ dependencies = [ [[package]] name = "srml-staking" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4062,7 +4084,7 @@ dependencies = [ [[package]] name = "srml-staking-reward-curve" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4073,7 +4095,7 @@ dependencies = [ [[package]] name = "srml-sudo" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4087,7 +4109,7 @@ dependencies = [ [[package]] name = "srml-support" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4108,7 +4130,7 @@ dependencies = [ [[package]] name = "srml-support-procedural" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4120,7 +4142,7 @@ dependencies = [ [[package]] name = "srml-support-procedural-tools" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4132,7 +4154,7 @@ dependencies = [ [[package]] name = "srml-support-procedural-tools-derive" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4142,7 +4164,7 @@ dependencies = [ [[package]] name = "srml-system" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4159,7 +4181,7 @@ dependencies = [ [[package]] name = "srml-system-rpc" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4177,7 +4199,7 @@ dependencies = [ [[package]] name = "srml-system-rpc-runtime-api" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-client 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -4186,7 +4208,7 @@ dependencies = [ [[package]] name = "srml-timestamp" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4201,7 +4223,7 @@ dependencies = [ [[package]] name = "srml-transaction-payment" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -4213,7 +4235,7 @@ dependencies = [ [[package]] name = "srml-treasury" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4300,7 +4322,7 @@ dependencies = [ [[package]] name = "substrate-application-crypto" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4312,7 +4334,7 @@ dependencies = [ [[package]] name = "substrate-authority-discovery" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4334,7 +4356,7 @@ dependencies = [ [[package]] name = "substrate-authority-discovery-primitives" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -4356,7 +4378,7 @@ dependencies = [ [[package]] name = "substrate-chain-spec" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4371,7 +4393,7 @@ dependencies = [ [[package]] name = "substrate-chain-spec-derive" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4382,7 +4404,7 @@ dependencies = [ [[package]] name = "substrate-cli" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4418,7 +4440,7 @@ dependencies = [ [[package]] name = "substrate-client" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4448,7 +4470,7 @@ dependencies = [ [[package]] name = "substrate-client-db" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", @@ -4472,7 +4494,7 @@ dependencies = [ [[package]] name = "substrate-consensus-babe" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "fork-tree 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -4510,7 +4532,7 @@ dependencies = [ [[package]] name = "substrate-consensus-babe-primitives" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4524,7 +4546,7 @@ dependencies = [ [[package]] name = "substrate-consensus-common" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4543,7 +4565,7 @@ dependencies = [ [[package]] name = "substrate-consensus-slots" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4561,7 +4583,7 @@ dependencies = [ [[package]] name = "substrate-consensus-uncles" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -4575,7 +4597,7 @@ dependencies = [ [[package]] name = "substrate-debug-derive" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4585,7 +4607,7 @@ dependencies = [ [[package]] name = "substrate-executor" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4609,7 +4631,7 @@ dependencies = [ [[package]] name = "substrate-externalities" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "environmental 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "primitive-types 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4620,7 +4642,7 @@ dependencies = [ [[package]] name = "substrate-finality-grandpa" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "finality-grandpa 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "fork-tree 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -4649,7 +4671,7 @@ dependencies = [ [[package]] name = "substrate-finality-grandpa-primitives" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4662,7 +4684,7 @@ dependencies = [ [[package]] name = "substrate-header-metadata" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4672,7 +4694,7 @@ dependencies = [ [[package]] name = "substrate-inherents" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4683,7 +4705,7 @@ dependencies = [ [[package]] name = "substrate-keyring" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -4695,7 +4717,7 @@ dependencies = [ [[package]] name = "substrate-keystore" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4710,7 +4732,7 @@ dependencies = [ [[package]] name = "substrate-network" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4752,7 +4774,7 @@ dependencies = [ [[package]] name = "substrate-offchain" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4779,7 +4801,7 @@ dependencies = [ [[package]] name = "substrate-offchain-primitives" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-client 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -4788,7 +4810,7 @@ dependencies = [ [[package]] name = "substrate-panic-handler" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4797,7 +4819,7 @@ dependencies = [ [[package]] name = "substrate-peerset" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4810,7 +4832,7 @@ dependencies = [ [[package]] name = "substrate-phragmen" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "sr-std 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -4819,7 +4841,7 @@ dependencies = [ [[package]] name = "substrate-primitives" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4830,6 +4852,7 @@ dependencies = [ "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libsecp256k1 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4847,6 +4870,7 @@ dependencies = [ "substrate-externalities 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-primitives-storage 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "twox-hash 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4855,7 +4879,7 @@ dependencies = [ [[package]] name = "substrate-primitives-storage" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4866,7 +4890,7 @@ dependencies = [ [[package]] name = "substrate-rpc" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4892,7 +4916,7 @@ dependencies = [ [[package]] name = "substrate-rpc-api" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4914,7 +4938,7 @@ dependencies = [ [[package]] name = "substrate-rpc-primitives" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -4923,7 +4947,7 @@ dependencies = [ [[package]] name = "substrate-rpc-servers" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-http-server 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4938,7 +4962,7 @@ dependencies = [ [[package]] name = "substrate-serializer" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4947,7 +4971,7 @@ dependencies = [ [[package]] name = "substrate-service" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4989,7 +5013,7 @@ dependencies = [ [[package]] name = "substrate-session" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "sr-std 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", @@ -5000,7 +5024,7 @@ dependencies = [ [[package]] name = "substrate-state-db" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5011,7 +5035,7 @@ dependencies = [ [[package]] name = "substrate-state-machine" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5030,7 +5054,7 @@ dependencies = [ [[package]] name = "substrate-telemetry" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5052,7 +5076,7 @@ dependencies = [ [[package]] name = "substrate-transaction-graph" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5066,7 +5090,7 @@ dependencies = [ [[package]] name = "substrate-transaction-pool" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5082,7 +5106,7 @@ dependencies = [ [[package]] name = "substrate-trie" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5101,7 +5125,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "substrate-wasm-interface" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#acf86cd4b0ad4c45dbba57c2ae323531d5b71264" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#c6524464feb7c88d35e73e5e3a9f7fde90763d97" dependencies = [ "wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6327,12 +6351,13 @@ dependencies = [ "checksum sr-staking-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)" = "" "checksum sr-std 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)" = "" "checksum sr-version 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)" = "" +"checksum srml-authority-discovery 0.1.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)" = "" "checksum srml-authorship 0.1.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)" = "" "checksum srml-babe 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)" = "" "checksum srml-balances 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)" = "" "checksum srml-collective 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)" = "" "checksum srml-democracy 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)" = "" -"checksum srml-elections 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)" = "" +"checksum srml-elections-phragmen 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)" = "" "checksum srml-executive 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)" = "" "checksum srml-finality-tracker 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)" = "" "checksum srml-grandpa 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)" = "" diff --git a/Cargo.toml b/Cargo.toml index af37ce86d404..17805a9cf446 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ path = "src/main.rs" [package] name = "polkadot" -version = "0.6.2" +version = "0.6.3" authors = ["Parity Technologies "] build = "build.rs" edition = "2018" diff --git a/README.adoc b/README.adoc index aae95598c916..8a2fd2ab03d9 100644 --- a/README.adoc +++ b/README.adoc @@ -12,9 +12,9 @@ In 2017 we split our implementation of "Polkadot" from its platform-level compon We are actively building both Substrate and Polkadot, but things will be a little odd for a while. If you see "substrate" and are wondering why you need it for Polkadot, now you know. -To connect on the "Kusama" canary network, you will want the `v0.5` code which is in this **Polkadot** repo. To play on the ("Alexander") testnet, you'll want the PoC-4 code instead. Note that PoC-3 uses the Alexander testnet, but will not be able to sync to the latest block. +To connect on the "Kusama" canary network, you will want the `v0.6` code, which is in this **Polkadot** repo. To play on the ("Alexander") testnet, you'll want the PoC-4 code instead. Note that PoC-3 uses the Alexander testnet, but will not be able to sync to the latest block. -* **Kusama** is in this link:https://github.com/paritytech/polkadot/tree/v0.5[**Polkadot**] repo branch `v0.5`. +* **Kusama** is in this link:https://github.com/paritytech/polkadot/tree/v0.6[**Polkadot**] repo branch `v0.6`. * **Polkadot PoC-4 "Alexander"** is in this link:https://github.com/paritytech/polkadot/tree/v0.4[**Polkadot**] repo branch `v0.4`. @@ -48,7 +48,7 @@ rustup update Build Kusama by cloning this repository and running the following commands from the root directory of the repo: ```bash -git checkout v0.5 +git checkout v0.6 ./scripts/init.sh cargo build --release ``` @@ -59,6 +59,8 @@ Connect to the global Kusama canary network by default by running: ./target/release/polkadot ``` +You can see your node on link:https://telemetry.polkadot.io/#list/Kusama%20CC2[telemetry]. + === Install PoC-4 on "Alexander" Testnet Build Polkadot PoC-4 by cloning this repository and running the following commands from the root directory of the repo: diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000000..db81bcaab4d0 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,101 @@ +# Security Policy + +Parity Technologies is committed to resolving security vulnerabilities in our software quickly and carefully. We take the necessary steps to minimize risk, provide timely information, and deliver vulnerability fixes and mitigations required to address security issues. + +## Reporting a Vulnerability + +Security vulnerabilities in Parity software should be reported by email to security@parity.io. If you think your report might be eligible for the Parity Bug Bounty Program, your email should be sent to bugbounty@parity.io. + +Your report should include the following: + +- your name +- description of the vulnerability +- attack scenario (if any) +- components +- reproduction +- other details + +Try to include as much information in your report as you can, including a description of the vulnerability, its potential impact, and steps for reproducing it. Be sure to use a descriptive subject line. + +You'll receive a response to your email within two business days indicating the next steps in handling your report. We encourage finders to use encrypted communication channels to protect the confidentiality of vulnerability reports. You can encrypt your report using our public key. This key is [on MIT's key server](https://pgp.mit.edu/pks/lookup?op=get&search=0x5D0F03018D07DE73) server and reproduced below. + +After the initial reply to your report, our team will endeavor to keep you informed of the progress being made towards a fix. These updates will be sent at least every five business days. + +Thank you for taking the time to responsibly disclose any vulnerabilities you find. + +## Responsible Investigation and Reporting + +Responsible investigation and reporting includes, but isn't limited to, the following: + +- Don't violate the privacy of other users, destroy data, etc. +- Don’t defraud or harm Parity Technologies Ltd or its users during your research; you should make a good faith effort to not interrupt or degrade our services. +- Don't target our physical security measures, or attempt to use social engineering, spam, distributed denial of service (DDOS) attacks, etc. +- Initially report the bug only to us and not to anyone else. +- Give us a reasonable amount of time to fix the bug before disclosing it to anyone else, and give us adequate written warning before disclosing it to anyone else. +- In general, please investigate and report bugs in a way that makes a reasonable, good faith effort not to be disruptive or harmful to us or our users. Otherwise your actions might be interpreted as an attack rather than an effort to be helpful. + +## Bug Bounty Program + +Our Bug Bounty Program allows us to recognise and reward members of the Parity community for helping us find and address significant bugs, in accordance with the terms of the Parity Bug Bounty Program. A detailed description on eligibility, rewards, legal information and terms & conditions for contributors can be found on [our website](https://paritytech.io/bug-bounty.html). + + + + + + +## Plaintext PGP Key + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBF0vHwQBEADKui4qAo4bzdzRhMm+uhUpYGf8jjjmET3zJ8kKQIpp6JTsV+HJ +6m1We0QYeMRXoOYH1xVHBf2zNCuHS0nSQdUCQA7SHWsPB05STa2hvlR7fSdQnCCp +gnLOJWXvvedlRDIAhvqI6cwLdUlXgVSKEwrwmrpiBhh4NxI3qX+LyIa+Ovkchu2S +d/YCnE4GqojSGRfJYiGwe2N+sF7OfaoKhQuTrtdDExHrMU4cWnTXW2wyxTr4xkj9 +jS2WeLVZWflvkDHT8JD9N6jNxBVEF/Qvjk83zI0kCOzkhek8x+YUgfLq3/rHOYbX +3pW21ccHYPacHjHWvKE+xRebjeEhJ4KxKHfCVjQcxybwDBqDka1AniZt4CQ7UORf +MU/ue2oSZ9nNg0uMdb/0AbQPZ04OlMcYPAPWzFL08nVPox9wT9uqlL6JtcOeC90h +oOeDmfgwmjMmdwWTRgt9qQjcbgXzVvuAzIGbzj1X3MdLspWdHs/d2+US4nji1TkN +oYIW7vE+xkd3aB+NZunIlm9Rwd/0mSgDg+DaNa5KceOLhq0/qKgcXC/RRU29I8II +tusRoR/oesGJGYTjh4k6PJkG+nvDPsoQrwYT44bhnniS1xYkxWYXF99JFI7LgMdD +e1SgKeIDVpvm873k82E6arp5655Wod1XOjaXBggCwFp84eKcEZEN+1qEWwARAQAB +tClQYXJpdHkgU2VjdXJpdHkgVGVhbSA8c2VjdXJpdHlAcGFyaXR5LmlvPokCVAQT +AQoAPhYhBJ1LK264+XFW0ZZpqf8IEtSRuWeYBQJdLx8EAhsDBQkDwmcABQsJCAcC +BhUKCQgLAgQWAgMBAh4BAheAAAoJEP8IEtSRuWeYL84QAI6NwnwS561DWYYRAd4y +ocGPr3CnwFSt1GjkSkRy3B+tMhzexBg1y7EbLRUefIrO4LwOlywtRk8tTRGgEI4i +5xRLHbOkeolfgCFSpOj5d8cMKCt5HEIv18hsv6dkrzlSYA5NLX/GRBEh3F/0sGny +vCXapfxa1cx72sU7631JBK7t2Tf+MfwxdfyFZ9TI9WdtP5AfVjgTkIVkEDFcZPTc +n3CYXqTYFIBCNUD8LP4iTi3xUt7pTGJQQoFT8l15nJCgzRYQ+tXpoTRlf+/LtXmw +6iidPV87E06jHdK9666rBouIabAtx7i0/4kwo+bSZ8DiSKRUaehiHGd212HSEmdF +jxquWE4pEzoUowYznhSIfR+WWIqRBHxEYarP4m98Hi+VXZ7Fw1ytzO8+BAKnLXnj +2W2+T9qJks5gqVEoaWNnqpvya6JA11QZvZ0w7Om2carDc2ILNm2Xx9J0mRUye8P0 +KxcgqJuKNGFtugebQAsXagkxOKsdKna1PlDlxEfTf6AgI3ST8qSiMAwaaIMB/REF +VKUapGoslQX4tOCjibI2pzEgE//D8NAaSVu2A9+BUcFERdZRxsI7fydIXNeZ2R46 +N2qfW+DP3YR/14QgdRxDItEavUoE1vByRXwIufKAkVemOZzIoFXKFsDeXwqTVW5i +6CXu6OddZ3QHDiT9TEbRny4QuQINBF0vKCwBEACnP5J7LEGbpxNBrPvGdxZUo0YA +U8RgeKDRPxJTvMo27V1IPZGaKRCRq8LBfg/eHhqZhQ7SLJBjBljd8kuT5dHDBTRe +jE1UIOhmnlSlrEJjAmpVO08irlGpq1o+8mGcvkBsR0poCVjeNeSnwYfRnR+c3GK5 +Er6/JRqfN4mJvnEC9/Pbm6C7ql6YLKxC3yqzF97JL5brbbuozrW7nixY/yAI8619 +VlBIMP7PAUbGcnSQyuV5b/Wr2Sgr6NJclnNSLjh2U9/Du6w/0tDGlMBts8HjRnWJ +BXbkTdQKCTaqgK68kTKSiN1/x+lynxHC2AavMpH/08Kopg2ZCzJowMKIgcB+4Z/I +DJKZWHWKumhaZMGXcWgzgcByog9IpamuROEZFJNEUAFf7YIncEckPSif4looiOdS +VurKZGvYXXaGSsZbGgHxI5CWu7ZxMdLBLvtOcCYmRQrG+g/h+PGU5BT0bNAfNTkm +V3/n1B/TWbpWRmB3AwT2emQivXHkaubGI0VivhaO43AuI9JWoqiMqFtxbuTeoxwD +xlu2Dzcp0v+AR4T5cIG9D5/+yiPc25aIY7cIKxuNFHIDL4td5fwSGC7vU6998PIG +2Y48TGBnw7zpEfDfMayqAeBjX0YU6PTNsvS5O6bP3j4ojTOUYD7Z8QdCvgISDID3 +WMGAdmSwmCRvsQ/OJwARAQABiQI8BBgBCgAmFiEEnUsrbrj5cVbRlmmp/wgS1JG5 +Z5gFAl0vKCwCGwwFCQB2pwAACgkQ/wgS1JG5Z5hdbw//ZqR+JcWm59NUIHjauETJ +sYDYhcAfa3txTacRn5uPz/TQiTd7wZ82+G8Et0ZnpEHy6eWyBqHpG0hiPhFBzxjY +nhjHl8jJeyo2mQIVJhzkL58BHBZk8WM2TlaU7VxZ6TYOmP2y3qf6FD6mCcrQ4Fml +E9f0lyVUoI/5Zs9oF0izRk8vkwaY3UvLM7XEY6nM8GnFG8kaiZMYmx26Zo7Uz31G +7EGGZFsrVDXfNhSJyz79Gyn+Lx9jOTdoR0sH/THYIIosE83awMGE6jKeuDYTbVWu ++ZtHQef+pRteki3wvNLJK+kC1y3BtHqDJS9Lqx0s8SCiVozlC+fZfC9hCtU7bXJK +0UJZ4qjSvj6whzfaNgOZAqJpmwgOnd8W/3YJk1DwUeX98FcU38MR23SOkx2EDdDE +77Kdu62vTs/tLmOTuyKBvYPaHaYulYjQTxurG+o8vhHtaL87ARvuq+83dj+nO5z3 +5O9vkcVJYWjOEnJe7ZvCTxeLJehpCmHIbyUuDx5P24MWVbyXOxIlxNxTqlub5GlW +rQF6Qsa/0k9TRk7Htbct6fAA0/VahJS0g096MrTH8AxBXDNE8lIoNeGikVlaxK9Z +S+aannlWYIJymZ4FygIPPaRlzhAoXBuJd8OaR5giC7dS1xquxKOiQEXTGsLeGFaI +BZYiIhW7GG4ozvKDqyNm4eg= +=yKcB +-----END PGP PUBLIC KEY BLOCK----- +``` diff --git a/availability-store/Cargo.toml b/availability-store/Cargo.toml index 7ea6cc4449b7..b2108313c819 100644 --- a/availability-store/Cargo.toml +++ b/availability-store/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "polkadot-availability-store" description = "Persistent database for parachain data" -version = "0.6.2" +version = "0.6.3" authors = ["Parity Technologies "] edition = "2018" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 6843ddc91c46..b3e49f389da4 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polkadot-cli" -version = "0.6.2" +version = "0.6.3" authors = ["Parity Technologies "] description = "Polkadot node implementation in Rust." edition = "2018" diff --git a/collator/Cargo.toml b/collator/Cargo.toml index 045f73ae3790..d8ebba4057f3 100644 --- a/collator/Cargo.toml +++ b/collator/Cargo.toml @@ -1,13 +1,13 @@ [package] name = "polkadot-collator" -version = "0.6.2" +version = "0.6.3" authors = ["Parity Technologies "] description = "Collator node implementation" edition = "2018" [dependencies] futures = "0.1.17" -futures03 = { package = "futures-preview", version = "0.3.0-alpha.19", features = ["compat"] } +futures03 = { package = "futures-preview", version = "0.3.0-alpha.18", features = ["compat"] } client = { package = "substrate-client", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } primitives = { package = "substrate-primitives", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } substrate-network = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } diff --git a/collator/src/lib.rs b/collator/src/lib.rs index d9e96fa26590..57b026721381 100644 --- a/collator/src/lib.rs +++ b/collator/src/lib.rs @@ -51,25 +51,25 @@ use std::time::Duration; use futures::{future, Stream, Future, IntoFuture}; use futures03::{TryStreamExt as _, StreamExt as _}; -use log::{info, warn}; +use log::{warn, error}; use client::BlockchainEvents; -use primitives::Pair; +use primitives::{Pair, Blake2Hasher}; use polkadot_primitives::{ BlockId, Hash, Block, parachain::{ - self, BlockData, DutyRoster, HeadData, ConsolidatedIngress, Message, Id as ParaId, OutgoingMessages, - PoVBlock, Status as ParachainStatus, ValidatorId, CollatorPair, + self, BlockData, DutyRoster, HeadData, ConsolidatedIngress, Message, Id as ParaId, + OutgoingMessages, PoVBlock, Status as ParachainStatus, ValidatorId, CollatorPair, } }; use polkadot_cli::{ - Worker, IntoExit, ProvideRuntimeApi, TaskExecutor, AbstractService, - CustomConfiguration, ParachainHost, + Worker, IntoExit, ProvideRuntimeApi, AbstractService, CustomConfiguration, ParachainHost, }; use polkadot_network::validation::{LeafWorkParams, ValidationNetwork}; use polkadot_network::{PolkadotNetworkService, PolkadotProtocol}; +use polkadot_runtime::RuntimeApi; use tokio::timer::Timeout; -pub use polkadot_cli::VersionInfo; +pub use polkadot_cli::{VersionInfo, TaskExecutor}; pub use polkadot_network::validation::Incoming; pub use polkadot_validation::SignedStatement; pub use polkadot_primitives::parachain::CollatorId; @@ -128,13 +128,24 @@ impl fmt::Display for Error { } } +/// The Polkadot client type. +pub type PolkadotClient = client::Client; + /// Something that can build a `ParachainContext`. pub trait BuildParachainContext { /// The parachain context produced by the `build` function. type ParachainContext: self::ParachainContext; /// Build the `ParachainContext`. - fn build(self, network: Arc) -> Result; + fn build( + self, + client: Arc>, + task_executor: TaskExecutor, + network: Arc, + ) -> Result + where + B: client::backend::Backend + 'static, + E: client::CallExecutor + Clone + Send + Sync + 'static; } /// Parachain context needed for collation. @@ -147,7 +158,7 @@ pub trait ParachainContext: Clone { /// Produce a candidate, given the relay parent hash, the latest ingress queue information /// and the last parachain head. fn produce_candidate>( - &self, + &mut self, relay_parent: Hash, status: ParachainStatus, ingress: I, @@ -174,7 +185,7 @@ pub fn collate<'a, R, P>( local_id: ParaId, parachain_status: ParachainStatus, relay_context: R, - para_context: P, + mut para_context: P, key: Arc, ) -> impl Future> + 'a @@ -289,10 +300,18 @@ impl Worker for CollationNode where } fn work(self, service: &S, task_executor: TaskExecutor) -> Self::Work - where S: AbstractService, - SC: polkadot_service::SelectChain + 'static, - B: polkadot_service::Backend + 'static, - CE: polkadot_service::CallExecutor + Clone + Send + Sync + 'static + where + S: AbstractService< + Block = Block, + RuntimeApi = RuntimeApi, + Backend = B, + SelectChain = SC, + NetworkSpecialization = PolkadotProtocol, + CallExecutor = CE, + >, + SC: polkadot_service::SelectChain + 'static, + B: client::backend::Backend + 'static, + CE: client::CallExecutor + Clone + Send + Sync + 'static { let CollationNode { build_parachain_context, exit, para_id, key } = self; let client = service.client(); @@ -301,7 +320,7 @@ impl Worker for CollationNode where let select_chain = if let Some(select_chain) = service.select_chain() { select_chain } else { - info!("The node cannot work because it can't select chain."); + error!("The node cannot work because it can't select chain."); return Box::new(future::err(())); }; @@ -334,13 +353,25 @@ impl Worker for CollationNode where exit.clone(), message_validator, client.clone(), - task_executor, + task_executor.clone(), )); - let parachain_context = build_parachain_context.build(validation_network.clone()).unwrap(); + let parachain_context = match build_parachain_context.build( + client.clone(), + task_executor, + validation_network.clone(), + ) { + Ok(ctx) => ctx, + Err(()) => { + error!("Could not build the parachain context!"); + return Box::new(future::err(())) + } + }; + let inner_exit = exit.clone(); let work = client.import_notification_stream() - .map(|v| Ok::<_, ()>(v)).compat() + .map(|v| Ok::<_, ()>(v)) + .compat() .for_each(move |notification| { macro_rules! try_fr { ($e:expr) => { @@ -489,7 +520,7 @@ mod tests { type ProduceCandidate = Result<(BlockData, HeadData, OutgoingMessages), InvalidHead>; fn produce_candidate>( - &self, + &mut self, _relay_parent: Hash, _status: ParachainStatus, ingress: I, diff --git a/docker/Dockerfile b/docker/Dockerfile index 19c3727edcf1..0a0746f27be6 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM phusion/baseimage:0.10.2 as builder +FROM phusion/baseimage:0.11 as builder LABEL maintainer "chevdor@gmail.com" LABEL description="This is the build stage for Polkadot. Here we create the binary." @@ -17,7 +17,7 @@ RUN curl https://sh.rustup.rs -sSf | sh -s -- -y && \ # ===== SECOND STAGE ====== -FROM phusion/baseimage:0.10.2 +FROM phusion/baseimage:0.11 LABEL maintainer "chevdor@gmail.com" LABEL description="This is the 2nd stage: a very small image where we copy the Polkadot binary." ARG PROFILE=release diff --git a/erasure-coding/Cargo.toml b/erasure-coding/Cargo.toml index 21b8176e3137..1dc7a3715f4a 100644 --- a/erasure-coding/Cargo.toml +++ b/erasure-coding/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polkadot-erasure-coding" -version = "0.6.2" +version = "0.6.3" authors = ["Parity Technologies "] edition = "2018" diff --git a/executor/Cargo.toml b/executor/Cargo.toml index 9efb53c0539a..5abd34ac514b 100644 --- a/executor/Cargo.toml +++ b/executor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polkadot-executor" -version = "0.6.2" +version = "0.6.3" authors = ["Parity Technologies "] description = "Polkadot node implementation in Rust." edition = "2018" diff --git a/network/Cargo.toml b/network/Cargo.toml index b1ebfceaa5ab..0010f0cc5e5c 100644 --- a/network/Cargo.toml +++ b/network/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polkadot-network" -version = "0.6.2" +version = "0.6.3" authors = ["Parity Technologies "] description = "Polkadot-specific networking protocol" edition = "2018" diff --git a/network/src/gossip.rs b/network/src/gossip.rs index b6d57d6bb025..04f873f0fcd0 100644 --- a/network/src/gossip.rs +++ b/network/src/gossip.rs @@ -265,7 +265,8 @@ impl ChainContext for (F, P) where let leaf_id = BlockId::Hash(leaf); let active_parachains = api.active_parachains(&leaf_id)?; - for para_id in active_parachains { + // TODO: https://github.com/paritytech/polkadot/issues/467 + for (para_id, _) in active_parachains { if let Some(ingress) = api.ingress(&leaf_id, para_id, None)? { for (_height, _from, queue_root) in ingress.iter() { with_queue_root(queue_root); diff --git a/network/src/tests/validation.rs b/network/src/tests/validation.rs index aa103cc4fb70..89d17be8f636 100644 --- a/network/src/tests/validation.rs +++ b/network/src/tests/validation.rs @@ -30,7 +30,7 @@ use polkadot_primitives::{Block, BlockNumber, Hash, Header, BlockId}; use polkadot_primitives::parachain::{ Id as ParaId, Chain, DutyRoster, ParachainHost, TargetedMessage, ValidatorId, StructuredUnroutedIngress, BlockIngressRoots, Status, - FeeSchedule, HeadData, + FeeSchedule, HeadData, Retriable, CollatorId }; use parking_lot::Mutex; use substrate_client::error::Result as ClientResult; @@ -177,7 +177,7 @@ impl NetworkService for TestNetwork { struct ApiData { validators: Vec, duties: Vec, - active_parachains: Vec, + active_parachains: Vec<(ParaId, Option<(CollatorId, Retriable)>)>, ingress: HashMap, } @@ -279,7 +279,7 @@ impl ParachainHost for RuntimeApi { _: ExecutionContext, _: Option<()>, _: Vec, - ) -> ClientResult>> { + ) -> ClientResult)>>> { Ok(NativeOrEncoded::Native(self.data.lock().active_parachains.clone())) } diff --git a/parachain/Cargo.toml b/parachain/Cargo.toml index 47f106e4b822..2c931928f74c 100644 --- a/parachain/Cargo.toml +++ b/parachain/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polkadot-parachain" -version = "0.6.2" +version = "0.6.3" authors = ["Parity Technologies "] description = "Types and utilities for creating and working with parachains" edition = "2018" @@ -10,8 +10,8 @@ codec = { package = "parity-scale-codec", version = "1.0.5", default-features = wasmi = { version = "0.4.3", optional = true } derive_more = { version = "0.14", optional = true } serde = { version = "1.0", default-features = false, features = [ "derive" ] } -substrate-primitives = { package = "substrate-primitives", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } rstd = { package = "sr-std", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } +substrate-primitives = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } lazy_static = { version = "1.3.0", optional = true } parking_lot = { version = "0.7.1", optional = true } log = { version = "0.4.6", optional = true } @@ -32,9 +32,9 @@ std = [ "wasmi", "derive_more", "serde/std", - "substrate-primitives/std", "rstd/std", "shared_memory", + "substrate-primitives/std", "lazy_static", "parking_lot", "log" diff --git a/parachain/src/lib.rs b/parachain/src/lib.rs index 3f3565332a46..ad3b9e4f4f11 100644 --- a/parachain/src/lib.rs +++ b/parachain/src/lib.rs @@ -54,7 +54,7 @@ pub mod wasm_api; use rstd::vec::Vec; use codec::{Encode, Decode, CompactAs}; -use substrate_primitives::RuntimeDebug; +use substrate_primitives::{RuntimeDebug, TypeId}; /// Validation parameters for evaluating the parachain validity function. // TODO: balance downloads (https://github.com/paritytech/polkadot/issues/220) @@ -86,6 +86,16 @@ pub struct ValidationResult { #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct Id(u32); +impl TypeId for Id { + const TYPE_ID: [u8; 4] = *b"para"; +} + +/// Type for determining the active set of parachains. +pub trait ActiveThreads { + /// Return the current ordered set of `Id`s of active parathreads. + fn active_threads() -> Vec; +} + impl From for u32 { fn from(x: Id) -> Self { x.0 } } @@ -94,10 +104,26 @@ impl From for Id { fn from(x: u32) -> Self { Id(x) } } +const USER_INDEX_START: u32 = 1000; + +/// The ID of the first user (non-system) parachain. +pub const LOWEST_USER_ID: Id = Id(USER_INDEX_START); + impl Id { - /// Convert this Id into its inner representation. - pub fn into_inner(self) -> u32 { - self.0 + /// Create an `Id`. + pub const fn new(id: u32) -> Self { + Self(id) + } + + /// Returns `true` if this parachain runs with system-level privileges. + pub fn is_system(&self) -> bool { self.0 < USER_INDEX_START } +} + +impl rstd::ops::Add for Id { + type Output = Self; + + fn add(self, other: u32) -> Self { + Self(self.0 + other) } } @@ -180,6 +206,9 @@ pub enum ParachainDispatchOrigin { /// As the special `Origin::Parachain(ParaId)`. This is good when interacting with parachain- /// aware modules which need to succinctly verify that the origin is a parachain. Parachain, + /// As the simple, superuser `Origin::Root`. This can only be done on specially permissioned + /// parachains. + Root, } impl rstd::convert::TryFrom for ParachainDispatchOrigin { diff --git a/parachain/src/wasm_api.rs b/parachain/src/wasm_api.rs index dec6b60b3dbc..90f804b45109 100644 --- a/parachain/src/wasm_api.rs +++ b/parachain/src/wasm_api.rs @@ -60,7 +60,7 @@ pub fn post_message(message: MessageRef) { let data_ptr = message.data.as_ptr(); let data_len = message.data.len(); - unsafe { ll::ext_post_message(message.target.into_inner(), data_ptr, data_len as u32) } + unsafe { ll::ext_post_message(message.target.into(), data_ptr, data_len as u32) } } /// Post a message to this parachain's relay chain. diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 4f8c6fd3ada1..c9deeaad1522 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polkadot-primitives" -version = "0.6.2" +version = "0.6.3" authors = ["Parity Technologies "] edition = "2018" diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index 782b5dbbcbd1..8cd38d8be971 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -20,9 +20,8 @@ #![cfg_attr(not(feature = "std"), no_std)] -use runtime_primitives::{generic, AnySignature}; - -pub use runtime_primitives::traits::{BlakeTwo256, Hash as HashT, Verify}; +use runtime_primitives::{generic, MultiSignature}; +pub use runtime_primitives::traits::{BlakeTwo256, Hash as HashT, Verify, IdentifyAccount}; pub mod parachain; @@ -35,12 +34,17 @@ pub type BlockNumber = u32; /// An instant or duration in time. pub type Moment = u64; -/// Alias to 512-bit hash when used in the context of a signature on the relay chain. -/// Equipped with logic for possibly "unsigned" messages. -pub type Signature = AnySignature; +/// Alias to type for a signature for a transaction on the relay chain. This allows one of several +/// kinds of underlying crypto to be used, so isn't a fixed size when encoded. +pub type Signature = MultiSignature; + +/// Alias to the public key used for this chain, actually a `MultiSigner`. Like the signature, this +/// also isn't a fixed size when encoded, as different cryptos have different size public keys. +pub type AccountPublic = ::Signer; -/// Alias to an sr25519 or ed25519 key. -pub type AccountId = ::Signer; +/// Alias to the opaque account ID type for this chain, actually a `AccountId32`. This is always +/// 32 bytes. +pub type AccountId = ::AccountId; /// The type for looking up accounts. We don't expect more than 4 billion of them. pub type AccountIndex = u32; diff --git a/primitives/src/parachain.rs b/primitives/src/parachain.rs index 8c7db2b5f173..0f22c9eaa733 100644 --- a/primitives/src/parachain.rs +++ b/primitives/src/parachain.rs @@ -31,7 +31,7 @@ use primitives::RuntimeDebug; use application_crypto::KeyTypeId; pub use polkadot_parachain::{ - Id, AccountIdConversion, ParachainDispatchOrigin, UpwardMessage, + Id, ParachainDispatchOrigin, LOWEST_USER_ID, UpwardMessage, }; /// The key type ID for a collator key. @@ -79,6 +79,65 @@ pub type ValidatorPair = validator_app::Pair; /// so we define it to be the same type as `SessionKey`. In the future it may have different crypto. pub type ValidatorSignature = validator_app::Signature; +/// Retriability for a given active para. +#[derive(Clone, Eq, PartialEq, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug))] +pub enum Retriable { + /// Ineligible for retry. This means it's either a parachain which is always scheduled anyway or + /// has been removed/swapped. + Never, + /// Eligible for retry; the associated value is the number of retries that the para already had. + WithRetries(u32), +} + +/// Type determining the active set of parachains in current block. +pub trait ActiveParas { + /// Return the active set of parachains in current block. This attempts to keep any IDs in the + /// same place between sequential blocks. It is therefore unordered. The second item in the + /// tuple is the required collator ID, if any. If `Some`, then it is invalid to include any + /// other collator's block. + /// + /// NOTE: The initial implementation simply concatenates the (ordered) set of (permanent) + /// parachain IDs with the (unordered) set of parathread IDs selected for this block. + fn active_paras() -> Vec<(Id, Option<(CollatorId, Retriable)>)>; +} + +/// Description of how often/when this parachain is scheduled for progression. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] +pub enum Scheduling { + /// Scheduled every block. + Always, + /// Scheduled dynamically (i.e. a parathread). + Dynamic, +} + +/// Information regarding a deployed parachain/thread. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] +pub struct Info { + /// Scheduling info. + pub scheduling: Scheduling, +} + +/// An `Info` value for a standard leased parachain. +pub const PARACHAIN_INFO: Info = Info { + scheduling: Scheduling::Always, +}; + +/// Auxilliary for when there's an attempt to swapped two parachains/parathreads. +pub trait SwapAux { + /// Result describing whether it is possible to swap two parachains. Doesn't mutate state. + fn ensure_can_swap(one: Id, other: Id) -> Result<(), &'static str>; + + /// Updates any needed state/references to enact a logical swap of two parachains. Identity, + /// code and head_data remain equivalent for all parachains/threads, however other properties + /// such as leases, deposits held and thread/chain nature are swapped. + /// + /// May only be called on a state that `ensure_can_swap` has previously returned `Ok` for: if this is + /// not the case, the result is undefined. May only return an error if `ensure_can_swap` also returns + /// an error. + fn on_swap(one: Id, other: Id) -> Result<(), &'static str>; +} + /// Identifier for a chain, either one of a number of parachains or the relay chain. #[derive(Copy, Clone, PartialEq, Encode, Decode)] #[cfg_attr(feature = "std", derive(Debug))] @@ -432,7 +491,7 @@ substrate_client::decl_runtime_apis! { /// Get the current duty roster. fn duty_roster() -> DutyRoster; /// Get the currently active parachains. - fn active_parachains() -> Vec; + fn active_parachains() -> Vec<(Id, Option<(CollatorId, Retriable)>)>; /// Get the given parachain's status. fn parachain_status(id: Id) -> Option; /// Get the given parachain's head code blob. diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index d4bc83e0bbc0..5cbed5a51fa5 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polkadot-rpc" -version = "0.6.0" +version = "0.6.3" authors = ["Parity Technologies "] edition = "2018" diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 15fa4012176a..208b24dbec81 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polkadot-runtime" -version = "0.6.2" +version = "0.6.3" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" @@ -14,6 +14,7 @@ safe-mix = { version = "1.0", default-features = false} serde = { version = "1.0", default-features = false } serde_derive = { version = "1.0", optional = true } +authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } babe-primitives = { package = "substrate-consensus-babe-primitives", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } client = { package = "substrate-client", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } inherents = { package = "substrate-inherents", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } @@ -27,13 +28,14 @@ substrate-serializer = { git = "https://github.com/paritytech/substrate", defaul substrate-session = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } version = { package = "sr-version", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } +authority-discovery = { package = "srml-authority-discovery", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } authorship = { package = "srml-authorship", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } babe = { package = "srml-babe", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } balances = { package = "srml-balances", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } transaction-payment = { package = "srml-transaction-payment", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } collective = { package = "srml-collective", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } democracy = { package = "srml-democracy", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } -elections = { package = "srml-elections", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } +elections-phragmen = { package = "srml-elections-phragmen", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } executive = { package = "srml-executive", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } finality-tracker = { package = "srml-finality-tracker", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } grandpa = { package = "srml-grandpa", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } @@ -53,6 +55,7 @@ timestamp = { package = "srml-timestamp", git = "https://github.com/paritytech/s treasury = { package = "srml-treasury", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } primitives = { package = "polkadot-primitives", path = "../primitives", default-features = false } +polkadot-parachain = { path = "../parachain", default-features = false } [dev-dependencies] hex-literal = "0.2.0" @@ -71,12 +74,15 @@ default = ["std"] no_std = [] only-staking = [] std = [ + "authority-discovery-primitives/std", + "authority-discovery/std", "bitvec/std", "primitives/std", "rustc-hex/std", "codec/std", "inherents/std", "substrate-primitives/std", + "polkadot-parachain/std", "client/std", "offchain-primitives/std", "rstd/std", @@ -86,7 +92,7 @@ std = [ "balances/std", "transaction-payment/std", "collective/std", - "elections/std", + "elections-phragmen/std", "democracy/std", "executive/std", "finality-tracker/std", diff --git a/runtime/src/crowdfund.rs b/runtime/src/crowdfund.rs index 718c21368853..b6a5539a3325 100644 --- a/runtime/src/crowdfund.rs +++ b/runtime/src/crowdfund.rs @@ -77,14 +77,16 @@ use sr_primitives::{ModuleId, weights::SimpleDispatchInfo, use crate::slots; use codec::{Encode, Decode}; use rstd::vec::Vec; -use crate::parachains::ParachainRegistrar; use substrate_primitives::storage::well_known_keys::CHILD_STORAGE_KEY_PREFIX; +use primitives::parachain::Id as ParaId; const MODULE_ID: ModuleId = ModuleId(*b"py/cfund"); -pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; -pub type ParaIdOf = <::Parachains as ParachainRegistrar<::AccountId>>::ParaId; +pub type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; +#[allow(dead_code)] +pub type NegativeImbalanceOf = + <::Currency as Currency<::AccountId>>::NegativeImbalance; pub trait Trait: slots::Trait { type Event: From> + Into<::Event>; @@ -117,7 +119,7 @@ pub enum LastContribution { #[derive(Encode, Decode, Clone, PartialEq, Eq)] #[cfg_attr(feature = "std", derive(Debug))] -pub struct FundInfo { +pub struct FundInfo { /// The parachain that this fund has funded, if there is one. As long as this is `Some`, then /// the funds may not be withdrawn and the fund cannot be dissolved. parachain: Option, @@ -154,7 +156,7 @@ decl_storage! { trait Store for Module as Example { /// Info on all of the funds. Funds get(funds): - map FundIndex => Option, T::Hash, T::BlockNumber, ParaIdOf>>; + map FundIndex => Option, T::Hash, T::BlockNumber>>; /// The total number of funds that have so far been allocated. FundCount get(fund_count): FundIndex; @@ -172,7 +174,6 @@ decl_event! { pub enum Event where ::AccountId, Balance = BalanceOf, - ParaId = ParaIdOf, { Created(FundIndex), Contributed(AccountId, FundIndex, Balance), @@ -321,7 +322,7 @@ decl_module! { /// - `para_id` is the parachain index that this fund won. fn onboard(origin, #[compact] index: FundIndex, - #[compact] para_id: ParaIdOf + #[compact] para_id: ParaId ) { let _ = ensure_signed(origin)?; @@ -502,13 +503,14 @@ mod tests { use std::{collections::HashMap, cell::RefCell}; use srml_support::{impl_outer_origin, assert_ok, assert_noop, parameter_types}; use substrate_primitives::H256; - use primitives::parachain::Id as ParaId; + use primitives::parachain::{Info as ParaInfo, Id as ParaId}; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried. use sr_primitives::{ Perbill, Permill, testing::Header, traits::{BlakeTwo256, OnInitialize, OnFinalize, IdentityLookup}, }; + use crate::registrar::Registrar; impl_outer_origin! { pub enum Origin for Test {} @@ -587,33 +589,33 @@ mod tests { } pub struct TestParachains; - impl ParachainRegistrar for TestParachains { - type ParaId = ParaId; - fn new_id() -> Self::ParaId { + impl Registrar for TestParachains { + fn new_id() -> ParaId { PARACHAIN_COUNT.with(|p| { *p.borrow_mut() += 1; (*p.borrow() - 1).into() }) } - fn register_parachain( - id: Self::ParaId, + fn register_para( + id: ParaId, + _info: ParaInfo, code: Vec, initial_head_data: Vec ) -> Result<(), &'static str> { PARACHAINS.with(|p| { - if p.borrow().contains_key(&id.into_inner()) { + if p.borrow().contains_key(&id.into()) { panic!("ID already exists") } - p.borrow_mut().insert(id.into_inner(), (code, initial_head_data)); + p.borrow_mut().insert(id.into(), (code, initial_head_data)); Ok(()) }) } - fn deregister_parachain(id: Self::ParaId) -> Result<(), &'static str> { + fn deregister_para(id: ParaId) -> Result<(), &'static str> { PARACHAINS.with(|p| { - if !p.borrow().contains_key(&id.into_inner()) { + if !p.borrow().contains_key(&id.into()) { panic!("ID doesn't exist") } - p.borrow_mut().remove(&id.into_inner()); + p.borrow_mut().remove(&id.into()); Ok(()) }) } diff --git a/runtime/src/impls.rs b/runtime/src/impls.rs index 632ae49f78bd..e322befe533d 100644 --- a/runtime/src/impls.rs +++ b/runtime/src/impls.rs @@ -19,10 +19,9 @@ use primitives::Balance; use sr_primitives::weights::Weight; use sr_primitives::traits::{Convert, Saturating}; -use sr_primitives::Fixed64; -use srml_support::traits::{OnUnbalanced, Currency}; -use crate::{Balances, Authorship, MaximumBlockWeight, NegativeImbalance}; -use crate::constants::fee::TARGET_BLOCK_FULLNESS; +use sr_primitives::{Fixed64, Perbill}; +use srml_support::traits::{OnUnbalanced, Currency, Get}; +use crate::{Balances, System, Authorship, MaximumBlockWeight, NegativeImbalance}; /// Logic for the author to get a portion of fees. pub struct ToAuthor; @@ -67,27 +66,21 @@ impl Convert for WeightToFee { } } -/// A struct that updates the weight multiplier based on the saturation level of the previous block. -/// This should typically be called once per-block. +/// Update the given multiplier based on the following formula /// -/// This assumes that weight is a numeric value in the u32 range. -/// -/// Given `TARGET_BLOCK_FULLNESS = 1/2`, a block saturation greater than 1/2 will cause the system -/// fees to slightly grow and the opposite for block saturations less than 1/2. -/// -/// Formula: -/// diff = (target_weight - current_block_weight) +/// diff = (target_weight - previous_block_weight) /// v = 0.00004 /// next_weight = weight * (1 + (v . diff) + (v . diff)^2 / 2) /// +/// Where `target_weight` must be given as the `Get` implementation of the `T` generic type. /// https://research.web3.foundation/en/latest/polkadot/Token%20Economics/#relay-chain-transaction-fees -pub struct FeeMultiplierUpdateHandler; +pub struct TargetedFeeAdjustment(rstd::marker::PhantomData); -impl Convert<(Weight, Fixed64), Fixed64> for FeeMultiplierUpdateHandler { - fn convert(previous_state: (Weight, Fixed64)) -> Fixed64 { - let (block_weight, multiplier) = previous_state; +impl> Convert for TargetedFeeAdjustment { + fn convert(multiplier: Fixed64) -> Fixed64 { + let block_weight = System::all_extrinsics_weight(); let max_weight = MaximumBlockWeight::get(); - let target_weight = (TARGET_BLOCK_FULLNESS * max_weight) as u128; + let target_weight = (T::get() * max_weight) as u128; let block_weight = block_weight as u128; // determines if the first_term is positive @@ -99,8 +92,8 @@ impl Convert<(Weight, Fixed64), Fixed64> for FeeMultiplierUpdateHandler { // 0.00004 = 4/100_000 = 40_000/10^9 let v = Fixed64::from_rational(4, 100_000); - // 0.00004^2 = 16/10^10 ~= 2/10^9. Taking the future /2 into account, then it is just 1 parts - // from a billionth. + // 0.00004^2 = 16/10^10 ~= 2/10^9. Taking the future /2 into account, then it is just 1 + // parts from a billionth. let v_squared_2 = Fixed64::from_rational(1, 1_000_000_000); let first_term = v.saturating_mul(diff); diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 942f58b2da7b..f80cd778a147 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -24,15 +24,16 @@ mod attestations; mod claims; mod parachains; mod slot_range; +mod registrar; mod slots; mod crowdfund; use rstd::prelude::*; -use codec::{Encode, Decode}; use substrate_primitives::u32_trait::{_1, _2, _3, _4}; +use codec::{Encode, Decode}; use primitives::{ AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, - parachain, ValidityError, + parachain::{self, ActiveParas}, ValidityError, }; use client::{ block_builder::api::{self as block_builder_api, InherentData, CheckInherentsResult}, @@ -47,8 +48,7 @@ use sr_primitives::{ }; use version::RuntimeVersion; use grandpa::{AuthorityId as GrandpaId, fg_primitives}; -use babe_primitives::AuthorityId as BabeId; -use elections::VoteIndex; +use babe_primitives::{AuthorityId as BabeId}; #[cfg(any(feature = "std", test))] use version::NativeVersion; use substrate_primitives::OpaqueMetadata; @@ -56,7 +56,7 @@ use sr_staking_primitives::SessionIndex; use srml_support::{ parameter_types, construct_runtime, traits::{SplitTwoWays, Currency, Randomness} }; -use im_online::sr25519::{AuthorityId as ImOnlineId}; +use im_online::sr25519::AuthorityId as ImOnlineId; use system::offchain::TransactionSubmitter; #[cfg(feature = "std")] @@ -67,11 +67,10 @@ pub use timestamp::Call as TimestampCall; pub use balances::Call as BalancesCall; pub use attestations::{Call as AttestationsCall, MORE_ATTESTATIONS_IDENTIFIER}; pub use parachains::{Call as ParachainsCall, NEW_HEADS_IDENTIFIER}; -pub use srml_support::StorageValue; /// Implementations of some helper traits passed into runtime modules as associated types. pub mod impls; -use impls::{CurrencyToVoteHandler, FeeMultiplierUpdateHandler, ToAuthor, WeightToFee}; +use impls::{CurrencyToVoteHandler, TargetedFeeAdjustment, ToAuthor, WeightToFee}; /// Constant values used within the runtime. pub mod constants; @@ -130,7 +129,9 @@ impl SignedExtension for OnlyStakingAndClaims { -> TransactionValidity { match call { - Call::Staking(_) | Call::Claims(_) | Call::Sudo(_) | Call::Session(_) => + Call::Staking(_) | Call::Claims(_) | Call::Sudo(_) | Call::Session(_) + | Call::ElectionsPhragmen(_) + => Ok(Default::default()), _ => Err(InvalidTransaction::Custom(ValidityError::NoPermission.into()).into()), } @@ -186,7 +187,7 @@ impl indices::Trait for Runtime { } parameter_types! { - pub const ExistentialDeposit: Balance = 10 * CENTS; + pub const ExistentialDeposit: Balance = 100 * CENTS; pub const TransferFee: Balance = 1 * CENTS; pub const CreationFee: Balance = 1 * CENTS; } @@ -214,6 +215,8 @@ impl balances::Trait for Runtime { parameter_types! { pub const TransactionBaseFee: Balance = 1 * CENTS; pub const TransactionByteFee: Balance = 10 * MILLICENTS; + // for a sane configuration, this should always be less than `AvailableBlockRatio`. + pub const TargetBlockFullness: Perbill = Perbill::from_percent(25); } impl transaction_payment::Trait for Runtime { @@ -222,13 +225,12 @@ impl transaction_payment::Trait for Runtime { type TransactionBaseFee = TransactionBaseFee; type TransactionByteFee = TransactionByteFee; type WeightToFee = WeightToFee; - type FeeMultiplierUpdate = FeeMultiplierUpdateHandler; + type FeeMultiplierUpdate = TargetedFeeAdjustment; } parameter_types! { pub const MinimumPeriod: u64 = SLOT_DURATION / 2; } - impl timestamp::Trait for Runtime { type Moment = u64; type OnTimestampSet = Babe; @@ -252,6 +254,9 @@ parameter_types! { pub const Offset: BlockNumber = 0; } +// !!!!!!!!!!!!! +// WARNING!!!!!! SEE NOTE BELOW BEFORE TOUCHING THIS CODE +// !!!!!!!!!!!!! type SessionHandlers = (Grandpa, Babe, ImOnline, Parachains); impl_opaque_keys! { pub struct SessionKeys { @@ -265,7 +270,6 @@ impl_opaque_keys! { pub parachain_validator: parachain::ValidatorId, } } - // NOTE: `SessionHandler` and `SessionKeys` are co-dependent: One key will be used for each handler. // The number and order of items in `SessionHandler` *MUST* be the same number and order of keys in // `SessionKeys`. @@ -282,15 +286,15 @@ impl session::Trait for Runtime { type ShouldEndSession = Babe; type Event = Event; type Keys = SessionKeys; - type SelectInitialValidators = Staking; type ValidatorId = AccountId; type ValidatorIdOf = staking::StashOf; + type SelectInitialValidators = Staking; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; } impl session::historical::Trait for Runtime { type FullIdentification = staking::Exposure; - type FullIdentificationOf = staking::ExposureOf; + type FullIdentificationOf = staking::ExposureOf; } srml_staking_reward_curve::build! { @@ -370,35 +374,20 @@ impl collective::Trait for Runtime { } parameter_types! { - pub const CandidacyBond: Balance = 10 * DOLLARS; - pub const VotingBond: Balance = 1 * DOLLARS; - pub const VotingFee: Balance = 2 * DOLLARS; - pub const MinimumVotingLock: Balance = 1 * DOLLARS; - pub const PresentSlashPerVoter: Balance = 1 * CENTS; - pub const CarryCount: u32 = 6; - // one additional vote should go by before an inactive voter can be reaped. - pub const InactiveGracePeriod: VoteIndex = 1; - pub const ElectionsVotingPeriod: BlockNumber = 2 * DAYS; - pub const DecayRatio: u32 = 0; -} - -impl elections::Trait for Runtime { + pub const CandidacyBond: Balance = 100 * DOLLARS; + pub const VotingBond: Balance = 5 * DOLLARS; +} + +impl elections_phragmen::Trait for Runtime { type Event = Event; type Currency = Balances; - type BadPresentation = (); - type BadReaper = (); - type BadVoterIndex = (); - type LoserCandidate = (); type ChangeMembers = Council; + type CurrencyToVote = CurrencyToVoteHandler; type CandidacyBond = CandidacyBond; type VotingBond = VotingBond; - type VotingFee = VotingFee; - type MinimumVotingLock = MinimumVotingLock; - type PresentSlashPerVoter = PresentSlashPerVoter; - type CarryCount = CarryCount; - type InactiveGracePeriod = InactiveGracePeriod; - type VotingPeriod = ElectionsVotingPeriod; - type DecayRatio = DecayRatio; + type LoserCandidate = Treasury; + type BadReport = Treasury; + type KickedMember = Treasury; } type TechnicalCollective = collective::Instance2; @@ -484,6 +473,24 @@ impl parachains::Trait for Runtime { type Call = Call; type ParachainCurrency = Balances; type Randomness = RandomnessCollectiveFlip; + type ActiveParachains = Registrar; + type Registrar = Registrar; +} + +parameter_types! { + pub const ParathreadDeposit: Balance = 500 * DOLLARS; + pub const QueueSize: usize = 2; + pub const MaxRetries: u32 = 3; +} + +impl registrar::Trait for Runtime { + type Event = Event; + type Origin = Origin; + type Currency = Balances; + type ParathreadDeposit = ParathreadDeposit; + type SwapAux = Slots; + type QueueSize = QueueSize; + type MaxRetries = MaxRetries; } parameter_types!{ @@ -493,8 +500,8 @@ parameter_types!{ impl slots::Trait for Runtime { type Event = Event; - type Currency = balances::Module; - type Parachains = parachains::Module; + type Currency = Balances; + type Parachains = Registrar; type LeasePeriod = LeasePeriod; type EndingPeriod = EndingPeriod; type Randomness = RandomnessCollectiveFlip; @@ -549,7 +556,7 @@ construct_runtime!( Democracy: democracy::{Module, Call, Storage, Config, Event}, Council: collective::::{Module, Call, Storage, Origin, Event, Config}, TechnicalCommittee: collective::::{Module, Call, Storage, Origin, Event, Config}, - Elections: elections::{Module, Call, Storage, Event, Config}, + ElectionsPhragmen: elections_phragmen::{Module, Call, Storage, Event, Config}, TechnicalMembership: membership::::{Module, Call, Storage, Event, Config}, Treasury: treasury::{Module, Call, Storage, Event}, @@ -558,9 +565,10 @@ construct_runtime!( // Parachains stuff; slots are disabled (no auctions initially). The rest are safe as they // have no public dispatchables. - Parachains: parachains::{Module, Call, Storage, Config, Inherent, Origin}, + Parachains: parachains::{Module, Call, Storage, Config, Inherent, Origin}, Attestations: attestations::{Module, Call, Storage}, Slots: slots::{Module, Call, Storage, Event}, + Registrar: registrar::{Module, Call, Storage, Event, Config}, // Sudo. Usable initially. // RELEASE: remove this for release build. @@ -588,6 +596,7 @@ pub type SignedExtra = ( system::CheckNonce, system::CheckWeight, transaction_payment::ChargeTransactionPayment::, + registrar::LimitParathreadCommits ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; @@ -658,8 +667,8 @@ impl_runtime_apis! { fn duty_roster() -> parachain::DutyRoster { Parachains::calculate_duty_roster().0 } - fn active_parachains() -> Vec { - Parachains::active_parachains() + fn active_parachains() -> Vec<(parachain::Id, Option<(parachain::CollatorId, parachain::Retriable)>)> { + Registrar::active_paras() } fn parachain_status(id: parachain::Id) -> Option { Parachains::parachain_status(&id) diff --git a/runtime/src/parachains.rs b/runtime/src/parachains.rs index ab07ad04821c..7eb6d079d3ac 100644 --- a/runtime/src/parachains.rs +++ b/runtime/src/parachains.rs @@ -17,22 +17,23 @@ //! Main parachains logic. For now this is just the determination of which validators do what. use rstd::prelude::*; +use rstd::result; use rstd::collections::btree_map::BTreeMap; -use codec::{Encode, Decode, HasCompact}; -use srml_support::{decl_storage, decl_module, fail, ensure}; +use codec::{Encode, Decode}; +use srml_support::{decl_storage, decl_module, ensure}; use sr_primitives::traits::{ - Hash as HashT, BlakeTwo256, Member, CheckedConversion, Saturating, One, Zero, Dispatchable, + Hash as HashT, BlakeTwo256, Saturating, One, Zero, Dispatchable, + AccountIdConversion, }; use sr_primitives::weights::SimpleDispatchInfo; use primitives::{ Hash, Balance, parachain::{ - self, Id as ParaId, Chain, DutyRoster, AttestedCandidate, Statement, AccountIdConversion, - ParachainDispatchOrigin, UpwardMessage, BlockIngressRoots, ValidatorId - } + self, Id as ParaId, Chain, DutyRoster, AttestedCandidate, Statement, ParachainDispatchOrigin, + UpwardMessage, BlockIngressRoots, ValidatorId, ActiveParas, CollatorId, Retriable + }, }; -use {system, session}; use srml_support::{ Parameter, dispatch::Result, traits::{Currency, Get, WithdrawReason, ExistenceRequirement, Randomness}, @@ -40,11 +41,9 @@ use srml_support::{ use inherents::{ProvideInherent, InherentData, RuntimeString, MakeFatalError, InherentIdentifier}; -#[cfg(any(feature = "std", test))] -use rstd::marker::PhantomData; - -use system::{ensure_none, ensure_root}; +use system::ensure_none; use crate::attestations::{self, IncludedBlocks}; +use crate::registrar::Registrar; // ranges for iteration of general block number don't work, so this // is a utility to get around that. @@ -72,75 +71,6 @@ fn number_range(low: N, high: N) -> BlockNumberRange { BlockNumberRange { low, high } } -/// Parachain registration API. -pub trait ParachainRegistrar { - /// An identifier for a parachain. - type ParaId: Member + Parameter + Default + AccountIdConversion + Copy + HasCompact; - - /// Create a new unique parachain identity for later registration. - fn new_id() -> Self::ParaId; - - /// Register a parachain with given `code` and `initial_head_data`. `id` must not yet be registered or it will - /// result in a error. - fn register_parachain(id: Self::ParaId, code: Vec, initial_head_data: Vec) -> Result; - - /// Deregister a parachain with given `id`. If `id` is not currently registered, an error is returned. - fn deregister_parachain(id: Self::ParaId) -> Result; -} - -impl ParachainRegistrar for Module { - type ParaId = ParaId; - fn new_id() -> ParaId { - ::mutate(|n| { let r = *n; *n = ParaId::from(u32::from(*n) + 1); r }) - } - fn register_parachain(id: ParaId, code: Vec, initial_head_data: Vec) -> Result { - let mut parachains = Self::active_parachains(); - match parachains.binary_search(&id) { - Ok(_) => fail!("Parachain already exists"), - Err(idx) => parachains.insert(idx, id), - } - - ::insert(id, code); - ::put(parachains); - ::insert(id, initial_head_data); - - // Because there are no ordering guarantees that inherents - // are applied before regular transactions, a parachain candidate could - // be registered before the `UpdateHeads` inherent is processed. If so, messages - // could be sent to a parachain in the block it is registered. - >::insert(id, >::block_number().saturating_sub(One::one())); - - Ok(()) - } - fn deregister_parachain(id: ParaId) -> Result { - let mut parachains = Self::active_parachains(); - match parachains.binary_search(&id) { - Ok(idx) => { parachains.remove(idx); } - Err(_) => return Ok(()), - } - - ::remove(id); - ::remove(id); - - let watermark = >::take(id); - - // clear all routing entries _to_. But not those _from_. - if let Some(watermark) = watermark { - let now = >::block_number(); - - // iterate over all blocks between watermark and now + 1 (since messages might - // have already been sent to `id` in this block. - for unrouted_block in number_range(watermark, now).map(|n| n.saturating_add(One::one())) { - >::remove(&(unrouted_block, id)); - } - } - - ::put(parachains); - - Ok(()) - } -} - // wrapper trait because an associated type of `Currency` // doesn't work.` pub trait ParachainCurrency { @@ -193,6 +123,12 @@ pub trait Trait: attestations::Trait { /// Something that provides randomness in the runtime. type Randomness: Randomness; + + /// Means to determine what the current set of active parachains are. + type ActiveParachains: ActiveParas; + + /// The way that we are able to register parachains. + type Registrar: Registrar; } /// Origin for the parachains module. @@ -219,9 +155,7 @@ const WATERMARK_QUEUE_SIZE: usize = 20000; decl_storage! { trait Store for Module as Parachains { /// All authorities' keys at the moment. - pub Authorities get(authorities) config(authorities): Vec; - /// Vector of all parachain IDs. - pub Parachains get(active_parachains): Vec; + pub Authorities get(authorities): Vec; /// The parachains registered at present. pub Code get(parachain_code): map ParaId => Option>; /// The heads of the parachains registered at present. @@ -244,35 +178,18 @@ decl_storage! { /// decoding when checking receipt validity. First item in tuple is the count of messages /// second if the total length (in bytes) of the message payloads. pub RelayDispatchQueueSize: map ParaId => (u32, u32); + /// The ordered list of ParaIds that have a `RelayDispatchQueue` entry. + NeedsDispatch: Vec; - /// Did the parachain heads get updated in this block? - DidUpdate: bool; - - /// The next unused ParaId value. - NextFreeId: ParaId; + /// Some if the parachain heads get updated in this block, along with the parachain IDs that + /// did update. Ordered in the same way as `registrar::Active` (i.e. by ParaId). + /// + /// None if not yet updated. + pub DidUpdate: Option>; } add_extra_genesis { - config(parachains): Vec<(ParaId, Vec, Vec)>; - config(_phdata): PhantomData; - build(build::); - } -} - -#[cfg(feature = "std")] -fn build(config: &GenesisConfig) { - let mut p = config.parachains.clone(); - p.sort_unstable_by_key(|&(ref id, _, _)| *id); - p.dedup_by_key(|&mut (ref id, _, _)| *id); - - let only_ids: Vec = p.iter().map(|&(ref id, _, _)| id).cloned().collect(); - - Parachains::put(&only_ids); - - for (id, code, genesis) in p { - // no ingress -- a chain cannot be routed to until it is live. - Code::insert(&id, &code); - Heads::insert(&id, &genesis); - >::insert(&id, T::BlockNumber::zero()); + config(authorities): Vec; + build(|config| Module::::initialize_authorities(&config.authorities)) } } @@ -281,32 +198,38 @@ decl_module! { pub struct Module for enum Call where origin: ::Origin { /// Provide candidate receipts for parachains, in ascending order by id. #[weight = SimpleDispatchInfo::FixedNormal(1_000_000)] - fn set_heads(origin, heads: Vec) -> Result { + pub fn set_heads(origin, heads: Vec) -> Result { ensure_none(origin)?; ensure!(!::exists(), "Parachain heads must be updated only once in the block"); let active_parachains = Self::active_parachains(); + let parachain_count = active_parachains.len(); ensure!(heads.len() <= parachain_count, "Too many parachain candidates"); + let mut proceeded = Vec::with_capacity(heads.len()); + if !active_parachains.is_empty() { // perform integrity checks before writing to storage. { let mut last_id = None; + let mut iter = active_parachains.iter(); for head in &heads { let id = head.parachain_index(); // proposed heads must be ascending order by parachain ID without duplicate. ensure!( last_id.as_ref().map_or(true, |x| x < &id), - "Parachain candidates out of order by ID" + "candidate out of order" ); // must be unknown since active parachains are always sorted. - ensure!( - iter.find(|x| x == &&id).is_some(), - "Submitted candidate for unregistered or out-of-order parachain {}" - ); + let (_, maybe_required_collator) = iter.find(|para| para.0 == id) + .ok_or("candidate for unregistered parachain {}")?; + + if let Some((required_collator, _)) = maybe_required_collator { + ensure!(required_collator == &head.candidate.collator, "invalid collator"); + } Self::check_upward_messages( id, @@ -316,7 +239,9 @@ decl_module! { )?; Self::check_egress_queue_roots(&head, &active_parachains)?; - last_id = Some(head.parachain_index()); + let id = head.parachain_index(); + proceeded.push(id); + last_id = Some(id); } } @@ -331,36 +256,23 @@ decl_module! { ); Self::dispatch_upward_messages( - current_number, - &active_parachains, MAX_QUEUE_COUNT, WATERMARK_QUEUE_SIZE, Self::dispatch_message, ); } - ::put(true); + DidUpdate::put(proceeded); Ok(()) } - /// Register a parachain with given code. - /// Fails if given ID is already used. - #[weight = SimpleDispatchInfo::FixedOperational(5_000_000)] - pub fn register_parachain(origin, id: ParaId, code: Vec, initial_head_data: Vec) -> Result { - ensure_root(origin)?; - >::register_parachain(id, code, initial_head_data) + fn on_initialize() { + ::DidUpdate::kill(); } - /// Deregister a parachain with given id - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] - pub fn deregister_parachain(origin, id: ParaId) -> Result { - ensure_root(origin)?; - >::deregister_parachain(id) - } - - fn on_finalize(_n: T::BlockNumber) { - assert!(::DidUpdate::take(), "Parachain heads must be updated once in the block"); + fn on_finalize() { + assert!(::DidUpdate::exists(), "Parachain heads must be updated once in the block"); } } } @@ -376,6 +288,42 @@ fn localized_payload(statement: Statement, parent_hash: ::primitives::Hash) -> V } impl Module { + /// Initialize the state of a new parachain/parathread. + pub fn initialize_para( + id: ParaId, + code: Vec, + initial_head_data: Vec, + ) { + ::insert(id, code); + ::insert(id, initial_head_data); + + // Because there are no ordering guarantees that inherents + // are applied before regular transactions, a parachain candidate could + // be registered before the `UpdateHeads` inherent is processed. If so, messages + // could be sent to a parachain in the block it is registered. + >::insert(id, >::block_number().saturating_sub(One::one())); + } + + pub fn cleanup_para( + id: ParaId, + ) { + ::remove(id); + ::remove(id); + + let watermark = >::take(id); + + // clear all routing entries _to_. But not those _from_. + if let Some(watermark) = watermark { + let now = >::block_number(); + + // iterate over all blocks between watermark and now + 1 (since messages might + // have already been sent to `id` in this block. + for unrouted_block in number_range(watermark, now).map(|n| n.saturating_add(One::one())) { + >::remove(&(unrouted_block, id)); + } + } + } + /// Dispatch some messages from a parachain. fn dispatch_message( id: ParaId, @@ -388,6 +336,8 @@ impl Module { system::RawOrigin::Signed(id.into_account()).into(), ParachainDispatchOrigin::Parachain => Origin::Parachain(id).into(), + ParachainDispatchOrigin::Root => + system::RawOrigin::Root.into(), }; let _ok = message_call.dispatch(origin).is_ok(); // Not much to do with the result as it is. It's up to the parachain to ensure that the @@ -422,6 +372,11 @@ impl Module { ), "Messages added when queue full" ); + if !id.is_system() { + for m in upward_messages.iter() { + ensure!(m.origin != ParachainDispatchOrigin::Root, "bad message origin"); + } + } } Ok(()) } @@ -438,6 +393,10 @@ impl Module { let mut ingress_update = BTreeMap::new(); + // we sort them in order to provide a fast lookup to ensure we can avoid duplicates in the + // needs_dispatch queue. + let mut ordered_needs_dispatch = NeedsDispatch::get(); + for head in heads.iter() { let id = head.parachain_index(); ::insert(id, &head.candidate.head_data.0); @@ -459,9 +418,15 @@ impl Module { } // Queue up upwards messages (from parachains to relay chain). - Self::queue_upward_messages(id, &head.candidate.upward_messages); + Self::queue_upward_messages( + id, + &head.candidate.upward_messages, + &mut ordered_needs_dispatch, + ); } + NeedsDispatch::put(ordered_needs_dispatch); + // apply the ingress update. for (to, ingress_roots) in ingress_update { >::insert((now, to), ingress_roots); @@ -469,36 +434,46 @@ impl Module { } /// Place any new upward messages into our queue for later dispatch. - fn queue_upward_messages(id: ParaId, upward_messages: &[UpwardMessage]) { + /// + /// `ordered_needs_dispatch` is mutated to ensure it reflects the new value of + /// `RelayDispatchQueueSize`. It is up to the caller to guarantee that it gets written into + /// storage after this call. + fn queue_upward_messages( + id: ParaId, + upward_messages: &[UpwardMessage], + ordered_needs_dispatch: &mut Vec, + ) { if !upward_messages.is_empty() { - ::mutate(id, |&mut(ref mut count, ref mut len)| { + RelayDispatchQueueSize::mutate(id, |&mut(ref mut count, ref mut len)| { *count += upward_messages.len() as u32; *len += upward_messages.iter() .fold(0, |a, x| a + x.data.len()) as u32; }); // Should never be able to fail assuming our state is uncorrupted, but best not // to panic, even if it does. - let _ = ::append(id, upward_messages); + let _ = RelayDispatchQueue::append(id, upward_messages); + if let Err(i) = ordered_needs_dispatch.binary_search(&id) { + // same. + ordered_needs_dispatch.insert(i, id); + } else { + sr_primitives::print("ordered_needs_dispatch contains id?!"); + } } } - /// Simple round-robin dispatcher, using block number modulo parachain count - /// to decide which takes precedence and proceeding from there. + /// Simple FIFO dispatcher. fn dispatch_upward_messages( - now: T::BlockNumber, - active_parachains: &[ParaId], max_queue_count: usize, watermark_queue_size: usize, mut dispatch_message: impl FnMut(ParaId, ParachainDispatchOrigin, &[u8]), ) { - let para_count = active_parachains.len(); - let offset = (now % T::BlockNumber::from(para_count as u32)) - .checked_into::() - .expect("value is modulo a usize value; qed"); - + let queueds = NeedsDispatch::get(); + let mut drained_count = 0usize; let mut dispatched_count = 0usize; let mut dispatched_size = 0usize; - for id in active_parachains.iter().cycle().skip(offset).take(para_count) { + for id in queueds.iter() { + drained_count += 1; + let (count, size) = ::get(id); let count = count as usize; let size = size as usize; @@ -508,8 +483,8 @@ impl Module { ) { if count > 0 { // still dispatching messages... - ::remove(id); - let messages = ::take(id); + RelayDispatchQueueSize::remove(id); + let messages = RelayDispatchQueue::take(id); for UpwardMessage { origin, data } in messages.into_iter() { dispatch_message(*id, origin, &data); } @@ -523,6 +498,7 @@ impl Module { } } } + NeedsDispatch::put(&queueds[drained_count..]); } /// Calculate the current block's duty roster using system's random seed. @@ -530,19 +506,24 @@ impl Module { pub fn calculate_duty_roster() -> (DutyRoster, [u8; 32]) { let parachains = Self::active_parachains(); let parachain_count = parachains.len(); + // TODO: use decode length. substrate #2794 let validator_count = Self::authorities().len(); - let validators_per_parachain = if parachain_count != 0 { (validator_count - 1) / parachain_count } else { 0 }; + let validators_per_parachain = + if parachain_count == 0 { + 0 + } else { + (validator_count - 1) / parachain_count + }; let mut roles_val = (0..validator_count).map(|i| match i { i if i < parachain_count * validators_per_parachain => { let idx = i / validators_per_parachain; - Chain::Parachain(parachains[idx].clone()) + Chain::Parachain(parachains[idx].0.clone()) } _ => Chain::Relay, }).collect::>(); - let mut seed = { let phrase = b"validator_role_pairs"; let seed = T::Randomness::random(&phrase[..]); @@ -628,9 +609,17 @@ impl Module { }) } - fn check_egress_queue_roots(head: &AttestedCandidate, active_parachains: &[ParaId]) -> Result { + /// Get the currently active set of parachains. + pub fn active_parachains() -> Vec<(ParaId, Option<(CollatorId, Retriable)>)> { + T::ActiveParachains::active_paras() + } + + fn check_egress_queue_roots( + head: &AttestedCandidate, + active_parachains: &[(ParaId, Option<(CollatorId, Retriable)>)] + ) -> Result { let mut last_egress_id = None; - let mut iter = active_parachains.iter(); + let mut iter = active_parachains.iter().map(|x| x.0); for (egress_para_id, root) in &head.candidate.egress_queue_roots { // egress routes should be ascending order by parachain ID without duplicate. ensure!( @@ -652,7 +641,7 @@ impl Module { // can't route to a parachain which doesn't exist ensure!( - iter.find(|x| x == &egress_para_id).is_some(), + iter.find(|x| x == egress_para_id).is_some(), "Routing to non-existent parachain" ); @@ -663,8 +652,10 @@ impl Module { // check the attestations on these candidates. The candidates should have been checked // that each candidates' chain ID is valid. - fn check_candidates(attested_candidates: &[AttestedCandidate], active_parachains: &[ParaId]) - -> rstd::result::Result, &'static str> + fn check_candidates( + attested_candidates: &[AttestedCandidate], + active_parachains: &[(ParaId, Option<(CollatorId, Retriable)>)] + ) -> rstd::result::Result, &'static str> { use primitives::parachain::ValidityAttestation; use sr_primitives::traits::AppVerify; @@ -822,11 +813,18 @@ impl Module { actual_number: >::block_number(), session: >::current_index(), random_seed, - active_parachains: active_parachains.to_vec(), + active_parachains: active_parachains.iter().map(|x| x.0).collect(), para_blocks: para_block_hashes, }) } + fn initialize_authorities(authorities: &[ValidatorId]) { + if !authorities.is_empty() { + assert!(Authorities::get().is_empty(), "Authorities are already initialized!"); + Authorities::put(authorities); + } + } + /* // TODO: Consider integrating if needed. (https://github.com/paritytech/polkadot/issues/223) /// Extract the parachain heads from the block. @@ -850,14 +848,14 @@ impl session::OneSessionHandler for Module { fn on_genesis_session<'a, I: 'a>(validators: I) where I: Iterator { - ::Authorities::put(&validators.map(|(_, key)| key).collect::>()) + Self::initialize_authorities(&validators.map(|(_, key)| key).collect::>()); } fn on_new_session<'a, I: 'a>(changed: bool, validators: I, _queued: I) where I: Iterator { if changed { - Self::on_genesis_session(validators) + ::Authorities::put(validators.map(|(_, key)| key).collect::>()); } } @@ -884,6 +882,17 @@ impl ProvideInherent for Module { } } +/// Ensure that the origin `o` represents a parachain. +/// Returns `Ok` with the parachain ID that effected the extrinsic or an `Err` otherwise. +pub fn ensure_parachain(o: OuterOrigin) -> result::Result + where OuterOrigin: Into> +{ + match o.into() { + Ok(Origin::Parachain(id)) => Ok(id), + _ => Err("bad origin: expected to be a parachain origin"), + } +} + #[cfg(test)] mod tests { use super::*; @@ -894,12 +903,12 @@ mod tests { use substrate_trie::NodeCodec; use sr_primitives::{ Perbill, - traits::{BlakeTwo256, IdentityLookup, OnInitialize}, + traits::{BlakeTwo256, IdentityLookup, OnInitialize, OnFinalize}, testing::{UintAuthorityId, Header}, curve::PiecewiseLinear, }; use primitives::{ - parachain::{CandidateReceipt, HeadData, ValidityAttestation, ValidatorId}, + parachain::{CandidateReceipt, HeadData, ValidityAttestation, ValidatorId, Info as ParaInfo, Scheduling}, BlockNumber, }; use crate::constants::time::*; @@ -908,6 +917,8 @@ mod tests { impl_outer_origin, impl_outer_dispatch, assert_ok, assert_err, parameter_types, }; use crate::parachains; + use crate::registrar; + use crate::slots; impl_outer_origin! { pub enum Origin for Test { @@ -1048,16 +1059,49 @@ mod tests { type RewardAttestation = (); } + parameter_types!{ + pub const LeasePeriod: u64 = 10; + pub const EndingPeriod: u64 = 3; + } + + impl slots::Trait for Test { + type Event = (); + type Currency = balances::Module; + type Parachains = registrar::Module; + type EndingPeriod = EndingPeriod; + type LeasePeriod = LeasePeriod; + type Randomness = RandomnessCollectiveFlip; + } + + parameter_types! { + pub const ParathreadDeposit: Balance = 10; + pub const QueueSize: usize = 2; + pub const MaxRetries: u32 = 3; + } + + impl registrar::Trait for Test { + type Event = (); + type Origin = Origin; + type Currency = balances::Module; + type ParathreadDeposit = ParathreadDeposit; + type SwapAux = slots::Module; + type QueueSize = QueueSize; + type MaxRetries = MaxRetries; + } + impl Trait for Test { type Origin = Origin; type Call = Call; type ParachainCurrency = balances::Module; type Randomness = RandomnessCollectiveFlip; + type ActiveParachains = registrar::Module; + type Registrar = registrar::Module; } type Parachains = Module; type System = system::Module; type RandomnessCollectiveFlip = randomness_collective_flip::Module; + type Registrar = registrar::Module; fn new_test_ext(parachains: Vec<(ParaId, Vec, Vec)>) -> TestExternalities { use staking::StakerStatus; @@ -1097,9 +1141,12 @@ mod tests { let balances: Vec<_> = (0..authority_keys.len()).map(|i| (i as u64, 10_000_000)).collect(); - GenesisConfig:: { - parachains, + GenesisConfig { authorities: authorities.clone(), + }.assimilate_storage::(&mut t).unwrap(); + + registrar::GenesisConfig:: { + parachains, _phdata: Default::default(), }.assimilate_storage(&mut t).unwrap(); @@ -1218,6 +1265,32 @@ mod tests { } } + fn init_block() { + println!("Initializing {}", System::block_number()); + System::on_initialize(System::block_number()); + Registrar::on_initialize(System::block_number()); + Parachains::on_initialize(System::block_number()); + } + fn run_to_block(n: u64) { + println!("Running until block {}", n); + while System::block_number() < n { + if System::block_number() > 1 { + println!("Finalizing {}", System::block_number()); + Parachains::on_finalize(System::block_number()); + Registrar::on_finalize(System::block_number()); + System::on_finalize(System::block_number()); + } + System::set_block_number(System::block_number() + 1); + init_block(); + } + } + + fn queue_upward_messages(id: ParaId, upward_messages: &[UpwardMessage]) { + NeedsDispatch::mutate(|nd| + Parachains::queue_upward_messages(id, upward_messages, nd) + ); + } + #[test] fn check_dispatch_upward_works() { let parachains = vec![ @@ -1226,16 +1299,16 @@ mod tests { (2u32.into(), vec![], vec![]), ]; new_test_ext(parachains.clone()).execute_with(|| { - let parachains = vec![0.into(), 1.into(), 2.into()]; - Parachains::queue_upward_messages(0.into(), &vec![ + init_block(); + queue_upward_messages(0.into(), &vec![ UpwardMessage { origin: ParachainDispatchOrigin::Parachain, data: vec![0; 4] } ]); - Parachains::queue_upward_messages(1.into(), &vec![ + queue_upward_messages(1.into(), &vec![ UpwardMessage { origin: ParachainDispatchOrigin::Parachain, data: vec![1; 4] } ]); let mut dispatched: Vec<(ParaId, ParachainDispatchOrigin, Vec)> = vec![]; let dummy = |id, origin, data: &[u8]| dispatched.push((id, origin, data.to_vec())); - Parachains::dispatch_upward_messages(0, ¶chains, 2, 3, dummy); + Parachains::dispatch_upward_messages(2, 3, dummy); assert_eq!(dispatched, vec![ (0.into(), ParachainDispatchOrigin::Parachain, vec![0; 4]) ]); @@ -1243,19 +1316,19 @@ mod tests { assert_eq!(::get(ParaId::from(1)).len(), 1); }); new_test_ext(parachains.clone()).execute_with(|| { - let parachains = vec![0.into(), 1.into(), 2.into()]; - Parachains::queue_upward_messages(0.into(), &vec![ + init_block(); + queue_upward_messages(0.into(), &vec![ UpwardMessage { origin: ParachainDispatchOrigin::Parachain, data: vec![0; 2] } ]); - Parachains::queue_upward_messages(1.into(), &vec![ + queue_upward_messages(1.into(), &vec![ UpwardMessage { origin: ParachainDispatchOrigin::Parachain, data: vec![1; 2] } ]); - Parachains::queue_upward_messages(2.into(), &vec![ + queue_upward_messages(2.into(), &vec![ UpwardMessage { origin: ParachainDispatchOrigin::Parachain, data: vec![2] } ]); let mut dispatched: Vec<(ParaId, ParachainDispatchOrigin, Vec)> = vec![]; let dummy = |id, origin, data: &[u8]| dispatched.push((id, origin, data.to_vec())); - Parachains::dispatch_upward_messages(0, ¶chains, 2, 3, dummy); + Parachains::dispatch_upward_messages(2, 3, dummy); assert_eq!(dispatched, vec![ (0.into(), ParachainDispatchOrigin::Parachain, vec![0; 2]), (2.into(), ParachainDispatchOrigin::Parachain, vec![2]) @@ -1265,44 +1338,44 @@ mod tests { assert!(::get(ParaId::from(2)).is_empty()); }); new_test_ext(parachains.clone()).execute_with(|| { - let parachains = vec![0.into(), 1.into(), 2.into()]; - Parachains::queue_upward_messages(0.into(), &vec![ + init_block(); + queue_upward_messages(0.into(), &vec![ UpwardMessage { origin: ParachainDispatchOrigin::Parachain, data: vec![0; 2] } ]); - Parachains::queue_upward_messages(1.into(), &vec![ + queue_upward_messages(1.into(), &vec![ UpwardMessage { origin: ParachainDispatchOrigin::Parachain, data: vec![1; 2] } ]); - Parachains::queue_upward_messages(2.into(), &vec![ + queue_upward_messages(2.into(), &vec![ UpwardMessage { origin: ParachainDispatchOrigin::Parachain, data: vec![2] } ]); let mut dispatched: Vec<(ParaId, ParachainDispatchOrigin, Vec)> = vec![]; let dummy = |id, origin, data: &[u8]| dispatched.push((id, origin, data.to_vec())); - Parachains::dispatch_upward_messages(1, ¶chains, 2, 3, dummy); + Parachains::dispatch_upward_messages(2, 3, dummy); assert_eq!(dispatched, vec![ - (1.into(), ParachainDispatchOrigin::Parachain, vec![1; 2]), + (0.into(), ParachainDispatchOrigin::Parachain, vec![0; 2]), (2.into(), ParachainDispatchOrigin::Parachain, vec![2]) ]); - assert_eq!(::get(ParaId::from(0)).len(), 1); - assert!(::get(ParaId::from(1)).is_empty()); + assert!(::get(ParaId::from(0)).is_empty()); + assert_eq!(::get(ParaId::from(1)).len(), 1); assert!(::get(ParaId::from(2)).is_empty()); }); new_test_ext(parachains.clone()).execute_with(|| { - let parachains = vec![0.into(), 1.into(), 2.into()]; - Parachains::queue_upward_messages(0.into(), &vec![ + init_block(); + queue_upward_messages(0.into(), &vec![ UpwardMessage { origin: ParachainDispatchOrigin::Parachain, data: vec![0; 2] } ]); - Parachains::queue_upward_messages(1.into(), &vec![ + queue_upward_messages(1.into(), &vec![ UpwardMessage { origin: ParachainDispatchOrigin::Parachain, data: vec![1; 2] } ]); - Parachains::queue_upward_messages(2.into(), &vec![ + queue_upward_messages(2.into(), &vec![ UpwardMessage { origin: ParachainDispatchOrigin::Parachain, data: vec![2] } ]); let mut dispatched: Vec<(ParaId, ParachainDispatchOrigin, Vec)> = vec![]; let dummy = |id, origin, data: &[u8]| dispatched.push((id, origin, data.to_vec())); - Parachains::dispatch_upward_messages(2, ¶chains, 2, 3, dummy); + Parachains::dispatch_upward_messages(2, 3, dummy); assert_eq!(dispatched, vec![ + (0.into(), ParachainDispatchOrigin::Parachain, vec![0; 2]), (2.into(), ParachainDispatchOrigin::Parachain, vec![2]), - (0.into(), ParachainDispatchOrigin::Parachain, vec![0; 2]) ]); assert!(::get(ParaId::from(0)).is_empty()); assert_eq!(::get(ParaId::from(1)).len(), 1); @@ -1316,20 +1389,21 @@ mod tests { (0u32.into(), vec![], vec![]), ]; new_test_ext(parachains.clone()).execute_with(|| { + run_to_block(2); let messages = vec![ UpwardMessage { origin: ParachainDispatchOrigin::Signed, data: vec![0] } ]; assert_ok!(Parachains::check_upward_messages(0.into(), &messages, 2, 3)); // all good. - Parachains::queue_upward_messages(0.into(), &vec![ + queue_upward_messages(0.into(), &vec![ UpwardMessage { origin: ParachainDispatchOrigin::Signed, data: vec![0] }, ]); let messages = vec![ UpwardMessage { origin: ParachainDispatchOrigin::Parachain, data: vec![1, 2] } ]; assert_ok!(Parachains::check_upward_messages(0.into(), &messages, 2, 3)); - Parachains::queue_upward_messages(0.into(), &messages); + queue_upward_messages(0.into(), &messages); assert_eq!(::get(ParaId::from(0)), vec![ UpwardMessage { origin: ParachainDispatchOrigin::Signed, data: vec![0] }, UpwardMessage { origin: ParachainDispatchOrigin::Parachain, data: vec![1, 2] }, @@ -1343,6 +1417,7 @@ mod tests { (0u32.into(), vec![], vec![]), ]; new_test_ext(parachains.clone()).execute_with(|| { + run_to_block(2); // oversize, but ok since it's just one and the queue is empty. let messages = vec![ UpwardMessage { origin: ParachainDispatchOrigin::Signed, data: vec![0; 4] }, @@ -1378,8 +1453,9 @@ mod tests { (0u32.into(), vec![], vec![]), ]; new_test_ext(parachains.clone()).execute_with(|| { + run_to_block(2); // too many messages. - Parachains::queue_upward_messages(0.into(), &vec![ + queue_upward_messages(0.into(), &vec![ UpwardMessage { origin: ParachainDispatchOrigin::Signed, data: vec![0] }, ]); let messages = vec![ @@ -1399,8 +1475,9 @@ mod tests { (0u32.into(), vec![], vec![]), ]; new_test_ext(parachains.clone()).execute_with(|| { + run_to_block(2); // too much data. - Parachains::queue_upward_messages(0.into(), &vec![ + queue_upward_messages(0.into(), &vec![ UpwardMessage { origin: ParachainDispatchOrigin::Signed, data: vec![0, 1] }, ]); let messages = vec![ @@ -1419,8 +1496,9 @@ mod tests { (0u32.into(), vec![], vec![]), ]; new_test_ext(parachains.clone()).execute_with(|| { + run_to_block(2); // bad - already an oversize messages queued. - Parachains::queue_upward_messages(0.into(), &vec![ + queue_upward_messages(0.into(), &vec![ UpwardMessage { origin: ParachainDispatchOrigin::Signed, data: vec![0; 4] }, ]); let messages = vec![ @@ -1439,8 +1517,9 @@ mod tests { (0u32.into(), vec![], vec![]), ]; new_test_ext(parachains.clone()).execute_with(|| { + run_to_block(2); // bad - oversized and already a message queued. - Parachains::queue_upward_messages(0.into(), &vec![ + queue_upward_messages(0.into(), &vec![ UpwardMessage { origin: ParachainDispatchOrigin::Signed, data: vec![0] }, ]); let messages = vec![ @@ -1462,6 +1541,7 @@ mod tests { ]; new_test_ext(parachains.clone()).execute_with(|| { + run_to_block(2); // parachain 0 is self let mut candidates = vec![ new_candidate_with_upward_messages(0, vec![ @@ -1491,9 +1571,10 @@ mod tests { ]; new_test_ext(parachains.clone()).execute_with(|| { - assert_eq!(Parachains::active_parachains(), vec![5u32.into(), 100u32.into()]); - assert_eq!(Parachains::parachain_code(ParaId::from(5u32)), Some(vec![1,2,3])); - assert_eq!(Parachains::parachain_code(ParaId::from(100u32)), Some(vec![4,5,6])); + run_to_block(2); + assert_eq!(Parachains::active_parachains(), vec![(5u32.into(), None), (100u32.into(), None)]); + assert_eq!(Parachains::parachain_code(ParaId::from(5u32)), Some(vec![1, 2, 3])); + assert_eq!(Parachains::parachain_code(ParaId::from(100u32)), Some(vec![4, 5, 6])); }); } @@ -1505,20 +1586,28 @@ mod tests { ]; new_test_ext(parachains.clone()).execute_with(|| { - assert_eq!(Parachains::active_parachains(), vec![5u32.into(), 100u32.into()]); + run_to_block(2); + assert_eq!(Parachains::active_parachains(), vec![(5u32.into(), None), (100u32.into(), None)]); assert_eq!(Parachains::parachain_code(ParaId::from(5u32)), Some(vec![1,2,3])); assert_eq!(Parachains::parachain_code(ParaId::from(100u32)), Some(vec![4,5,6])); - assert_ok!(Parachains::register_parachain(Origin::ROOT, 99u32.into(), vec![7,8,9], vec![1, 1, 1])); + assert_ok!(Registrar::register_para(Origin::ROOT, 99u32.into(), ParaInfo{scheduling: Scheduling::Always}, vec![7,8,9], vec![1, 1, 1])); + assert_ok!(Parachains::set_heads(Origin::NONE, vec![])); - assert_eq!(Parachains::active_parachains(), vec![5u32.into(), 99u32.into(), 100u32.into()]); - assert_eq!(Parachains::parachain_code(ParaId::from(99u32)), Some(vec![7,8,9])); + run_to_block(3); - assert_ok!(Parachains::deregister_parachain(Origin::ROOT, 5u32.into())); + assert_eq!(Parachains::active_parachains(), vec![(5u32.into(), None), (99u32.into(), None), (100u32.into(), None)]); + assert_eq!(Parachains::parachain_code(&ParaId::from(99u32)), Some(vec![7,8,9])); - assert_eq!(Parachains::active_parachains(), vec![99u32.into(), 100u32.into()]); - assert_eq!(Parachains::parachain_code(ParaId::from(5u32)), None); + assert_ok!(Registrar::deregister_para(Origin::ROOT, 5u32.into())); + assert_ok!(Parachains::set_heads(Origin::NONE, vec![])); + + // parachain still active this block. another block must pass before it's inactive. + run_to_block(4); + + assert_eq!(Parachains::active_parachains(), vec![(99u32.into(), None), (100u32.into(), None)]); + assert_eq!(Parachains::parachain_code(&ParaId::from(5u32)), None); }); } @@ -1530,6 +1619,7 @@ mod tests { ]; new_test_ext(parachains.clone()).execute_with(|| { + run_to_block(2); let check_roster = |duty_roster: &DutyRoster| { assert_eq!(duty_roster.validator_duty.len(), 8); for i in (0..2).map(ParaId::from) { @@ -1565,6 +1655,7 @@ mod tests { ]; new_test_ext(parachains.clone()).execute_with(|| { + run_to_block(2); let candidate = AttestedCandidate { validity_votes: vec![], validator_indices: BitVec::new(), @@ -1593,6 +1684,9 @@ mod tests { ]; new_test_ext(parachains.clone()).execute_with(|| { + run_to_block(2); + assert_eq!(Parachains::active_parachains().len(), 2); + let mut candidate_a = AttestedCandidate { validity_votes: vec![], validator_indices: BitVec::new(), @@ -1646,6 +1740,7 @@ mod tests { ]; new_test_ext(parachains.clone()).execute_with(|| { + run_to_block(2); let mut candidate = AttestedCandidate { validity_votes: vec![], validator_indices: BitVec::new(), @@ -1682,6 +1777,7 @@ mod tests { ]; new_test_ext(parachains.clone()).execute_with(|| { + run_to_block(2); let mut candidate = AttestedCandidate { validity_votes: vec![], validator_indices: BitVec::new(), @@ -1712,8 +1808,6 @@ mod tests { #[test] fn ingress_works() { - use sr_primitives::traits::OnFinalize; - let parachains = vec![ (0u32.into(), vec![], vec![]), (1u32.into(), vec![], vec![]), @@ -1724,8 +1818,9 @@ mod tests { assert_eq!(Parachains::ingress(ParaId::from(1), None), Some(Vec::new())); assert_eq!(Parachains::ingress(ParaId::from(99), None), Some(Vec::new())); + init_block(); for i in 1..10 { - System::set_block_number(i); + run_to_block(i); let from_a = vec![(1.into(), [i as u8; 32].into())]; let mut candidate_a = AttestedCandidate { @@ -1766,11 +1861,9 @@ mod tests { set_heads(vec![candidate_a, candidate_b]), Origin::NONE, )); - - Parachains::on_finalize(i); } - System::set_block_number(10); + run_to_block(10); assert_ok!(Parachains::dispatch( set_heads(vec![]), Origin::NONE, @@ -1796,7 +1889,7 @@ mod tests { ))).collect::>()), ); - assert_ok!(Parachains::deregister_parachain(Origin::ROOT, 1u32.into())); + assert_ok!(Registrar::deregister_para(Origin::ROOT, 1u32.into())); // after deregistering, there is no ingress to 1, but unrouted messages // from 1 stick around. @@ -1805,8 +1898,7 @@ mod tests { vec![(1.into(), [i as u8; 32].into())] ))).collect::>())); - Parachains::on_finalize(10); - System::set_block_number(11); + run_to_block(11); let mut candidate_c = AttestedCandidate { validity_votes: vec![], @@ -1829,8 +1921,7 @@ mod tests { Origin::NONE, )); - Parachains::on_finalize(11); - System::set_block_number(12); + run_to_block(12); // at the next block, ingress to 99 should be empty. assert_eq!(Parachains::ingress(ParaId::from(99), None), Some(Vec::new())); @@ -1846,6 +1937,7 @@ mod tests { ]; new_test_ext(parachains.clone()).execute_with(|| { + run_to_block(2); // parachain 99 does not exist let non_existent = vec![(99.into(), [1; 32].into())]; let mut candidate = new_candidate_with_egress_roots(non_existent); @@ -1870,6 +1962,7 @@ mod tests { ]; new_test_ext(parachains.clone()).execute_with(|| { + run_to_block(2); // parachain 0 is self let to_self = vec![(0.into(), [1; 32].into())]; let mut candidate = new_candidate_with_egress_roots(to_self); @@ -1894,6 +1987,7 @@ mod tests { ]; new_test_ext(parachains.clone()).execute_with(|| { + run_to_block(2); // parachain 0 is self let out_of_order = vec![(1.into(), [1; 32].into()), ((0.into(), [1; 32].into()))]; let mut candidate = new_candidate_with_egress_roots(out_of_order); @@ -1918,6 +2012,7 @@ mod tests { ]; new_test_ext(parachains.clone()).execute_with(|| { + run_to_block(2); // parachain 0 is self let contains_empty_trie_root = vec![(1.into(), [1; 32].into()), ((2.into(), EMPTY_TRIE_ROOT.into()))]; let mut candidate = new_candidate_with_egress_roots(contains_empty_trie_root); diff --git a/runtime/src/registrar.rs b/runtime/src/registrar.rs new file mode 100644 index 000000000000..97dd7e5e62cc --- /dev/null +++ b/runtime/src/registrar.rs @@ -0,0 +1,1369 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Module to handle which parachains/parathreads (collectively referred to as "paras") are +//! registered and which are scheduled. Doesn't manage any of the actual execution/validation logic +//! which is left to `parachains.rs`. + +use rstd::{prelude::*, result}; +#[cfg(any(feature = "std", test))] +use rstd::marker::PhantomData; +use codec::{Encode, Decode}; + +use sr_primitives::{ + weights::{SimpleDispatchInfo, DispatchInfo}, + transaction_validity::{TransactionValidityError, ValidTransaction, TransactionValidity}, + traits::{Hash as HashT, SignedExtension} +}; + +use srml_support::{ + decl_storage, decl_module, decl_event, ensure, + dispatch::{Result, IsSubType}, traits::{Get, Currency, ReservableCurrency} +}; +use system::{self, ensure_root, ensure_signed}; +use primitives::parachain::{ + Id as ParaId, CollatorId, Scheduling, LOWEST_USER_ID, SwapAux, Info as ParaInfo, ActiveParas, + Retriable +}; +use crate::parachains; +use sr_primitives::transaction_validity::InvalidTransaction; + +/// Parachain registration API. +pub trait Registrar { + /// Create a new unique parachain identity for later registration. + fn new_id() -> ParaId; + + /// Register a parachain with given `code` and `initial_head_data`. `id` must not yet be registered or it will + /// result in a error. + fn register_para( + id: ParaId, + info: ParaInfo, + code: Vec, + initial_head_data: Vec, + ) -> Result; + + /// Deregister a parachain with given `id`. If `id` is not currently registered, an error is returned. + fn deregister_para(id: ParaId) -> Result; +} + +impl Registrar for Module { + fn new_id() -> ParaId { + ::mutate(|n| { let r = *n; *n = ParaId::from(u32::from(*n) + 1); r }) + } + + fn register_para( + id: ParaId, + info: ParaInfo, + code: Vec, + initial_head_data: Vec, + ) -> Result { + ensure!(!Paras::exists(id), "Parachain already exists"); + if let Scheduling::Always = info.scheduling { + Parachains::mutate(|parachains| + match parachains.binary_search(&id) { + Ok(_) => Err("Parachain already exists"), + Err(idx) => { + parachains.insert(idx, id); + Ok(()) + } + } + )?; + } + >::initialize_para(id, code, initial_head_data); + Paras::insert(id, info); + Ok(()) + } + + fn deregister_para(id: ParaId) -> Result { + let info = Paras::take(id).ok_or("Invalid id")?; + if let Scheduling::Always = info.scheduling { + Parachains::mutate(|parachains| + parachains.binary_search(&id) + .map(|index| parachains.remove(index)) + .map_err(|_| "Invalid id") + )?; + } + >::cleanup_para(id); + Paras::remove(id); + Ok(()) + } +} + +type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + +pub trait Trait: parachains::Trait { + /// The overarching event type. + type Event: From + Into<::Event>; + + /// The aggregated origin type must support the parachains origin. We require that we can + /// infallibly convert between this origin and the system origin, but in reality, they're the + /// same type, we just can't express that to the Rust type system without writing a `where` + /// clause everywhere. + type Origin: From<::Origin> + + Into::Origin>>; + + /// The system's currency for parathread payment. + type Currency: ReservableCurrency; + + /// The deposit to be paid to run a parathread. + type ParathreadDeposit: Get>; + + /// Handler for when two ParaIds are swapped. + type SwapAux: SwapAux; + + /// The number of items in the parathread queue, aka the number of blocks in advance to schedule + /// parachain execution. + type QueueSize: Get; + + /// The number of rotations that you will have as grace if you miss a block. + type MaxRetries: Get; +} + +decl_storage! { + trait Store for Module as Registrar { + // Vector of all parachain IDs, in ascending order. + Parachains: Vec; + + /// The number of threads to schedule per block. + ThreadCount: u32; + + /// An array of the queue of set of threads scheduled for the coming blocks; ordered by + /// ascending para ID. There can be no duplicates of para ID in each list item. + SelectedThreads: Vec>; + + /// Parathreads/chains scheduled for execution this block. If the collator ID is set, then + /// a particular collator has already been chosen for the next block, and no other collator + /// may provide the block. In this case we allow the possibility of the combination being + /// retried in a later block, expressed by `Retriable`. + /// + /// Ordered by ParaId. + Active: Vec<(ParaId, Option<(CollatorId, Retriable)>)>; + + /// The next unused ParaId value. Start this high in order to keep low numbers for + /// system-level chains. + NextFreeId: ParaId = LOWEST_USER_ID; + + /// Pending swap operations. + PendingSwap: map ParaId => Option; + + /// Map of all registered parathreads/chains. + Paras get(paras): map ParaId => Option; + + /// The current queue for parathreads that should be retried. + RetryQueue get(retry_queue): Vec>; + + /// Users who have paid a parathread's deposit + Debtors: map ParaId => T::AccountId; + } + add_extra_genesis { + config(parachains): Vec<(ParaId, Vec, Vec)>; + config(_phdata): PhantomData; + build(build::); + } +} + +#[cfg(feature = "std")] +fn build(config: &GenesisConfig) { + use sr_primitives::traits::Zero; + + let mut p = config.parachains.clone(); + p.sort_unstable_by_key(|&(ref id, _, _)| *id); + p.dedup_by_key(|&mut (ref id, _, _)| *id); + + let only_ids: Vec = p.iter().map(|&(ref id, _, _)| id).cloned().collect(); + + Parachains::put(&only_ids); + + for (id, code, genesis) in p { + Paras::insert(id, &primitives::parachain::PARACHAIN_INFO); + // no ingress -- a chain cannot be routed to until it is live. + ::insert(&id, &code); + ::insert(&id, &genesis); + >::insert(&id, T::BlockNumber::zero()); + // Save initial parachains in registrar + Paras::insert(id, ParaInfo { scheduling: Scheduling::Always }) + } +} + +/// Swap the existence of two items, provided by value, within an ordered list. +/// +/// If neither item exists, or if both items exist this will do nothing. If exactly one of the +/// items exists, then it will be removed and the other inserted. +pub fn swap_ordered_existence(ids: &mut [T], one: T, other: T) { + let maybe_one_pos = ids.binary_search(&one); + let maybe_other_pos = ids.binary_search(&other); + match (maybe_one_pos, maybe_other_pos) { + (Ok(one_pos), Err(_)) => ids[one_pos] = other, + (Err(_), Ok(other_pos)) => ids[other_pos] = one, + _ => return, + }; + ids.sort(); +} + +decl_module! { + /// Parachains module. + pub struct Module for enum Call where origin: ::Origin { + fn deposit_event() = default; + + /// Register a parachain with given code. + /// Fails if given ID is already used. + #[weight = SimpleDispatchInfo::FixedOperational(5_000_000)] + pub fn register_para(origin, + #[compact] id: ParaId, + info: ParaInfo, + code: Vec, + initial_head_data: Vec, + ) -> Result { + ensure_root(origin)?; + >:: + register_para(id, info, code, initial_head_data) + } + + /// Deregister a parachain with given id + #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + pub fn deregister_para(origin, #[compact] id: ParaId) -> Result { + ensure_root(origin)?; + >::deregister_para(id) + } + + /// Reset the number of parathreads that can pay to be scheduled in a single block. + /// + /// - `count`: The number of parathreads. + /// + /// Must be called from Root origin. + fn set_thread_count(origin, count: u32) { + ensure_root(origin)?; + ThreadCount::put(count); + } + + /// Register a parathread for immediate use. + /// + /// Must be sent from a Signed origin that is able to have ParathreadDeposit reserved. + /// `code` and `initial_head_data` are used to initialize the parathread's state. + fn register_parathread(origin, + code: Vec, + initial_head_data: Vec, + ) { + let who = ensure_signed(origin)?; + + T::Currency::reserve(&who, T::ParathreadDeposit::get())?; + + let info = ParaInfo { + scheduling: Scheduling::Dynamic, + }; + let id = >::new_id(); + + let _ = >:: + register_para(id, info, code, initial_head_data); + + >::insert(id, who); + + Self::deposit_event(Event::ParathreadRegistered(id)); + } + + /// Place a bid for a parathread to be progressed in the next block. + /// + /// This is a kind of special transaction that should by heavily prioritized in the + /// transaction pool according to the `value`; only `ThreadCount` of them may be presented + /// in any single block. + fn select_parathread(origin, + #[compact] _id: ParaId, + _collator: CollatorId, + _head_hash: T::Hash, + ) { + ensure_signed(origin)?; + // Everything else is checked for in the transaction `SignedExtension`. + } + + /// Deregister a parathread and retrieve the deposit. + /// + /// Must be sent from a `Parachain` origin which is currently a parathread. + /// + /// Ensure that before calling this that any funds you want emptied from the parathread's + /// account is moved out; after this it will be impossible to retrieve them (without + /// governance intervention). + fn deregister_parathread(origin) { + let id = parachains::ensure_parachain(::Origin::from(origin))?; + + let info = Paras::get(id).ok_or("invalid id")?; + if let Scheduling::Dynamic = info.scheduling {} else { Err("invalid parathread id")? } + + >::deregister_para(id)?; + Self::force_unschedule(|i| i == id); + + let debtor = >::take(id); + let _ = T::Currency::unreserve(&debtor, T::ParathreadDeposit::get()); + + Self::deposit_event(Event::ParathreadRegistered(id)); + } + + /// Swap a parachain with another parachain or parathread. The origin must be a `Parachain`. + /// The swap will happen only if there is already an opposite swap pending. If there is not, + /// the swap will be stored in the pending swaps map, ready for a later confirmatory swap. + /// + /// The `ParaId`s remain mapped to the same head data and code so external code can rely on + /// `ParaId` to be a long-term identifier of a notional "parachain". However, their + /// scheduling info (i.e. whether they're a parathread or parachain), auction information + /// and the auction deposit are switched. + fn swap(origin, #[compact] other: ParaId) { + let id = parachains::ensure_parachain(::Origin::from(origin))?; + + if PendingSwap::get(other) == Some(id) { + // actually do the swap. + T::SwapAux::ensure_can_swap(id, other)?; + + // Remove intention to swap. + PendingSwap::remove(other); + Self::force_unschedule(|i| i == id || i == other); + Parachains::mutate(|ids| swap_ordered_existence(ids, id, other)); + Paras::mutate(id, |i| + Paras::mutate(other, |j| + rstd::mem::swap(i, j) + ) + ); + + >::mutate(id, |i| + >::mutate(other, |j| + rstd::mem::swap(i, j) + ) + ); + let _ = T::SwapAux::on_swap(id, other); + } else { + PendingSwap::insert(id, other); + } + } + + /// Block initializer. Clears SelectedThreads and constructs/replaces Active. + fn on_initialize() { + let next_up = SelectedThreads::mutate(|t| { + let r = if t.len() >= T::QueueSize::get() { + // Take the first set of parathreads in queue + t.remove(0) + } else { + vec![] + }; + while t.len() < T::QueueSize::get() { + t.push(vec![]); + } + r + }); + // mutable so that we can replace with `None` if parathread appears in new schedule. + let mut retrying = Self::take_next_retry(); + if let Some(((para, _), _)) = retrying { + // this isn't really ideal: better would be if there were an earlier pass that set + // retrying to the first item in the Missed queue that isn't already scheduled, but + // this is potentially O(m*n) in terms of missed queue size and parathread pool size. + if next_up.iter().any(|x| x.0 == para) { + retrying = None + } + } + + let mut paras = Parachains::get().into_iter() + .map(|id| (id, None)) + .chain(next_up.into_iter() + .map(|(para, collator)| + (para, Some((collator, Retriable::WithRetries(0)))) + ) + ).chain(retrying.into_iter() + .map(|((para, collator), retries)| + (para, Some((collator, Retriable::WithRetries(retries + 1)))) + ) + ).collect::>(); + // for Rust's timsort algorithm, sorting a concatenation of two sorted ranges is near + // O(N). + paras.sort_by_key(|&(ref id, _)| *id); + + Active::put(paras); + } + + fn on_finalize() { + // a block without this will panic, but let's not panic here. + if let Some(proceeded_vec) = parachains::DidUpdate::get() { + // Active is sorted and DidUpdate is a sorted subset of its elements. + // + // We just go through the contents of active and find any items that don't appear in + // DidUpdate *and* which are enabled for retry. + let mut proceeded = proceeded_vec.into_iter(); + let mut i = proceeded.next(); + for sched in Active::get().into_iter() { + match i { + // Scheduled parachain proceeded properly. Move onto next item. + Some(para) if para == sched.0 => i = proceeded.next(), + // Scheduled `sched` missed their block. + // Queue for retry if it's allowed. + _ => if let (i, Some((c, Retriable::WithRetries(n)))) = sched { + Self::retry_later((i, c), n) + }, + } + } + } + } + } +} + +decl_event!{ + pub enum Event { + /// A parathread was registered; its new ID is supplied. + ParathreadRegistered(ParaId), + + /// The parathread of the supplied ID was de-registered. + ParathreadDeregistered(ParaId), + } +} + +impl Module { + /// Ensures that the given `ParaId` corresponds to a registered parathread, and returns a descriptor if so. + pub fn ensure_thread_id(id: ParaId) -> Option { + Paras::get(id).and_then(|info| if let Scheduling::Dynamic = info.scheduling { + Some(info) + } else { + None + }) + } + + fn retry_later(sched: (ParaId, CollatorId), retries: u32) { + if retries < T::MaxRetries::get() { + RetryQueue::mutate(|q| { + q.resize(T::MaxRetries::get() as usize, vec![]); + q[retries as usize].push(sched); + }); + } + } + + fn take_next_retry() -> Option<((ParaId, CollatorId), u32)> { + RetryQueue::mutate(|q| { + for (i, q) in q.iter_mut().enumerate() { + if !q.is_empty() { + return Some((q.remove(0), i as u32)); + } + } + None + }) + } + + /// Forcibly remove the threads matching `m` from all current and future scheduling. + fn force_unschedule(m: impl Fn(ParaId) -> bool) { + RetryQueue::mutate(|qs| for q in qs.iter_mut() { + q.retain(|i| !m(i.0)) + }); + SelectedThreads::mutate(|qs| for q in qs.iter_mut() { + q.retain(|i| !m(i.0)) + }); + Active::mutate(|a| for i in a.iter_mut() { + if m(i.0) { + if let Some((_, ref mut r)) = i.1 { + *r = Retriable::Never; + } + } + }); + } +} + +impl ActiveParas for Module { + fn active_paras() -> Vec<(ParaId, Option<(CollatorId, Retriable)>)> { + Active::get() + } +} + +/// Ensure that parathread selections happen prioritized by fees. +#[derive(Encode, Decode, Clone, Eq, PartialEq)] +pub struct LimitParathreadCommits(rstd::marker::PhantomData) where + ::Call: IsSubType, T>; + +impl rstd::fmt::Debug for LimitParathreadCommits where + ::Call: IsSubType, T> +{ + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + write!(f, "LimitParathreadCommits") + } +} + +/// Custom validity errors used in Polkadot while validating transactions. +#[repr(u8)] +pub enum Error { + /// Parathread ID has already been submitted for this block. + Duplicate = 0, + /// Parathread ID does not identify a parathread. + InvalidId = 1, +} + +impl SignedExtension for LimitParathreadCommits where + ::Call: IsSubType, T> +{ + type AccountId = T::AccountId; + type Call = ::Call; + type AdditionalSigned = (); + type Pre = (); + + fn additional_signed(&self) + -> rstd::result::Result + { + Ok(()) + } + + fn validate( + &self, + _who: &Self::AccountId, + call: &Self::Call, + _info: DispatchInfo, + _len: usize, + ) -> TransactionValidity { + let mut r = ValidTransaction::default(); + if let Some(local_call) = call.is_sub_type() { + if let Call::select_parathread(id, collator, hash) = local_call { + // ensure that the para ID is actually a parathread. + let e = TransactionValidityError::from(InvalidTransaction::Custom(Error::InvalidId as u8)); + >::ensure_thread_id(*id).ok_or(e)?; + + // ensure that we haven't already had a full complement of selected parathreads. + let mut upcoming_selected_threads = SelectedThreads::get(); + if upcoming_selected_threads.is_empty() { + upcoming_selected_threads.push(vec![]); + } + let i = upcoming_selected_threads.len() - 1; + let selected_threads = &mut upcoming_selected_threads[i]; + let thread_count = ThreadCount::get() as usize; + ensure!( + selected_threads.len() < thread_count, + InvalidTransaction::ExhaustsResources.into() + ); + + // ensure that this is not selecting a duplicate parathread ID + let e = TransactionValidityError::from(InvalidTransaction::Custom(Error::Duplicate as u8)); + let pos = selected_threads + .binary_search_by(|&(ref other_id, _)| other_id.cmp(id)) + .err() + .ok_or(e)?; + + // ensure that this is a live bid (i.e. that the thread's chain head matches) + let e = TransactionValidityError::from(InvalidTransaction::Custom(Error::InvalidId as u8)); + let head = >::parachain_head(id).ok_or(e)?; + let actual = T::Hashing::hash(&head); + ensure!(&actual == hash, InvalidTransaction::Stale.into()); + + // updated the selected threads. + selected_threads.insert(pos, (*id, collator.clone())); + rstd::mem::drop(selected_threads); + SelectedThreads::put(upcoming_selected_threads); + + // provides the state-transition for this head-data-hash; this should cue the pool + // to throw out competing transactions with lesser fees. + r.provides = vec![hash.encode()]; + } + } + Ok(r) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use bitvec::vec::BitVec; + use sr_io::TestExternalities; + use substrate_primitives::{H256, Pair}; + use sr_primitives::{ + traits::{ + BlakeTwo256, IdentityLookup, OnInitialize, OnFinalize, Dispatchable, + AccountIdConversion, + }, testing::{UintAuthorityId, Header}, Perbill + }; + use primitives::{ + parachain::{ + ValidatorId, Info as ParaInfo, Scheduling, LOWEST_USER_ID, AttestedCandidate, + CandidateReceipt, HeadData, ValidityAttestation, Statement, Chain, CollatorPair, + }, + Balance, BlockNumber, + }; + use srml_support::{ + impl_outer_origin, impl_outer_dispatch, assert_ok, parameter_types, assert_noop, + }; + use keyring::Sr25519Keyring; + + use crate::parachains; + use crate::slots; + use crate::attestations; + + impl_outer_origin! { + pub enum Origin for Test { + parachains, + } + } + + impl_outer_dispatch! { + pub enum Call for Test where origin: Origin { + parachains::Parachains, + registrar::Registrar, + } + } + + #[derive(Clone, Eq, PartialEq)] + pub struct Test; + parameter_types! { + pub const BlockHashCount: u32 = 250; + pub const MaximumBlockWeight: u32 = 4 * 1024 * 1024; + pub const MaximumBlockLength: u32 = 4 * 1024 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); + } + impl system::Trait for Test { + type Origin = Origin; + type Call = Call; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + } + + parameter_types! { + pub const ExistentialDeposit: Balance = 0; + pub const TransferFee: Balance = 0; + pub const CreationFee: Balance = 0; + } + + impl balances::Trait for Test { + type Balance = Balance; + type OnFreeBalanceZero = (); + type OnNewAccount = (); + type Event = (); + type DustRemoval = (); + type TransferPayment = (); + type ExistentialDeposit = ExistentialDeposit; + type TransferFee = TransferFee; + type CreationFee = CreationFee; + } + + parameter_types!{ + pub const LeasePeriod: u64 = 10; + pub const EndingPeriod: u64 = 3; + } + + impl slots::Trait for Test { + type Event = (); + type Currency = balances::Module; + type Parachains = Registrar; + type EndingPeriod = EndingPeriod; + type LeasePeriod = LeasePeriod; + type Randomness = RandomnessCollectiveFlip; + } + + parameter_types!{ + pub const AttestationPeriod: BlockNumber = 100; + } + + impl attestations::Trait for Test { + type AttestationPeriod = AttestationPeriod; + type ValidatorIdentities = parachains::ValidatorIdentities; + type RewardAttestation = (); + } + + parameter_types! { + pub const Period: BlockNumber = 1; + pub const Offset: BlockNumber = 0; + pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17); + } + + impl session::Trait for Test { + type OnSessionEnding = (); + type Keys = UintAuthorityId; + type ShouldEndSession = session::PeriodicSessions; + type SessionHandler = (); + type Event = (); + type SelectInitialValidators = (); + type ValidatorId = u64; + type ValidatorIdOf = (); + type DisabledValidatorsThreshold = DisabledValidatorsThreshold; + } + + impl parachains::Trait for Test { + type Origin = Origin; + type Call = Call; + type ParachainCurrency = balances::Module; + type ActiveParachains = Registrar; + type Registrar = Registrar; + type Randomness = RandomnessCollectiveFlip; + } + + parameter_types! { + pub const ParathreadDeposit: Balance = 10; + pub const QueueSize: usize = 2; + pub const MaxRetries: u32 = 3; + } + + impl Trait for Test { + type Event = (); + type Origin = Origin; + type Currency = balances::Module; + type ParathreadDeposit = ParathreadDeposit; + type SwapAux = slots::Module; + type QueueSize = QueueSize; + type MaxRetries = MaxRetries; + } + + type Balances = balances::Module; + type Parachains = parachains::Module; + type System = system::Module; + type Slots = slots::Module; + type Registrar = Module; + type RandomnessCollectiveFlip = randomness_collective_flip::Module; + + const AUTHORITY_KEYS: [Sr25519Keyring; 8] = [ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, + Sr25519Keyring::Ferdie, + Sr25519Keyring::One, + Sr25519Keyring::Two, + ]; + + fn new_test_ext(parachains: Vec<(ParaId, Vec, Vec)>) -> TestExternalities { + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + + let authority_keys = [ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, + Sr25519Keyring::Ferdie, + Sr25519Keyring::One, + Sr25519Keyring::Two, + ]; + + // stashes are the index. + let session_keys: Vec<_> = authority_keys.iter().enumerate() + .map(|(i, _k)| (i as u64, UintAuthorityId(i as u64))) + .collect(); + + let authorities: Vec<_> = authority_keys.iter().map(|k| ValidatorId::from(k.public())).collect(); + + let balances: Vec<_> = (0..authority_keys.len()).map(|i| (i as u64, 10_000_000)).collect(); + + parachains::GenesisConfig { + authorities: authorities.clone(), + }.assimilate_storage::(&mut t).unwrap(); + + GenesisConfig:: { + parachains, + _phdata: Default::default(), + }.assimilate_storage(&mut t).unwrap(); + + session::GenesisConfig:: { + keys: session_keys, + }.assimilate_storage(&mut t).unwrap(); + + balances::GenesisConfig:: { + balances, + vesting: vec![], + }.assimilate_storage(&mut t).unwrap(); + + t.into() + } + + fn init_block() { + println!("Initializing {}", System::block_number()); + System::on_initialize(System::block_number()); + Registrar::on_initialize(System::block_number()); + Parachains::on_initialize(System::block_number()); + Slots::on_initialize(System::block_number()); + } + + fn run_to_block(n: u64) { + println!("Running until block {}", n); + while System::block_number() < n { + if System::block_number() > 1 { + println!("Finalizing {}", System::block_number()); + if !parachains::DidUpdate::exists() { + println!("Null heads update"); + assert_ok!(Parachains::set_heads(system::RawOrigin::None.into(), vec![])); + } + Slots::on_finalize(System::block_number()); + Parachains::on_finalize(System::block_number()); + Registrar::on_finalize(System::block_number()); + System::on_finalize(System::block_number()); + } + System::set_block_number(System::block_number() + 1); + init_block(); + } + } + + fn schedule_thread(id: ParaId, head_data: &[u8], col: &CollatorId) { + let tx: LimitParathreadCommits = LimitParathreadCommits(Default::default()); + let hdh = BlakeTwo256::hash(head_data); + let inner_call = super::Call::select_parathread(id, col.clone(), hdh); + let call = Call::Registrar(inner_call); + let origin = 4u64; + assert!(tx.validate(&origin, &call, Default::default(), 0).is_ok()); + assert_ok!(call.dispatch(Origin::signed(origin))); + } + + fn user_id(i: u32) -> ParaId { + LOWEST_USER_ID + i + } + + fn attest(id: ParaId, collator: &CollatorPair, head_data: &[u8], block_data: &[u8]) -> AttestedCandidate { + let block_data_hash = BlakeTwo256::hash(block_data); + let candidate = CandidateReceipt { + parachain_index: id, + collator: collator.public(), + signature: block_data_hash.using_encoded(|d| collator.sign(d)), + head_data: HeadData(head_data.to_vec()), + egress_queue_roots: vec![], + fees: 0, + block_data_hash, + upward_messages: vec![], + }; + let payload = (Statement::Valid(candidate.hash()), System::parent_hash()).encode(); + let roster = Parachains::calculate_duty_roster().0.validator_duty; + AttestedCandidate { + candidate, + validity_votes: AUTHORITY_KEYS.iter() + .enumerate() + .filter(|(i, _)| roster[*i] == Chain::Parachain(id)) + .map(|(_, k)| k.sign(&payload).into()) + .map(ValidityAttestation::Explicit) + .collect(), + validator_indices: roster.iter() + .map(|i| i == &Chain::Parachain(id)) + .collect::(), + } + } + + #[test] + fn basic_setup_works() { + new_test_ext(vec![]).execute_with(|| { + assert_eq!(super::Parachains::get(), vec![]); + assert_eq!(ThreadCount::get(), 0); + assert_eq!(Active::get(), vec![]); + assert_eq!(NextFreeId::get(), LOWEST_USER_ID); + assert_eq!(PendingSwap::get(&ParaId::from(0u32)), None); + assert_eq!(Paras::get(&ParaId::from(0u32)), None); + }); + } + + #[test] + fn genesis_registration_works() { + let parachains = vec![ + (5u32.into(), vec![1,2,3], vec![1]), + (100u32.into(), vec![4,5,6], vec![2,]), + ]; + + new_test_ext(parachains).execute_with(|| { + // Need to trigger on_initialize + run_to_block(2); + // Genesis registration works + assert_eq!(Registrar::active_paras(), vec![(5u32.into(), None), (100u32.into(), None)]); + assert_eq!( + Registrar::paras(&ParaId::from(5u32)), + Some(ParaInfo { scheduling: Scheduling::Always }), + ); + assert_eq!( + Registrar::paras(&ParaId::from(100u32)), + Some(ParaInfo { scheduling: Scheduling::Always }), + ); + assert_eq!(Parachains::parachain_code(&ParaId::from(5u32)), Some(vec![1, 2, 3])); + assert_eq!(Parachains::parachain_code(&ParaId::from(100u32)), Some(vec![4, 5, 6])); + }); + } + + #[test] + fn swap_chain_and_thread_works() { + new_test_ext(vec![]).execute_with(|| { + assert_ok!(Registrar::set_thread_count(Origin::ROOT, 1)); + + // Need to trigger on_initialize + run_to_block(2); + + // Register a new parathread + assert_ok!(Registrar::register_parathread( + Origin::signed(1u64), + vec![1; 3], + vec![1; 3], + )); + + // Lease out a new parachain + assert_ok!(Slots::new_auction(Origin::ROOT, 5, 1)); + assert_ok!(Slots::bid(Origin::signed(1), 0, 1, 1, 4, 1)); + + run_to_block(9); + // Ensure that the thread is scheduled around the swap time. + let col = Sr25519Keyring::One.public().into(); + schedule_thread(user_id(0), &[1; 3], &col); + + run_to_block(10); + let h = BlakeTwo256::hash(&[2u8; 3]); + assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, user_id(1), h, vec![2; 3])); + assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), user_id(1), vec![2; 3])); + assert_ok!(Slots::set_offboarding(Origin::signed(user_id(1).into_account()), 1)); + + run_to_block(11); + // should be one active parachain and one active parathread. + assert_eq!(Registrar::active_paras(), vec![ + (user_id(0), Some((col.clone(), Retriable::WithRetries(0)))), + (user_id(1), None), + ]); + + // One half of the swap call does not actually trigger the swap. + assert_ok!(Registrar::swap(parachains::Origin::Parachain(user_id(0)).into(), user_id(1))); + + // Nothing changes from what was originally registered + assert_eq!(Registrar::paras(&user_id(0)), Some(ParaInfo { scheduling: Scheduling::Dynamic })); + assert_eq!(Registrar::paras(&user_id(1)), Some(ParaInfo { scheduling: Scheduling::Always })); + assert_eq!(super::Parachains::get(), vec![user_id(1)]); + assert_eq!(Slots::managed_ids(), vec![user_id(1)]); + assert_eq!(Slots::deposits(user_id(1)), vec![1; 3]); + assert_eq!(Slots::offboarding(user_id(1)), 1); + assert_eq!(Parachains::parachain_code(&user_id(0)), Some(vec![1u8; 3])); + assert_eq!(Parachains::parachain_head(&user_id(0)), Some(vec![1u8; 3])); + assert_eq!(Parachains::parachain_code(&user_id(1)), Some(vec![2u8; 3])); + assert_eq!(Parachains::parachain_head(&user_id(1)), Some(vec![2u8; 3])); + // Intention to swap is added + assert_eq!(PendingSwap::get(user_id(0)), Some(user_id(1))); + + // Intention to swap is reciprocated, swap actually happens + assert_ok!(Registrar::swap(parachains::Origin::Parachain(user_id(1)).into(), user_id(0))); + + assert_eq!(Registrar::paras(&user_id(0)), Some(ParaInfo { scheduling: Scheduling::Always })); + assert_eq!(Registrar::paras(&user_id(1)), Some(ParaInfo { scheduling: Scheduling::Dynamic })); + assert_eq!(super::Parachains::get(), vec![user_id(0)]); + assert_eq!(Slots::managed_ids(), vec![user_id(0)]); + assert_eq!(Slots::deposits(user_id(0)), vec![1; 3]); + assert_eq!(Slots::offboarding(user_id(0)), 1); + assert_eq!(Parachains::parachain_code(&user_id(0)), Some(vec![1u8; 3])); + assert_eq!(Parachains::parachain_head(&user_id(0)), Some(vec![1u8; 3])); + assert_eq!(Parachains::parachain_code(&user_id(1)), Some(vec![2u8; 3])); + assert_eq!(Parachains::parachain_head(&user_id(1)), Some(vec![2u8; 3])); + + // Intention to swap is no longer present + assert_eq!(PendingSwap::get(user_id(0)), None); + assert_eq!(PendingSwap::get(user_id(1)), None); + + run_to_block(12); + // thread should not be queued or scheduled any more, even though it would otherwise be + // being retried.. + assert_eq!(Registrar::active_paras(), vec![(user_id(0), None)]); + }); + } + + #[test] + fn swap_handles_funds_correctly() { + new_test_ext(vec![]).execute_with(|| { + assert_ok!(Registrar::set_thread_count(Origin::ROOT, 1)); + + // Need to trigger on_initialize + run_to_block(2); + + let initial_1_balance = Balances::free_balance(1); + let initial_2_balance = Balances::free_balance(2); + + // User 1 register a new parathread + assert_ok!(Registrar::register_parathread( + Origin::signed(1), + vec![1; 3], + vec![1; 3], + )); + + // User 2 leases out a new parachain + assert_ok!(Slots::new_auction(Origin::ROOT, 5, 1)); + assert_ok!(Slots::bid(Origin::signed(2), 0, 1, 1, 4, 1)); + + run_to_block(9); + + // Swap the parachain and parathread + assert_ok!(Registrar::swap(parachains::Origin::Parachain(user_id(0)).into(), user_id(1))); + assert_ok!(Registrar::swap(parachains::Origin::Parachain(user_id(1)).into(), user_id(0))); + + // Deregister the parathread that was originally a parachain + assert_ok!(Registrar::deregister_parathread(parachains::Origin::Parachain(user_id(1)).into())); + + // Go past when a parachain loses its slot + run_to_block(50); + + // Funds are correctly returned + assert_eq!(Balances::free_balance(1), initial_1_balance); + assert_eq!(Balances::free_balance(2), initial_2_balance); + }); + } + + #[test] + fn register_deregister_chains_works() { + let parachains = vec![ + (1u32.into(), vec![1; 3], vec![1; 3]), + ]; + + new_test_ext(parachains).execute_with(|| { + // Need to trigger on_initialize + run_to_block(2); + + // Genesis registration works + assert_eq!(Registrar::active_paras(), vec![(1u32.into(), None)]); + assert_eq!( + Registrar::paras(&ParaId::from(1u32)), + Some(ParaInfo { scheduling: Scheduling::Always }) + ); + assert_eq!(Parachains::parachain_code(&ParaId::from(1u32)), Some(vec![1; 3])); + + // Register a new parachain + assert_ok!(Registrar::register_para( + Origin::ROOT, + 2u32.into(), + ParaInfo { scheduling: Scheduling::Always }, + vec![2; 3], + vec![2; 3], + )); + + let orig_bal = Balances::free_balance(&3u64); + // Register a new parathread + assert_ok!(Registrar::register_parathread( + Origin::signed(3u64), + vec![3; 3], + vec![3; 3], + )); + // deposit should be taken (reserved) + assert_eq!(Balances::free_balance(&3u64) + ParathreadDeposit::get(), orig_bal); + assert_eq!(Balances::reserved_balance(&3u64), ParathreadDeposit::get()); + + run_to_block(3); + + // New paras are registered + assert_eq!(Registrar::active_paras(), vec![(1u32.into(), None), (2u32.into(), None)]); + assert_eq!( + Registrar::paras(&ParaId::from(2u32)), + Some(ParaInfo { scheduling: Scheduling::Always }) + ); + assert_eq!( + Registrar::paras(&user_id(0)), + Some(ParaInfo { scheduling: Scheduling::Dynamic }) + ); + assert_eq!(Parachains::parachain_code(&ParaId::from(2u32)), Some(vec![2; 3])); + assert_eq!(Parachains::parachain_code(&user_id(0)), Some(vec![3; 3])); + + assert_ok!(Registrar::deregister_para(Origin::ROOT, 2u32.into())); + assert_ok!(Registrar::deregister_parathread( + parachains::Origin::Parachain(user_id(0)).into() + )); + // reserved balance should be returned. + assert_eq!(Balances::free_balance(&3u64), orig_bal); + assert_eq!(Balances::reserved_balance(&3u64), 0); + + run_to_block(4); + + assert_eq!(Registrar::active_paras(), vec![(1u32.into(), None)]); + assert_eq!(Registrar::paras(&ParaId::from(2u32)), None); + assert_eq!(Parachains::parachain_code(&ParaId::from(2u32)), None); + assert_eq!(Registrar::paras(&user_id(0)), None); + assert_eq!(Parachains::parachain_code(&user_id(0)), None); + }); + } + + #[test] + fn parathread_scheduling_works() { + new_test_ext(vec![]).execute_with(|| { + assert_ok!(Registrar::set_thread_count(Origin::ROOT, 1)); + + run_to_block(2); + + // Register a new parathread + assert_ok!(Registrar::register_parathread( + Origin::signed(3u64), + vec![3; 3], + vec![3; 3], + )); + + run_to_block(3); + + // transaction submitted to get parathread progressed. + let col = Sr25519Keyring::One.public().into(); + schedule_thread(user_id(0), &[3; 3], &col); + + run_to_block(5); + assert_eq!(Registrar::active_paras(), vec![ + (user_id(0), Some((col.clone(), Retriable::WithRetries(0)))) + ]); + assert_ok!(Parachains::set_heads(Origin::NONE, vec![ + attest(user_id(0), &Sr25519Keyring::One.pair().into(), &[3; 3], &[0; 0]) + ])); + + run_to_block(6); + // at next block, it shouldn't be retried. + assert_eq!(Registrar::active_paras(), vec![]); + }); + } + + #[test] + fn removing_scheduled_parathread_works() { + new_test_ext(vec![]).execute_with(|| { + assert_ok!(Registrar::set_thread_count(Origin::ROOT, 1)); + + run_to_block(2); + + // Register some parathreads. + assert_ok!(Registrar::register_parathread(Origin::signed(3), vec![3; 3], vec![3; 3])); + + run_to_block(3); + // transaction submitted to get parathread progressed. + let col = Sr25519Keyring::One.public().into(); + schedule_thread(user_id(0), &[3; 3], &col); + + // now we remove the parathread + assert_ok!(Registrar::deregister_parathread( + parachains::Origin::Parachain(user_id(0)).into() + )); + + run_to_block(5); + assert_eq!(Registrar::active_paras(), vec![]); // should not be scheduled. + + assert_ok!(Registrar::register_parathread(Origin::signed(3), vec![4; 3], vec![4; 3])); + + run_to_block(6); + // transaction submitted to get parathread progressed. + schedule_thread(user_id(1), &[4; 3], &col); + + run_to_block(9); + // thread's slot was missed and is now being re-scheduled. + + assert_ok!(Registrar::deregister_parathread( + parachains::Origin::Parachain(user_id(1)).into() + )); + + run_to_block(10); + // thread's rescheduled slot was missed, but should not be reschedule since it was + // removed. + assert_eq!(Registrar::active_paras(), vec![]); // should not be scheduled. + }); + } + + #[test] + fn parathread_rescheduling_works() { + new_test_ext(vec![]).execute_with(|| { + assert_ok!(Registrar::set_thread_count(Origin::ROOT, 1)); + + run_to_block(2); + + // Register some parathreads. + assert_ok!(Registrar::register_parathread(Origin::signed(3), vec![3; 3], vec![3; 3])); + assert_ok!(Registrar::register_parathread(Origin::signed(4), vec![4; 3], vec![4; 3])); + assert_ok!(Registrar::register_parathread(Origin::signed(5), vec![5; 3], vec![5; 3])); + + run_to_block(3); + + // transaction submitted to get parathread progressed. + let col = Sr25519Keyring::One.public().into(); + schedule_thread(user_id(0), &[3; 3], &col); + + // 4x: the initial time it was scheduled, plus 3 retries. + for n in 5..9 { + run_to_block(n); + assert_eq!(Registrar::active_paras(), vec![ + (user_id(0), Some((col.clone(), Retriable::WithRetries((n - 5) as u32)))) + ]); + } + + // missed too many times. dropped. + run_to_block(9); + assert_eq!(Registrar::active_paras(), vec![]); + + // schedule and miss all 3 and check that they go through the queueing system ok. + assert_ok!(Registrar::set_thread_count(Origin::ROOT, 2)); + schedule_thread(user_id(0), &[3; 3], &col); + schedule_thread(user_id(1), &[4; 3], &col); + + run_to_block(10); + schedule_thread(user_id(2), &[5; 3], &col); + + // 0 and 1 scheduled as normal. + run_to_block(11); + assert_eq!(Registrar::active_paras(), vec![ + (user_id(0), Some((col.clone(), Retriable::WithRetries(0)))), + (user_id(1), Some((col.clone(), Retriable::WithRetries(0)))) + ]); + + // 2 scheduled, 0 retried + run_to_block(12); + assert_eq!(Registrar::active_paras(), vec![ + (user_id(0), Some((col.clone(), Retriable::WithRetries(1)))), + (user_id(2), Some((col.clone(), Retriable::WithRetries(0)))), + ]); + + // 1 retried + run_to_block(13); + assert_eq!(Registrar::active_paras(), vec![ + (user_id(1), Some((col.clone(), Retriable::WithRetries(1)))) + ]); + + // 2 retried + run_to_block(14); + assert_eq!(Registrar::active_paras(), vec![ + (user_id(2), Some((col.clone(), Retriable::WithRetries(1)))) + ]); + + run_to_block(15); + assert_eq!(Registrar::active_paras(), vec![ + (user_id(0), Some((col.clone(), Retriable::WithRetries(2)))) + ]); + + run_to_block(16); + assert_eq!(Registrar::active_paras(), vec![ + (user_id(1), Some((col.clone(), Retriable::WithRetries(2)))) + ]); + + run_to_block(17); + assert_eq!(Registrar::active_paras(), vec![ + (user_id(2), Some((col.clone(), Retriable::WithRetries(2)))) + ]); + }); + } + + #[test] + fn parathread_auction_handles_basic_errors() { + new_test_ext(vec![]).execute_with(|| { + run_to_block(2); + let o = Origin::signed(0); + assert_ok!(Registrar::register_parathread(o, vec![7, 8, 9], vec![1, 1, 1])); + + run_to_block(3); + assert_eq!( + Registrar::paras(&user_id(0)), + Some(ParaInfo { scheduling: Scheduling::Dynamic }) + ); + + let good_para_id = user_id(0); + let bad_para_id = user_id(1); + let bad_head_hash = ::Hashing::hash(&vec![1, 2, 1]); + let good_head_hash = ::Hashing::hash(&vec![1, 1, 1]); + let info = DispatchInfo::default(); + + // Allow for threads + assert_ok!(Registrar::set_thread_count(Origin::ROOT, 10)); + + // Bad parathread id + let col = CollatorId::default(); + let inner = super::Call::select_parathread(bad_para_id, col.clone(), good_head_hash); + let call = Call::Registrar(inner); + assert!( + LimitParathreadCommits::(std::marker::PhantomData) + .validate(&0, &call, info, 0).is_err() + ); + + // Bad head data + let inner = super::Call::select_parathread(good_para_id, col.clone(), bad_head_hash); + let call = Call::Registrar(inner); + assert!( + LimitParathreadCommits::(std::marker::PhantomData) + .validate(&0, &call, info, 0).is_err() + ); + + // No duplicates + let inner = super::Call::select_parathread(good_para_id, col.clone(), good_head_hash); + let call = Call::Registrar(inner); + assert!( + LimitParathreadCommits::(std::marker::PhantomData) + .validate(&0, &call, info, 0).is_ok() + ); + assert!( + LimitParathreadCommits::(std::marker::PhantomData) + .validate(&0, &call, info, 0).is_err() + ); + }); + } + + #[test] + fn parathread_auction_works() { + new_test_ext(vec![]).execute_with(|| { + run_to_block(2); + // Register 5 parathreads + for x in 0..5 { + let o = Origin::signed(x as u64); + assert_ok!(Registrar::register_parathread(o, vec![x; 3], vec![x; 3])); + } + + run_to_block(3); + + for x in 0..5 { + assert_eq!( + Registrar::paras(&user_id(x)), + Some(ParaInfo { scheduling: Scheduling::Dynamic }) + ); + } + + // Only 3 slots available... who will win?? + assert_ok!(Registrar::set_thread_count(Origin::ROOT, 3)); + + // Everyone wants a thread + for x in 0..5 { + let para_id = user_id(x as u32); + let collator_id = CollatorId::default(); + let head_hash = ::Hashing::hash(&vec![x; 3]); + let inner = super::Call::select_parathread(para_id, collator_id, head_hash); + let call = Call::Registrar(inner); + let info = DispatchInfo::default(); + + // First 3 transactions win a slot + if x < 3 { + assert!( + LimitParathreadCommits::(std::marker::PhantomData) + .validate(&0, &call, info, 0) + .is_ok() + ); + } else { + // All others lose + assert_noop!( + LimitParathreadCommits::(std::marker::PhantomData) + .validate(&0, &call, info, 0), + InvalidTransaction::ExhaustsResources.into() + ); + } + } + + // 3 Threads are selected + assert_eq!( + SelectedThreads::get()[1], + vec![ + (user_id(0), CollatorId::default()), + (user_id(1), CollatorId::default()), + (user_id(2), CollatorId::default()), + ] + ); + + // Assuming Queue Size is 2 + assert_eq!(::QueueSize::get(), 2); + + // 2 blocks later + run_to_block(5); + // Threads left queue + assert_eq!(SelectedThreads::get()[0], vec![]); + // Threads are active + assert_eq!( + Registrar::active_paras(), + vec![ + (user_id(0), Some((CollatorId::default(), Retriable::WithRetries(0)))), + (user_id(1), Some((CollatorId::default(), Retriable::WithRetries(0)))), + (user_id(2), Some((CollatorId::default(), Retriable::WithRetries(0)))), + ] + ); + }); + } +} diff --git a/runtime/src/slots.rs b/runtime/src/slots.rs index 95811f19495f..20408e24454a 100644 --- a/runtime/src/slots.rs +++ b/runtime/src/slots.rs @@ -19,20 +19,21 @@ //! information for commissioning and decommissioning them. use rstd::{prelude::*, mem::swap, convert::TryInto}; -use sr_primitives::traits::{CheckedSub, StaticLookup, Zero, One, CheckedConversion, Hash}; +use sr_primitives::traits::{CheckedSub, StaticLookup, Zero, One, CheckedConversion, Hash, AccountIdConversion}; use sr_primitives::weights::SimpleDispatchInfo; -use codec::{Encode, Decode}; +use codec::{Encode, Decode, Codec}; use srml_support::{ decl_module, decl_storage, decl_event, ensure, traits::{Currency, ReservableCurrency, WithdrawReason, ExistenceRequirement, Get, Randomness}, }; -use primitives::parachain::AccountIdConversion; -use crate::parachains::ParachainRegistrar; +use primitives::parachain::{ + SwapAux, PARACHAIN_INFO, Id as ParaId +}; use system::{ensure_signed, ensure_root}; +use crate::registrar::{Registrar, swap_ordered_existence}; use crate::slot_range::{SlotRange, SLOT_RANGE_COUNT}; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -type ParaIdOf = <::Parachains as ParachainRegistrar<::AccountId>>::ParaId; /// The module's configuration trait. pub trait Trait: system::Trait { @@ -43,7 +44,7 @@ pub trait Trait: system::Trait { type Currency: ReservableCurrency; /// The parachain registrar type. - type Parachains: ParachainRegistrar; + type Parachains: Registrar; /// The number of blocks over which an auction may be retroactively ended. type EndingPeriod: Get; @@ -77,7 +78,7 @@ pub struct NewBidder { /// The desired target of a bidder in an auction. #[derive(Clone, Eq, PartialEq, Encode, Decode)] #[cfg_attr(feature = "std", derive(Debug))] -pub enum Bidder { +pub enum Bidder { /// An account ID, funds coming from that account. New(NewBidder), @@ -86,7 +87,7 @@ pub enum Bidder { Existing(ParaId), } -impl> Bidder { +impl Bidder { /// Get the account that will fund this bid. fn funding_account(&self) -> AccountId { match self { @@ -113,10 +114,12 @@ pub enum IncomingParachain { type LeasePeriodOf = ::BlockNumber; // Winning data type. This encodes the top bidders of each range together with their bid. -type WinningData = [Option<(Bidder<::AccountId, ParaIdOf>, BalanceOf)>; SLOT_RANGE_COUNT]; +type WinningData = + [Option<(Bidder<::AccountId>, BalanceOf)>; SLOT_RANGE_COUNT]; // Winners data type. This encodes each of the final winners of a parachain auction, the parachain // index assigned to them, their winning bid and the range that they won. -type WinnersData = Vec<(Option::AccountId>>, ParaIdOf, BalanceOf, SlotRange)>; +type WinnersData = + Vec<(Option::AccountId>>, ParaId, BalanceOf, SlotRange)>; // This module's storage items. decl_storage! { @@ -124,9 +127,9 @@ decl_storage! { /// The number of auctions that been started so far. pub AuctionCounter get(auction_counter): AuctionIndex; - /// All `ParaId` values that are managed by this module. This includes chains that are not - /// yet deployed (but have won an auction in the future). - pub ManagedIds get(managed_ids): Vec>; + /// Ordered list of all `ParaId` values that are managed by this module. This includes + /// chains that are not yet deployed (but have won an auction in the future). + pub ManagedIds get(managed_ids): Vec; /// Various amounts on deposit for each parachain. An entry in `ManagedIds` implies a non- /// default entry here. @@ -141,7 +144,7 @@ decl_storage! { /// If a parachain doesn't exist *yet* but is scheduled to exist in the future, then it /// will be left-padded with one or more zeroes to denote the fact that nothing is held on /// deposit for the non-existent chain currently, but is held at some point in the future. - pub Deposits get(deposits): map ParaIdOf => Vec>; + pub Deposits get(deposits): map ParaId => Vec>; /// Information relating to the current auction, if there is one. /// @@ -157,22 +160,37 @@ decl_storage! { /// Amounts currently reserved in the accounts of the bidders currently winning /// (sub-)ranges. - pub ReservedAmounts get(reserved_amounts): map Bidder> => Option>; + pub ReservedAmounts get(reserved_amounts): map Bidder => Option>; /// The set of Para IDs that have won and need to be on-boarded at an upcoming lease-period. /// This is cleared out on the first block of the lease period. - pub OnboardQueue get(onboard_queue): map LeasePeriodOf => Vec>; + pub OnboardQueue get(onboard_queue): map LeasePeriodOf => Vec; /// The actual on-boarding information. Only exists when one of the following is true: /// - It is before the lease period that the parachain should be on-boarded. /// - The full on-boarding information has not yet been provided and the parachain is not /// yet due to be off-boarded. - pub Onboarding get(onboarding): map ParaIdOf => + pub Onboarding get(onboarding): map ParaId => Option<(LeasePeriodOf, IncomingParachain)>; /// Off-boarding account; currency held on deposit for the parachain gets placed here if the /// parachain gets off-boarded; i.e. its lease period is up and it isn't renewed. - pub Offboarding get(offboarding): map ParaIdOf => T::AccountId; + pub Offboarding get(offboarding): map ParaId => T::AccountId; + } +} + +impl SwapAux for Module { + fn ensure_can_swap(one: ParaId, other: ParaId) -> Result<(), &'static str> { + if >::exists(one) || >::exists(other) { + Err("can't swap an undeployed parachain")? + } + Ok(()) + } + fn on_swap(one: ParaId, other: ParaId) -> Result<(), &'static str> { + >::swap(one, other); + >::swap(one, other); + ManagedIds::mutate(|ids| swap_ordered_existence(ids, one, other)); + Ok(()) } } @@ -181,7 +199,7 @@ decl_event!( AccountId = ::AccountId, BlockNumber = ::BlockNumber, LeasePeriod = LeasePeriodOf, - ParaId = ParaIdOf, + ParaId = ParaId, Balance = BalanceOf, { /// A new lease period is beginning. @@ -283,7 +301,7 @@ decl_module! { /// - `amount` is the amount to bid to be held as deposit for the parachain should the /// bid win. This amount is held throughout the range. #[weight = SimpleDispatchInfo::FixedNormal(500_000)] - fn bid(origin, + pub fn bid(origin, #[compact] sub: SubId, #[compact] auction_index: AuctionIndex, #[compact] first_slot: LeasePeriodOf, @@ -310,7 +328,7 @@ decl_module! { /// absolute lease period index value, not an auction-specific offset. /// - `amount` is the amount to bid to be held as deposit for the parachain should the /// bid win. This amount is held throughout the range. - #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(500_000)] fn bid_renew(origin, #[compact] auction_index: AuctionIndex, #[compact] first_slot: LeasePeriodOf, @@ -318,7 +336,7 @@ decl_module! { #[compact] amount: BalanceOf ) { let who = ensure_signed(origin)?; - let para_id = >::try_from_account(&who) + let para_id = ::try_from_account(&who) .ok_or("account is not a parachain")?; let bidder = Bidder::Existing(para_id); Self::handle_bid(bidder, auction_index, first_slot, last_slot, amount)?; @@ -330,10 +348,10 @@ decl_module! { /// /// - `dest` is the destination account to receive the parachain's deposit. #[weight = SimpleDispatchInfo::FixedNormal(1_000_000)] - fn set_offboarding(origin, dest: ::Source) { + pub fn set_offboarding(origin, dest: ::Source) { let who = ensure_signed(origin)?; let dest = T::Lookup::lookup(dest)?; - let para_id = >::try_from_account(&who) + let para_id = ::try_from_account(&who) .ok_or("not a parachain origin")?; >::insert(para_id, dest); } @@ -345,10 +363,10 @@ decl_module! { /// - `para_id` is the parachain ID allotted to the winning bidder. /// - `code_hash` is the hash of the parachain's Wasm validation function. /// - `initial_head_data` is the parachain's initial head data. - #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + #[weight = SimpleDispatchInfo::FixedNormal(500_000)] pub fn fix_deploy_data(origin, #[compact] sub: SubId, - #[compact] para_id: ParaIdOf, + #[compact] para_id: ParaId, code_hash: T::Hash, initial_head_data: Vec ) { @@ -377,7 +395,7 @@ decl_module! { /// - `para_id` is the parachain ID whose code will be elaborated. /// - `code` is the preimage of the registered `code_hash` of `para_id`. #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] - fn elaborate_deploy_data(_origin, #[compact] para_id: ParaIdOf, code: Vec) { + pub fn elaborate_deploy_data(_origin, #[compact] para_id: ParaId, code: Vec) { let (starts, details) = >::get(¶_id) .ok_or("parachain id not in onboarding")?; if let IncomingParachain::Fixed{code_hash, initial_head_data} = details { @@ -390,7 +408,8 @@ decl_module! { // Should have already begun. Remove the on-boarding entry and register the // parachain for its immediate start. >::remove(¶_id); - let _ = T::Parachains::register_parachain(para_id, code, initial_head_data); + let _ = T::Parachains:: + register_para(para_id, PARACHAIN_INFO, code, initial_head_data); } } else { return Err("deploy data not yet fixed") @@ -401,7 +420,7 @@ decl_module! { impl Module { /// Deposit currently held for a particular parachain that we administer. - fn deposit_held(para_id: &ParaIdOf) -> BalanceOf { + fn deposit_held(para_id: &ParaId) -> BalanceOf { >::get(para_id).into_iter().max().unwrap_or_else(Zero::zero) } @@ -495,8 +514,14 @@ impl Module { // Add para IDs of any chains that will be newly deployed to our set of managed // IDs. - >::mutate(|m| m.push(para_id)); - + ManagedIds::mutate(|ids| + if let Err(pos) = ids.binary_search(¶_id) { + ids.insert(pos, para_id) + } else { + // This can't happen as it's a winner being newly + // deployed and thus the para_id shouldn't already be being managed. + } + ); Self::deposit_event(RawEvent::WonDeploy(bidder.clone(), range, para_id, amount)); // Add a deployment record so we know to on-board them at the appropriate @@ -575,7 +600,7 @@ impl Module { Self::deposit_event(RawEvent::NewLeasePeriod(lease_period_index)); // First, bump off old deposits and decommission any managed chains that are coming // to a close. - >::mutate(|ids| { + ManagedIds::mutate(|ids| { let new = ids.drain(..).filter(|id| { let mut d = >::get(id); if !d.is_empty() { @@ -588,7 +613,7 @@ impl Module { // Only unregister it if it was actually registered in the first place. // If the on-boarding entry still existed, then it was never actually // commissioned. - let _ = T::Parachains::deregister_parachain(id.clone()); + let _ = T::Parachains::deregister_para(id.clone()); } // Return the full deposit to the off-boarding account. T::Currency::deposit_creating(&>::take(id), d[0]); @@ -630,7 +655,8 @@ impl Module { { // The chain's deployment data is set; go ahead and register it, and remove the // now-redundant on-boarding entry. - let _ = T::Parachains::register_parachain(para_id.clone(), code, initial_head_data); + let _ = T::Parachains:: + register_para(para_id.clone(), PARACHAIN_INFO, code, initial_head_data); // ^^ not much we can do if it fails for some reason. >::remove(para_id) } @@ -646,7 +672,7 @@ impl Module { /// - `last_slot`: The last lease period index of the range to be bid on (inclusive). /// - `amount`: The total amount to be the bid for deposit over the range. pub fn handle_bid( - bidder: Bidder>, + bidder: Bidder, auction_index: u32, first_slot: LeasePeriodOf, last_slot: LeasePeriodOf, @@ -737,7 +763,7 @@ impl Module { /// https://github.com/w3f/consensus/blob/master/NPoS/auctiondynamicthing.py fn calculate_winners( mut winning: WinningData, - new_id: impl Fn() -> ParaIdOf + new_id: impl Fn() -> ParaId ) -> WinnersData { let winning_ranges = { let mut best_winners_ending_at: @@ -785,7 +811,6 @@ impl Module { } } - /// tests for this module #[cfg(test)] mod tests { @@ -799,7 +824,7 @@ mod tests { }; use srml_support::{impl_outer_origin, parameter_types, assert_ok, assert_noop}; use balances; - use primitives::parachain::Id as ParaId; + use primitives::parachain::{Id as ParaId, Info as ParaInfo}; impl_outer_origin! { pub enum Origin for Test {} @@ -859,33 +884,33 @@ mod tests { } pub struct TestParachains; - impl ParachainRegistrar for TestParachains { - type ParaId = ParaId; - fn new_id() -> Self::ParaId { + impl Registrar for TestParachains { + fn new_id() -> ParaId { PARACHAIN_COUNT.with(|p| { *p.borrow_mut() += 1; (*p.borrow() - 1).into() }) } - fn register_parachain( - id: Self::ParaId, + fn register_para( + id: ParaId, + _info: ParaInfo, code: Vec, initial_head_data: Vec ) -> Result<(), &'static str> { PARACHAINS.with(|p| { - if p.borrow().contains_key(&id.into_inner()) { + if p.borrow().contains_key(&id.into()) { panic!("ID already exists") } - p.borrow_mut().insert(id.into_inner(), (code, initial_head_data)); + p.borrow_mut().insert(id.into(), (code, initial_head_data)); Ok(()) }) } - fn deregister_parachain(id: Self::ParaId) -> Result<(), &'static str> { + fn deregister_para(id: ParaId) -> Result<(), &'static str> { PARACHAINS.with(|p| { - if !p.borrow().contains_key(&id.into_inner()) { + if !p.borrow().contains_key(&id.into()) { panic!("ID doesn't exist") } - p.borrow_mut().remove(&id.into_inner()); + p.borrow_mut().remove(&id.into()); Ok(()) }) } @@ -1342,8 +1367,8 @@ mod tests { assert_eq!(Slots::onboard_queue(2), vec![]); assert_eq!(Slots::onboard_queue(3), vec![]); assert_eq!(Slots::onboard_queue(4), vec![0.into()]); - assert_eq!(Slots::onboarding( - ParaId::from(0)), + assert_eq!( + Slots::onboarding(ParaId::from(0)), Some((4, IncomingParachain::Unset(NewBidder { who: 1, sub: 0 }))) ); assert_eq!(Slots::deposit_held(&0.into()), 5); @@ -1396,8 +1421,8 @@ mod tests { run_to_block(9); assert_eq!(Slots::onboard_queue(1), vec![0.into()]); - assert_eq!(Slots::onboarding( - ParaId::from(0)), + assert_eq!( + Slots::onboarding(ParaId::from(0)), Some((1, IncomingParachain::Unset(NewBidder { who: 3, sub: 0 }))) ); assert_eq!(Slots::deposit_held(&0.into()), 3); diff --git a/runtime/src/testing.rs b/runtime/src/testing.rs new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/service/Cargo.toml b/service/Cargo.toml index 04448a897be4..68e6f9ecbbb1 100644 --- a/service/Cargo.toml +++ b/service/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polkadot-service" -version = "0.6.2" +version = "0.6.3" authors = ["Parity Technologies "] edition = "2018" @@ -37,5 +37,6 @@ substrate-keystore = { git = "https://github.com/paritytech/substrate", branch = srml-babe = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } srml-staking = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } im-online = { package = "srml-im-online", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } +authority-discovery = { package = "substrate-authority-discovery", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } babe = { package = "substrate-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } babe-primitives = { package = "substrate-consensus-babe-primitives", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" } diff --git a/service/src/chain_spec.rs b/service/src/chain_spec.rs index b1dee37ea82b..68d4bd0056a4 100644 --- a/service/src/chain_spec.rs +++ b/service/src/chain_spec.rs @@ -16,16 +16,16 @@ //! Polkadot chain configurations. -use primitives::{Pair, Public, crypto::UncheckedInto}; -use polkadot_primitives::{AccountId, parachain::ValidatorId}; +use primitives::{Pair, Public, crypto::UncheckedInto, sr25519}; +use polkadot_primitives::{AccountId, AccountPublic, parachain::ValidatorId}; use polkadot_runtime::{ - GenesisConfig, CouncilConfig, ElectionsConfig, DemocracyConfig, SystemConfig, + GenesisConfig, CouncilConfig, ElectionsPhragmenConfig, DemocracyConfig, SystemConfig, SessionConfig, StakingConfig, BalancesConfig, SessionKeys, TechnicalCommitteeConfig, SudoConfig, IndicesConfig, StakerStatus, WASM_BINARY, - ClaimsConfig, ParachainsConfig + ClaimsConfig, ParachainsConfig, RegistrarConfig }; use polkadot_runtime::constants::{currency::DOTS, time::*}; -use sr_primitives::Perbill; +use sr_primitives::{traits::IdentifyAccount, Perbill}; use telemetry::TelemetryEndpoints; use hex_literal::hex; use babe_primitives::AuthorityId as BabeId; @@ -55,7 +55,7 @@ fn session_keys( fn staging_testnet_config_genesis() -> GenesisConfig { // subkey inspect "$SECRET" let endowed_accounts = vec![ - hex!["12b782529c22032ed4694e0f6e7d486be7daa6d12088f6bc74d593b3900b8438"].unchecked_into(), // 5CVFESwfkk7NmhQ6FwHCM9roBvr9BGa4vJHFYU8DnGQxrXvz + hex!["12b782529c22032ed4694e0f6e7d486be7daa6d12088f6bc74d593b3900b8438"].into(), // 5CVFESwfkk7NmhQ6FwHCM9roBvr9BGa4vJHFYU8DnGQxrXvz ]; // for i in 1 2 3 4; do for j in stash controller; do subkey inspect "$SECRET//$i//$j"; done; done @@ -64,29 +64,29 @@ fn staging_testnet_config_genesis() -> GenesisConfig { // for i in 1 2 3 4; do for j in im_online; do subkey --sr25519 inspect "$SECRET//$i//$j"; done; done // for i in 1 2 3 4; do for j in parachains; do subkey --sr25519 inspect "$SECRET//$i//$j"; done; done let initial_authorities: Vec<(AccountId, AccountId, BabeId, GrandpaId, ImOnlineId, ValidatorId)> = vec![( - hex!["32a5718e87d16071756d4b1370c411bbbb947eb62f0e6e0b937d5cbfc0ea633b"].unchecked_into(), // 5DD7Q4VEfPTLEdn11CnThoHT5f9xKCrnofWJL5SsvpTghaAT - hex!["bee39fe862c85c91aaf343e130d30b643c6ea0b4406a980206f1df8331f7093b"].unchecked_into(), // 5GNzaEqhrZAtUQhbMe2gn9jBuNWfamWFZHULryFwBUXyd1cG + hex!["32a5718e87d16071756d4b1370c411bbbb947eb62f0e6e0b937d5cbfc0ea633b"].into(), // 5DD7Q4VEfPTLEdn11CnThoHT5f9xKCrnofWJL5SsvpTghaAT + hex!["bee39fe862c85c91aaf343e130d30b643c6ea0b4406a980206f1df8331f7093b"].into(), // 5GNzaEqhrZAtUQhbMe2gn9jBuNWfamWFZHULryFwBUXyd1cG hex!["a639b507ee1585e0b6498ff141d6153960794523226866d1b44eba3f25f36356"].unchecked_into(), // 5FpewyS2VY8Cj3tKgSckq8ECkjd1HKHvBRnWhiHqRQsWfFC1 hex!["76620f7c98bce8619979c2b58cf2b0aff71824126d2b039358729dad993223db"].unchecked_into(), // 5EjvdwATjyFFikdZibVvx1q5uBHhphS2Mnsq5c7yfaYK25vm hex!["a639b507ee1585e0b6498ff141d6153960794523226866d1b44eba3f25f36356"].unchecked_into(), // 5FpewyS2VY8Cj3tKgSckq8ECkjd1HKHvBRnWhiHqRQsWfFC1 hex!["a639b507ee1585e0b6498ff141d6153960794523226866d1b44eba3f25f36356"].unchecked_into(), // 5FpewyS2VY8Cj3tKgSckq8ECkjd1HKHvBRnWhiHqRQsWfFC1 ),( - hex!["b496c98a405ceab59b9e970e59ef61acd7765a19b704e02ab06c1cdfe171e40f"].unchecked_into(), // 5G9VGb8ESBeS8Ca4or43RfhShzk9y7T5iTmxHk5RJsjZwsRx - hex!["86d3a7571dd60139d297e55d8238d0c977b2e208c5af088f7f0136b565b0c103"].unchecked_into(), // 5F7V9Y5FcxKXe1aroqvPeRiUmmeQwTFcL3u9rrPXcMuMiCNx + hex!["b496c98a405ceab59b9e970e59ef61acd7765a19b704e02ab06c1cdfe171e40f"].into(), // 5G9VGb8ESBeS8Ca4or43RfhShzk9y7T5iTmxHk5RJsjZwsRx + hex!["86d3a7571dd60139d297e55d8238d0c977b2e208c5af088f7f0136b565b0c103"].into(), // 5F7V9Y5FcxKXe1aroqvPeRiUmmeQwTFcL3u9rrPXcMuMiCNx hex!["765e46067adac4d1fe6c783aa2070dfa64a19f84376659e12705d1734b3eae01"].unchecked_into(), // 5GvuM53k1Z4nAB5zXJFgkRSHv4Bqo4BsvgbQWNWkiWZTMwWY hex!["e2234d661bee4a04c38392c75d1566200aa9e6ae44dd98ee8765e4cc9af63cb7"].unchecked_into(), // 5HBDAaybNqjmY7ww8ZcZZY1L5LHxvpnyfqJwoB7HhR6raTmG hex!["765e46067adac4d1fe6c783aa2070dfa64a19f84376659e12705d1734b3eae01"].unchecked_into(), // 5GvuM53k1Z4nAB5zXJFgkRSHv4Bqo4BsvgbQWNWkiWZTMwWY hex!["765e46067adac4d1fe6c783aa2070dfa64a19f84376659e12705d1734b3eae01"].unchecked_into(), // 5GvuM53k1Z4nAB5zXJFgkRSHv4Bqo4BsvgbQWNWkiWZTMwWY ),( - hex!["ae12f70078a22882bf5135d134468f77301927aa67c376e8c55b7ff127ace115"].unchecked_into(), // 5FzwpgGvk2kk9agow6KsywLYcPzjYc8suKej2bne5G5b9YU3 - hex!["7addb914ec8486bbc60643d2647685dcc06373401fa80e09813b630c5831d54b"].unchecked_into(), // 5EqoZhVC2BcsM4WjvZNidu2muKAbu5THQTBKe3EjvxXkdP7A + hex!["ae12f70078a22882bf5135d134468f77301927aa67c376e8c55b7ff127ace115"].into(), // 5FzwpgGvk2kk9agow6KsywLYcPzjYc8suKej2bne5G5b9YU3 + hex!["7addb914ec8486bbc60643d2647685dcc06373401fa80e09813b630c5831d54b"].into(), // 5EqoZhVC2BcsM4WjvZNidu2muKAbu5THQTBKe3EjvxXkdP7A hex!["664eae1ca4713dd6abf8c15e6c041820cda3c60df97dc476c2cbf7cb82cb2d2e"].unchecked_into(), // 5CXNq1mSKJT4Sc2CbyBBdANeSkbUvdWvE4czJjKXfBHi9sX5 hex!["5b57ed1443c8967f461db1f6eb2ada24794d163a668f1cf9d9ce3235dfad8799"].unchecked_into(), // 5E8ULLQrDAtWhfnVfZmX41Yux86zNAwVJYguWJZVWrJvdhBe hex!["664eae1ca4713dd6abf8c15e6c041820cda3c60df97dc476c2cbf7cb82cb2d2e"].unchecked_into(), // 5CXNq1mSKJT4Sc2CbyBBdANeSkbUvdWvE4czJjKXfBHi9sX5 hex!["664eae1ca4713dd6abf8c15e6c041820cda3c60df97dc476c2cbf7cb82cb2d2e"].unchecked_into(), // 5CXNq1mSKJT4Sc2CbyBBdANeSkbUvdWvE4czJjKXfBHi9sX5 ),( - hex!["0867dbb49721126df589db100dda728dc3b475cbf414dad8f72a1d5e84897252"].unchecked_into(), // 5CFj6Kg9rmVn1vrqpyjau2ztyBzKeVdRKwNPiA3tqhB5HPqq - hex!["26ab2b4b2eba2263b1e55ceb48f687bb0018130a88df0712fbdaf6a347d50e2a"].unchecked_into(), // 5CwQXP6nvWzigFqNhh2jvCaW9zWVzkdveCJY3tz2MhXMjTon + hex!["0867dbb49721126df589db100dda728dc3b475cbf414dad8f72a1d5e84897252"].into(), // 5CFj6Kg9rmVn1vrqpyjau2ztyBzKeVdRKwNPiA3tqhB5HPqq + hex!["26ab2b4b2eba2263b1e55ceb48f687bb0018130a88df0712fbdaf6a347d50e2a"].into(), // 5CwQXP6nvWzigFqNhh2jvCaW9zWVzkdveCJY3tz2MhXMjTon hex!["2adb17a5cafbddc7c3e00ec45b6951a8b12ce2264235b4def342513a767e5d3d"].unchecked_into(), // 5FCd9Y7RLNyxz5wnCAErfsLbXGG34L2BaZRHzhiJcMUMd5zd hex!["e60d23f49e93c1c1f2d7c115957df5bbd7faf5ebf138d1e9d02e8b39a1f63df0"].unchecked_into(), // 5HGLmrZsiTFTPp3QoS1W8w9NxByt8PVq79reqvdxNcQkByqK hex!["2adb17a5cafbddc7c3e00ec45b6951a8b12ce2264235b4def342513a767e5d3d"].unchecked_into(), // 5FCd9Y7RLNyxz5wnCAErfsLbXGG34L2BaZRHzhiJcMUMd5zd @@ -138,11 +138,11 @@ fn staging_testnet_config_genesis() -> GenesisConfig { members: vec![], phantom: Default::default(), }), - elections: Some(ElectionsConfig { + elections_phragmen: Some(ElectionsPhragmenConfig { members: vec![], - presentation_duration: 1 * DAYS, term_duration: 49 * DAYS, - desired_seats: 7, + desired_members: 7, + desired_runners_up: 3, }), membership_Instance1: Some(Default::default()), babe: Some(Default::default()), @@ -150,6 +150,8 @@ fn staging_testnet_config_genesis() -> GenesisConfig { im_online: Some(Default::default()), parachains: Some(ParachainsConfig { authorities: vec![], + }), + registrar: Some(RegistrarConfig { parachains: vec![], _phdata: Default::default(), }), @@ -185,6 +187,13 @@ pub fn get_from_seed(seed: &str) -> ::Pu } +/// Helper function to generate an account ID from seed +pub fn get_account_id_from_seed(seed: &str) -> AccountId where + AccountPublic: From<::Public> +{ + AccountPublic::from(get_from_seed::(seed)).into_account() +} + /// Helper function to generate stash, controller and session key from seed pub fn get_authority_keys_from_seed(seed: &str) -> ( AccountId, @@ -195,8 +204,8 @@ pub fn get_authority_keys_from_seed(seed: &str) -> ( ValidatorId ) { ( - get_from_seed::(&format!("{}//stash", seed)), - get_from_seed::(seed), + get_account_id_from_seed::(&format!("{}//stash", seed)), + get_account_id_from_seed::(seed), get_from_seed::(seed), get_from_seed::(seed), get_from_seed::(seed), @@ -212,25 +221,25 @@ pub fn testnet_genesis( ) -> GenesisConfig { let endowed_accounts: Vec = endowed_accounts.unwrap_or_else(|| { vec![ - get_from_seed::("Alice"), - get_from_seed::("Bob"), - get_from_seed::("Charlie"), - get_from_seed::("Dave"), - get_from_seed::("Eve"), - get_from_seed::("Ferdie"), - get_from_seed::("Alice//stash"), - get_from_seed::("Bob//stash"), - get_from_seed::("Charlie//stash"), - get_from_seed::("Dave//stash"), - get_from_seed::("Eve//stash"), - get_from_seed::("Ferdie//stash"), + 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"), ] }); const ENDOWMENT: u128 = 1_000_000 * DOTS; const STASH: u128 = 100 * DOTS; - let desired_seats = (endowed_accounts.len() / 2 - initial_authorities.len()) as u32; + let desired_members = (endowed_accounts.len() / 2 - initial_authorities.len()) as u32; GenesisConfig { system: Some(SystemConfig { @@ -271,15 +280,16 @@ pub fn testnet_genesis( members: vec![], phantom: Default::default(), }), - elections: Some(ElectionsConfig { + elections_phragmen: Some(ElectionsPhragmenConfig { members: endowed_accounts.iter() .filter(|&endowed| initial_authorities.iter() .find(|&(_, controller, _, _, _, _)| controller == endowed) .is_none() - ).map(|a| (a.clone(), 1000000)).collect(), - presentation_duration: 10 * MINUTES, + ).cloned() + .collect(), term_duration: 1 * DAYS, - desired_seats, + desired_runners_up: desired_members / 2, + desired_members, }), membership_Instance1: Some(Default::default()), babe: Some(Default::default()), @@ -287,6 +297,8 @@ pub fn testnet_genesis( im_online: Some(Default::default()), parachains: Some(ParachainsConfig { authorities: vec![], + }), + registrar: Some(RegistrarConfig{ parachains: vec![], _phdata: Default::default(), }), @@ -305,7 +317,7 @@ fn development_config_genesis() -> GenesisConfig { vec![ get_authority_keys_from_seed("Alice"), ], - get_from_seed::("Alice"), + get_account_id_from_seed::("Alice"), None, ) } @@ -330,7 +342,7 @@ fn local_testnet_genesis() -> GenesisConfig { get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob"), ], - get_from_seed::("Alice"), + get_account_id_from_seed::("Alice"), None, ) } diff --git a/service/src/lib.rs b/service/src/lib.rs index 16c0239c44b1..c0b459131e6d 100644 --- a/service/src/lib.rs +++ b/service/src/lib.rs @@ -18,7 +18,7 @@ pub mod chain_spec; -use futures::prelude::*; +use futures::sync::mpsc; use client::LongestChain; use std::sync::Arc; use std::time::Duration; @@ -140,8 +140,10 @@ pub fn new_full(config: Configuration) CallExecutor = impl CallExecutor + Clone + Send + Sync + 'static, >, ServiceError> { - let is_authority = config.roles.is_authority(); + use substrate_network::DhtEvent; + let is_collator = config.custom.collating_for.is_some(); + let is_authority = config.roles.is_authority() && !is_collator; let force_authoring = config.force_authoring; let max_block_data_size = config.custom.max_block_data_size; let db_path = config.database_path.clone(); @@ -150,23 +152,24 @@ pub fn new_full(config: Configuration) let (builder, mut import_setup, inherent_data_providers) = new_full_start!(config); + // Dht event channel from the network to the authority discovery module. Use + // bounded channel to ensure back-pressure. Authority discovery is triggering one + // event per authority within the current authority set. This estimates the + // authority set size to be somewhere below 10 000 thereby setting the channel + // buffer size to 10 000. + let (dht_event_tx, _dht_event_rx) = mpsc::channel::(10000); + let service = builder .with_network_protocol(|config| Ok(PolkadotProtocol::new(config.custom.collating_for.clone())))? .with_finality_proof_provider(|client, backend| Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _) )? + .with_dht_event_tx(dht_event_tx)? .build()?; let (block_import, link_half, babe_link) = import_setup.take() .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); - if is_collator { - info!( - "The node cannot start as an authority because it is also configured to run as a collator." - ); - return Ok(service); - } - let client = service.client(); let known_oracle = client.clone(); let select_chain = if let Some(select_chain) = service.select_chain() { @@ -278,7 +281,7 @@ pub fn new_full(config: Configuration) let enable_grandpa = !disable_grandpa; if enable_grandpa { // start the full GRANDPA voter - // NOTE: unlike in polkadot/master we are currently running the full + // NOTE: unlike in substrate we are currently running the full // GRANDPA voter protocol for all full nodes (regardless of whether // they're validators or not). at this point the full voter should // provide better guarantees of block and vote data availability than diff --git a/statement-table/Cargo.toml b/statement-table/Cargo.toml index 3a5909e61b75..5f781f9c1619 100644 --- a/statement-table/Cargo.toml +++ b/statement-table/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polkadot-statement-table" -version = "0.6.2" +version = "0.6.3" authors = ["Parity Technologies "] edition = "2018" diff --git a/test-parachains/adder/Cargo.toml b/test-parachains/adder/Cargo.toml index ede61468a055..8b9b2679e168 100644 --- a/test-parachains/adder/Cargo.toml +++ b/test-parachains/adder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "adder" -version = "0.6.2" +version = "0.6.3" authors = ["Parity Technologies "] description = "Test parachain which adds to a number as its state transition" edition = "2018" @@ -8,7 +8,7 @@ build = "build.rs" [dependencies] parachain = { package = "polkadot-parachain", path = "../../parachain/", default-features = false, features = [ "wasm-api" ] } -codec = { package = "parity-scale-codec", version = "~1.0.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } tiny-keccak = "1.5.0" dlmalloc = { version = "0.1.3", features = [ "global" ] } diff --git a/test-parachains/adder/collator/Cargo.toml b/test-parachains/adder/collator/Cargo.toml index 4c4412f3db84..540a3505eebd 100644 --- a/test-parachains/adder/collator/Cargo.toml +++ b/test-parachains/adder/collator/Cargo.toml @@ -10,6 +10,7 @@ parachain = { package = "polkadot-parachain", path = "../../../parachain" } collator = { package = "polkadot-collator", path = "../../../collator" } primitives = { package = "polkadot-primitives", path = "../../../primitives" } substrate-primitives = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } +client = { package = "substrate-client", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } parking_lot = "0.9.0" ctrlc = { version = "3.0", features = ["termination"] } futures = "0.1" diff --git a/test-parachains/adder/collator/src/main.rs b/test-parachains/adder/collator/src/main.rs index 25352b161002..6803131b89e6 100644 --- a/test-parachains/adder/collator/src/main.rs +++ b/test-parachains/adder/collator/src/main.rs @@ -21,13 +21,17 @@ use std::collections::HashMap; use std::sync::Arc; use adder::{HeadData as AdderHead, BlockData as AdderBody}; -use substrate_primitives::Pair; +use substrate_primitives::{Pair, Blake2Hasher}; use parachain::codec::{Encode, Decode}; use primitives::{ - Hash, - parachain::{HeadData, BlockData, Id as ParaId, Message, OutgoingMessages, Status as ParachainStatus}, + Hash, Block, + parachain::{ + HeadData, BlockData, Id as ParaId, Message, OutgoingMessages, Status as ParachainStatus, + }, +}; +use collator::{ + InvalidHead, ParachainContext, VersionInfo, Network, BuildParachainContext, TaskExecutor, }; -use collator::{InvalidHead, ParachainContext, VersionInfo, Network, BuildParachainContext}; use parking_lot::Mutex; const GENESIS: AdderHead = AdderHead { @@ -56,7 +60,7 @@ impl ParachainContext for AdderContext { type ProduceCandidate = Result<(BlockData, HeadData, OutgoingMessages), InvalidHead>; fn produce_candidate>( - &self, + &mut self, _relay_parent: Hash, status: ParachainStatus, ingress: I, @@ -101,7 +105,16 @@ impl ParachainContext for AdderContext { impl BuildParachainContext for AdderContext { type ParachainContext = Self; - fn build(self, network: Arc) -> Result { + fn build( + self, + _: Arc>, + _: TaskExecutor, + network: Arc, + ) -> Result + where + B: client::backend::Backend + 'static, + E: client::CallExecutor + Clone + Send + Sync + 'static + { Ok(Self { _network: Some(network), ..self }) } } diff --git a/test-parachains/adder/wasm/Cargo.toml b/test-parachains/adder/wasm/Cargo.toml new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test-parachains/halt/Cargo.toml b/test-parachains/halt/Cargo.toml index 8327759270a9..76050455b098 100644 --- a/test-parachains/halt/Cargo.toml +++ b/test-parachains/halt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "halt" -version = "0.6.2" +version = "0.6.3" authors = ["Parity Technologies "] description = "Test parachain which executes forever" edition = "2018" diff --git a/validation/Cargo.toml b/validation/Cargo.toml index d178d828cb3b..cb11b604de1e 100644 --- a/validation/Cargo.toml +++ b/validation/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "polkadot-validation" -version = "0.6.2" +version = "0.6.3" authors = ["Parity Technologies "] edition = "2018" [dependencies] futures = "0.1.17" -futures03 = { package = "futures-preview", version = "0.3.0-alpha.19", features = ["compat"] } +futures03 = { package = "futures-preview", version = "0.3.0-alpha.18", features = ["compat"] } futures-timer = "0.4.0" parking_lot = "0.9.0" tokio = "0.1.7" diff --git a/validation/src/evaluation.rs b/validation/src/evaluation.rs index 0099f489a092..778a735925fe 100644 --- a/validation/src/evaluation.rs +++ b/validation/src/evaluation.rs @@ -20,7 +20,7 @@ use super::MAX_TRANSACTIONS_SIZE; use codec::Encode; use polkadot_primitives::{Block, Hash, BlockNumber}; -use polkadot_primitives::parachain::Id as ParaId; +use polkadot_primitives::parachain::{Id as ParaId, CollatorId, Retriable}; /// Result type alias for block evaluation pub type Result = std::result::Result; @@ -66,7 +66,7 @@ pub fn evaluate_initial( _now: u64, parent_hash: &Hash, parent_number: BlockNumber, - _active_parachains: &[ParaId], + _active_parachains: &[(ParaId, Option<(CollatorId, Retriable)>)], ) -> Result<()> { let transactions_size = proposal.extrinsics.iter().fold(0, |a, tx| { a + Encode::encode(tx).len() diff --git a/validation/src/lib.rs b/validation/src/lib.rs index ddf6d538dc64..8382ec0a0342 100644 --- a/validation/src/lib.rs +++ b/validation/src/lib.rs @@ -763,7 +763,7 @@ impl CreateProposal where self.believed_minimum_timestamp, &self.parent_hash, self.parent_number, - &active_parachains, + &active_parachains[..], ).is_ok()); Ok(new_block)