elections-phragmen: renounce candidacy [+ remove dead code] (#4123)

* new elections phragmen module.

* Bump

* rename typo

* Few nits

* Fix runner outgoing bond

* remove useused var

* Fix refund logic.

* Update doc.

* Update lock
This commit is contained in:
Kian Paimani
2019-11-23 18:10:30 +01:00
committed by Gavin Wood
parent c9175b59ff
commit 1c9316a6c1
2 changed files with 598 additions and 382 deletions
+200 -200
View File
@@ -1263,6 +1263,181 @@ dependencies = [
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "frame-executive"
version = "2.0.0"
dependencies = [
"frame-support 2.0.0",
"frame-system 2.0.0",
"hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pallet-balances 2.0.0",
"pallet-indices 2.0.0",
"pallet-transaction-payment 2.0.0",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
"substrate-primitives 2.0.0",
]
[[package]]
name = "frame-metadata"
version = "2.0.0"
dependencies = [
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-std 2.0.0",
"substrate-primitives 2.0.0",
]
[[package]]
name = "frame-support"
version = "2.0.0"
dependencies = [
"bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-metadata 2.0.0",
"frame-support-procedural 2.0.0",
"frame-system 2.0.0",
"impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"once_cell 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-arithmetic 2.0.0",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
"substrate-inherents 2.0.0",
"substrate-primitives 2.0.0",
"substrate-state-machine 2.0.0",
"tracing 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "frame-support-procedural"
version = "2.0.0"
dependencies = [
"frame-support-procedural-tools 2.0.0",
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "frame-support-procedural-tools"
version = "2.0.0"
dependencies = [
"frame-support-procedural-tools-derive 2.0.0",
"proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "frame-support-procedural-tools-derive"
version = "2.0.0"
dependencies = [
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "frame-support-rpc"
version = "2.0.0"
dependencies = [
"frame-support 2.0.0",
"frame-system 2.0.0",
"futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-client-transports 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"substrate-primitives-storage 2.0.0",
"substrate-rpc-api 2.0.0",
"tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "frame-support-test"
version = "2.0.0"
dependencies = [
"frame-support 2.0.0",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"substrate-inherents 2.0.0",
"substrate-primitives 2.0.0",
"substrate-state-machine 2.0.0",
"trybuild 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "frame-system"
version = "2.0.0"
dependencies = [
"criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-support 2.0.0",
"impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.1.0 (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.102 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
"sr-version 2.0.0",
"substrate-primitives 2.0.0",
]
[[package]]
name = "frame-system-rpc"
version = "2.0.0"
dependencies = [
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-system-rpc-runtime-api 2.0.0",
"futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core-client 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-derive 14.0.3 (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.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 2.0.0",
"substrate-client 2.0.0",
"substrate-primitives 2.0.0",
"substrate-test-runtime-client 2.0.0",
"substrate-transaction-pool 2.0.0",
]
[[package]]
name = "frame-system-rpc-runtime-api"
version = "2.0.0"
dependencies = [
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-api 2.0.0",
]
[[package]]
name = "frame-utility"
version = "2.0.0"
dependencies = [
"frame-support 2.0.0",
"frame-system 2.0.0",
"pallet-balances 2.0.0",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
"substrate-primitives 2.0.0",
]
[[package]]
name = "fs-swap"
version = "0.2.4"
@@ -2851,6 +3026,8 @@ dependencies = [
"console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"console_log 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-support 2.0.0",
"frame-system 2.0.0",
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2863,8 +3040,6 @@ dependencies = [
"node-primitives 2.0.0",
"node-rpc 2.0.0",
"node-runtime 2.0.0",
"frame-support 2.0.0",
"frame-system 2.0.0",
"pallet-authority-discovery 0.1.0",
"pallet-balances 2.0.0",
"pallet-contracts 2.0.0",
@@ -2919,11 +3094,11 @@ name = "node-executor"
version = "2.0.0"
dependencies = [
"criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-support 2.0.0",
"frame-system 2.0.0",
"node-primitives 2.0.0",
"node-runtime 2.0.0",
"node-testing 2.0.0",
"frame-support 2.0.0",
"frame-system 2.0.0",
"pallet-balances 2.0.0",
"pallet-contracts 2.0.0",
"pallet-grandpa 2.0.0",
@@ -2958,10 +3133,10 @@ dependencies = [
name = "node-rpc"
version = "2.0.0"
dependencies = [
"frame-system-rpc 2.0.0",
"jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"node-primitives 2.0.0",
"node-runtime 2.0.0",
"frame-system-rpc 2.0.0",
"pallet-contracts-rpc 2.0.0",
"pallet-transaction-payment-rpc 2.0.0",
"sr-primitives 2.0.0",
@@ -2986,13 +3161,13 @@ dependencies = [
name = "node-runtime"
version = "2.0.0"
dependencies = [
"integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"node-primitives 2.0.0",
"frame-executive 2.0.0",
"frame-support 2.0.0",
"frame-system 2.0.0",
"frame-system-rpc-runtime-api 2.0.0",
"frame-utility 2.0.0",
"integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"node-primitives 2.0.0",
"pallet-authority-discovery 0.1.0",
"pallet-authorship 0.1.0",
"pallet-babe 2.0.0",
@@ -3110,11 +3285,11 @@ dependencies = [
name = "node-testing"
version = "2.0.0"
dependencies = [
"frame-support 2.0.0",
"frame-system 2.0.0",
"node-executor 2.0.0",
"node-primitives 2.0.0",
"node-runtime 2.0.0",
"frame-support 2.0.0",
"frame-system 2.0.0",
"pallet-balances 2.0.0",
"pallet-contracts 2.0.0",
"pallet-grandpa 2.0.0",
@@ -3279,181 +3454,6 @@ dependencies = [
"stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "frame-executive"
version = "2.0.0"
dependencies = [
"hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-support 2.0.0",
"frame-system 2.0.0",
"pallet-balances 2.0.0",
"pallet-indices 2.0.0",
"pallet-transaction-payment 2.0.0",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
"substrate-primitives 2.0.0",
]
[[package]]
name = "frame-metadata"
version = "2.0.0"
dependencies = [
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-std 2.0.0",
"substrate-primitives 2.0.0",
]
[[package]]
name = "frame-support"
version = "2.0.0"
dependencies = [
"bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"once_cell 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-metadata 2.0.0",
"frame-support-procedural 2.0.0",
"frame-system 2.0.0",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-arithmetic 2.0.0",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
"substrate-inherents 2.0.0",
"substrate-primitives 2.0.0",
"substrate-state-machine 2.0.0",
"tracing 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "frame-support-procedural"
version = "2.0.0"
dependencies = [
"frame-support-procedural-tools 2.0.0",
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "frame-support-procedural-tools"
version = "2.0.0"
dependencies = [
"frame-support-procedural-tools-derive 2.0.0",
"proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "frame-support-procedural-tools-derive"
version = "2.0.0"
dependencies = [
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "frame-support-rpc"
version = "2.0.0"
dependencies = [
"futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-client-transports 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-support 2.0.0",
"frame-system 2.0.0",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"substrate-primitives-storage 2.0.0",
"substrate-rpc-api 2.0.0",
"tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "frame-support-test"
version = "2.0.0"
dependencies = [
"frame-support 2.0.0",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"substrate-inherents 2.0.0",
"substrate-primitives 2.0.0",
"substrate-state-machine 2.0.0",
"trybuild 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "frame-system"
version = "2.0.0"
dependencies = [
"criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-support 2.0.0",
"parity-scale-codec 1.1.0 (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.102 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
"sr-version 2.0.0",
"substrate-primitives 2.0.0",
]
[[package]]
name = "frame-system-rpc"
version = "2.0.0"
dependencies = [
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core-client 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-derive 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-system-rpc-runtime-api 2.0.0",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 2.0.0",
"substrate-client 2.0.0",
"substrate-primitives 2.0.0",
"substrate-test-runtime-client 2.0.0",
"substrate-transaction-pool 2.0.0",
]
[[package]]
name = "frame-system-rpc-runtime-api"
version = "2.0.0"
dependencies = [
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-api 2.0.0",
]
[[package]]
name = "frame-utility"
version = "2.0.0"
dependencies = [
"frame-support 2.0.0",
"frame-system 2.0.0",
"pallet-balances 2.0.0",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
"substrate-primitives 2.0.0",
]
[[package]]
name = "pallet-assets"
version = "2.0.0"
@@ -3472,9 +3472,9 @@ dependencies = [
name = "pallet-aura"
version = "2.0.0"
dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-support 2.0.0",
"frame-system 2.0.0",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pallet-session 2.0.0",
"pallet-timestamp 2.0.0",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3512,9 +3512,9 @@ dependencies = [
name = "pallet-authorship"
version = "0.1.0"
dependencies = [
"impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-support 2.0.0",
"frame-system 2.0.0",
"impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sp-authorship 2.0.0",
"sr-io 2.0.0",
@@ -3528,10 +3528,10 @@ dependencies = [
name = "pallet-babe"
version = "2.0.0"
dependencies = [
"hex-literal 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)",
"frame-support 2.0.0",
"frame-system 2.0.0",
"hex-literal 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)",
"pallet-session 2.0.0",
"pallet-timestamp 2.0.0",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3569,9 +3569,9 @@ dependencies = [
name = "pallet-collective"
version = "2.0.0"
dependencies = [
"hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-support 2.0.0",
"frame-system 2.0.0",
"hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pallet-balances 2.0.0",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3587,10 +3587,10 @@ name = "pallet-contracts"
version = "2.0.0"
dependencies = [
"assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-support 2.0.0",
"frame-system 2.0.0",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pallet-balances 2.0.0",
"pallet-randomness-collective-flip 2.0.0",
"pallet-timestamp 2.0.0",
@@ -3654,9 +3654,9 @@ dependencies = [
name = "pallet-elections"
version = "2.0.0"
dependencies = [
"hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-support 2.0.0",
"frame-system 2.0.0",
"hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pallet-balances 2.0.0",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3671,9 +3671,9 @@ dependencies = [
name = "pallet-elections-phragmen"
version = "2.0.0"
dependencies = [
"hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-support 2.0.0",
"frame-system 2.0.0",
"hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pallet-balances 2.0.0",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3723,9 +3723,9 @@ dependencies = [
name = "pallet-finality-tracker"
version = "2.0.0"
dependencies = [
"impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-support 2.0.0",
"frame-system 2.0.0",
"impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"sp-finality-tracker 2.0.0",
@@ -3881,10 +3881,10 @@ dependencies = [
name = "pallet-session"
version = "2.0.0"
dependencies = [
"impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-support 2.0.0",
"frame-system 2.0.0",
"impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pallet-timestamp 2.0.0",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3950,9 +3950,9 @@ dependencies = [
name = "pallet-timestamp"
version = "2.0.0"
dependencies = [
"impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-support 2.0.0",
"frame-system 2.0.0",
"impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"sp-timestamp 2.0.0",
@@ -5474,11 +5474,11 @@ name = "subkey"
version = "2.0.0"
dependencies = [
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-system 2.0.0",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"node-primitives 2.0.0",
"node-runtime 2.0.0",
"frame-system 2.0.0",
"pallet-balances 2.0.0",
"pallet-transaction-payment 2.0.0",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -6589,12 +6589,12 @@ name = "substrate-test-runtime"
version = "2.0.0"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
"frame-executive 2.0.0",
"frame-support 2.0.0",
"frame-system 2.0.0",
"frame-system-rpc-runtime-api 2.0.0",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
"pallet-babe 2.0.0",
"pallet-timestamp 2.0.0",
"parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+398 -182
View File
@@ -52,15 +52,21 @@
//!
//! Candidates also reserve a bond as they submit candidacy. A candidate cannot take their candidacy
//! back. A candidate can end up in one of the below situations:
//! - **Winner**: A winner is kept as a _member_. They must still have a bond in reserve and they
//! are automatically counted as a candidate for the next election.
//! - **Loser**: Any of the candidate who are not a winner are left as losers. A loser might be an
//! _outgoing member_, meaning that they are an active member who failed to keep their spot. In
//! this case, the outgoing member will get their bond back. Otherwise, the bond is slashed from
//! the loser candidate.
//! - **Winner**: A winner is kept as a _member_. They must still have a bond in reserve and they
//! are automatically counted as a candidate for the next election.
//! - **Runner-up**: Runners-up are the best candidates immediately after the winners. The number
//! of runners_up to keep is configurable. Runners-up are used, in order that they are elected,
//! as replacements when a candidate is kicked by `remove_member()`.
//! of runners_up to keep is configurable. Runners-up are used, in order that they are elected,
//! as replacements when a candidate is kicked by `[remove_member]`, or when an active member
//! renounces their candidacy. Runners are automatically counted as a candidate for the next
//! election.
//! - **Loser**: Any of the candidate who are not a winner are left as losers. A loser might be an
//! _outgoing member or runner_, meaning that they are an active member who failed to keep their
//! spot. An outgoing will always lose their bond.
//!
//! ##### Renouncing candidacy.
//!
//! All candidates, elected or not, can renounce their candidacy. A call to [`renounce_candidacy`]
//! will always cause the candidacy bond to be refunded.
//!
//! Note that with the members being the default candidates for the next round and votes persisting
//! in storage, the election system is entirely stable given no further input. This means that if
@@ -77,12 +83,10 @@
#![cfg_attr(not(feature = "std"), no_std)]
use rstd::prelude::*;
use codec::Decode;
use sr_primitives::{print, traits::{Zero, StaticLookup, Bounded, Convert}};
use support::weights::SimpleDispatchInfo;
use support::{
decl_storage, decl_event, ensure, decl_module, dispatch,
storage::unhashed,
traits::{
Currency, Get, LockableCurrency, LockIdentifier, ReservableCurrency, WithdrawReasons,
ChangeMembers, OnUnbalanced, WithdrawReason
@@ -161,11 +165,6 @@ decl_storage! {
/// The present candidate list. Sorted based on account id. A current member can never enter
/// this vector and is always implicitly assumed to be a candidate.
pub Candidates get(fn candidates): Vec<T::AccountId>;
/// Has the storage format been updated?
/// NOTE: Only use and set to false if you have used an early version of this module. Should
/// be set to true otherwise.
DidMigrate: bool;
}
}
@@ -315,6 +314,7 @@ decl_module! {
let index = is_candidate.unwrap_err();
ensure!(!Self::is_member(&who), "member cannot re-submit candidacy");
ensure!(!Self::is_runner(&who), "runner cannot re-submit candidacy");
T::Currency::reserve(&who, T::CandidacyBond::get())
.map_err(|_| "candidate does not have enough funds")?;
@@ -322,7 +322,63 @@ decl_module! {
<Candidates<T>>::mutate(|c| c.insert(index, who));
}
/// Remove a particular member from the set. This is effective immediately.
/// Renounce one's intention to be a candidate for the next election round. 3 potential
/// outcomes exist:
/// - `origin` is a candidate and not elected in any set. In this case, the bond is
/// unreserved, returned and origin is removed as a candidate.
/// - `origin` is a current runner up. In this case, the bond is unreserved, returned and
/// origin is removed as a runner.
/// - `origin` is a current member. In this case, the bond is unreserved and origin is
/// removed as a member, consequently not being a candidate for the next round anymore.
/// Similar to [`remove_voter`], if replacement runners exists, they are immediately used.
#[weight = SimpleDispatchInfo::FixedOperational(2_000_000)]
fn renounce_candidacy(origin) {
let who = ensure_signed(origin)?;
// NOTE: this function attempts the 3 conditions (being a candidate, member, runner) and
// fails if none are matched. Unlike other Palette functions and modules where checks
// happen first and then execution happens, this function is written the other way
// around. The main intention is that reading all of the candidates, members and runners
// from storage is expensive. Furthermore, we know (soft proof) that they are always
// mutually exclusive. Hence, we try one, and only then decode more storage.
if let Ok(_replacement) = Self::remove_and_replace_member(&who) {
T::Currency::unreserve(&who, T::CandidacyBond::get());
Self::deposit_event(RawEvent::MemberRenounced(who.clone()));
// safety guard to make sure we do only one arm. Better to read runners later.
return Ok(());
}
let mut runners_with_stake = Self::runners_up();
if let Ok(index) = runners_with_stake
.binary_search_by(|(ref r, ref _s)| r.cmp(&who))
{
runners_with_stake.remove(index);
// unreserve the bond
T::Currency::unreserve(&who, T::CandidacyBond::get());
// update storage.
<RunnersUp<T>>::put(runners_with_stake);
// safety guard to make sure we do only one arm. Better to read runners later.
return Ok(());
}
let mut candidates = Self::candidates();
if let Ok(index) = candidates.binary_search(&who) {
candidates.remove(index);
// unreserve the bond
T::Currency::unreserve(&who, T::CandidacyBond::get());
// update storage.
<Candidates<T>>::put(candidates);
// safety guard to make sure we do only one arm. Better to read runners later.
return Ok(());
}
return Err("origin is not a candidate, member or a runner.");
}
/// Remove a particular member from the set. This is effective immediately and the bond of
/// the outgoing member is slashed.
///
/// If a runner-up is available, then the best runner-up will be removed and replaces the
/// outgoing member. Otherwise, a new phragmen round is started.
@@ -339,51 +395,21 @@ decl_module! {
ensure_root(origin)?;
let who = T::Lookup::lookup(who)?;
let mut members_with_stake = Self::members();
if let Ok(index) = members_with_stake.binary_search_by(|(ref m, ref _s)| m.cmp(&who)) {
// remove, slash, emit event.
members_with_stake.remove(index);
return Self::remove_and_replace_member(&who).map(|had_replacement| {
let (imbalance, _) = T::Currency::slash_reserved(&who, T::CandidacyBond::get());
T::KickedMember::on_unbalanced(imbalance);
Self::deposit_event(RawEvent::MemberKicked(who.clone()));
let mut runners_up = Self::runners_up();
if let Some((replacement, stake)) = runners_up.pop() {
// replace the outgoing with the best runner up.
if let Err(index) = members_with_stake
.binary_search_by(|(ref m, ref _s)| m.cmp(&replacement))
{
members_with_stake.insert(index, (replacement.clone(), stake));
ElectionRounds::mutate(|v| *v += 1);
T::ChangeMembers::change_members_sorted(
&[replacement],
&[who],
&members_with_stake
.iter()
.map(|(m, _)| m.clone())
.collect::<Vec<T::AccountId>>(),
);
}
// else it would mean that the runner up was already a member. This cannot
// happen. If it does, not much that we can do about it.
<Members<T>>::put(members_with_stake);
<RunnersUp<T>>::put(runners_up);
} else {
// update `Members` storage -- `do_phragmen` adds this to the candidate list.
<Members<T>>::put(members_with_stake);
// trigger a new phragmen. grab a cup of coffee. This might take a while.
if !had_replacement {
Self::do_phragmen();
}
}
()
})
}
/// What to do at the end of each block. Checks if an election needs to happen or not.
fn on_initialize(n: T::BlockNumber) {
if !DidMigrate::exists() {
DidMigrate::put(true);
Self::do_migrate();
}
if let Err(e) = Self::end_block(n) {
print("Guru meditation");
print(e);
@@ -405,6 +431,8 @@ decl_event!(
/// A member has been removed. This should always be followed by either `NewTerm` ot
/// `EmptyTerm`.
MemberKicked(AccountId),
/// A member has renounced their candidacy.
MemberRenounced(AccountId),
/// A voter (first element) was reported (byt the second element) with the the report being
/// successful or not (third element).
VoterReported(AccountId, AccountId, bool),
@@ -412,6 +440,54 @@ decl_event!(
);
impl<T: Trait> Module<T> {
/// Attempts to remove a member `who`. If a runner up exists, it is used as the replacement.
/// Otherwise, `Ok(false)` is returned to signal the caller.
///
/// In both cases, [`Members`], [`ElectionRounds`] and [`RunnersUp`] storage are updated
/// accordingly. Furthermore, the membership change is reported.
///
/// O(phragmen) in the worse case.
fn remove_and_replace_member(who: &T::AccountId) -> Result<bool, &'static str> {
let mut members_with_stake = Self::members();
if let Ok(index) = members_with_stake.binary_search_by(|(ref m, ref _s)| m.cmp(who)) {
members_with_stake.remove(index);
let mut runners_up = Self::runners_up();
if let Some((replacement, stake)) = runners_up.pop() {
// replace the outgoing with the best runner up.
if let Err(index) = members_with_stake
.binary_search_by(|(ref m, ref _s)| m.cmp(&replacement))
{
members_with_stake.insert(index, (replacement.clone(), stake));
ElectionRounds::mutate(|v| *v += 1);
T::ChangeMembers::change_members_sorted(
&[replacement],
&[who.clone()],
&members_with_stake
.iter()
.map(|(m, _)| m.clone())
.collect::<Vec<T::AccountId>>(),
);
}
// else it would mean that the runner up was already a member. This cannot
// happen. If it does, not much that we can do about it.
<Members<T>>::put(members_with_stake);
<RunnersUp<T>>::put(runners_up);
Ok(true)
} else {
// update `Members` storage -- `do_phragmen` adds this to the candidate list.
<Members<T>>::put(members_with_stake);
// signal caller that no replacement has been found.
Ok(false)
}
} else {
Err("not a member")
}
}
/// Check if `who` is a candidate. It returns the insert index if the element does not exists as
/// an error.
///
@@ -434,6 +510,13 @@ impl<T: Trait> Module<T> {
Self::members_ids().binary_search(who).is_ok()
}
/// Check if `who` is currently an active runner.
///
/// Limited number of runners-up. Binary search. Constant time factor. O(1)
fn is_runner(who: &T::AccountId) -> bool {
Self::runners_up_ids().binary_search(who).is_ok()
}
/// Returns number of desired members.
fn desired_members() -> u32 {
T::DesiredMembers::get()
@@ -524,14 +607,12 @@ impl<T: Trait> Module<T> {
let mut candidates = Self::candidates();
// candidates who explicitly called `submit_candidacy`. Only these folks are at the risk of
// losing their bond.
let mut exposed_candidates = candidates.clone();
let exposed_candidates = candidates.clone();
// current members are always a candidate for the next round as well.
// this is guaranteed to not create any duplicates.
candidates.append(&mut Self::members_ids());
// previous runners_up are also always candidates for the next round.
candidates.append(&mut Self::runners_up_ids());
// and exposed to being an outgoing in case they are no longer elected.
exposed_candidates.append(&mut Self::runners_up_ids());
let voters_and_votes = <VotesOf<T>>::enumerate()
.map(|(v, i)| (v, i))
@@ -544,9 +625,10 @@ impl<T: Trait> Module<T> {
Self::locked_stake_of,
);
let mut to_release_bond: Vec<T::AccountId> = Vec::with_capacity(desired_seats);
let old_members = <Members<T>>::take();
if let Some(phragmen_result) = maybe_phragmen_result {
let old_members = <Members<T>>::take();
let old_runners = <RunnersUp<T>>::take();
// filter out those who had literally no votes at all.
// AUDIT/NOTE: the need to do this is because all candidates, even those who have no
// vote are still considered by phragmen and when good candidates are scarce, then these
@@ -581,22 +663,28 @@ impl<T: Trait> Module<T> {
// split new set into winners and runner ups.
let split_point = desired_seats.min(new_set_with_stake.len());
let mut new_members = (&new_set_with_stake[..split_point]).to_vec();
let runners_up = &new_set_with_stake[split_point..]
let new_members_ids = new_members
.iter()
.map(|(m, _)| m.clone())
.collect::<Vec<T::AccountId>>();
let new_runners_up = &new_set_with_stake[split_point..]
.into_iter()
.cloned()
.rev()
.collect::<Vec<(T::AccountId, BalanceOf<T>)>>();
let new_runners_up_ids = new_runners_up
.iter()
.map(|(r, _)| r.clone())
.collect::<Vec<T::AccountId>>();
// save the runners as-is. They are sorted based on desirability.
// sort and save the members.
new_members.sort();
<Members<T>>::put(&new_members);
// save the runners as-is
<RunnersUp<T>>::put(runners_up);
// report member changes. We compute diff because we need the outgoing list.
let (incoming, outgoing) = T::ChangeMembers::compute_members_diff(
&Self::members_ids(),
&new_members_ids,
&old_members.into_iter().map(|(m, _)| m).collect::<Vec<T::AccountId>>(),
);
T::ChangeMembers::change_members_sorted(
@@ -605,62 +693,50 @@ impl<T: Trait> Module<T> {
&Self::members_ids(),
);
// unlike exposed_candidates, these are members who were in the list and no longer
// exist. They must get their bond back.
to_release_bond = outgoing.to_vec();
// outgoing candidates lose their bond.
let mut to_burn_bond = outgoing.to_vec();
// compute the outgoing of runners up as well and append them to the `to_burn_bond`
{
let (_, outgoing) = T::ChangeMembers::compute_members_diff(
&new_runners_up_ids,
&old_runners.into_iter().map(|(r, _)| r).collect::<Vec<T::AccountId>>(),
);
to_burn_bond.extend(outgoing);
}
// Burn loser bond. members list is sorted. O(NLogM) (N candidates, M members)
// runner up list is not sorted. O(K*N) given K runner ups. Overall: O(NLogM + N*K)
// both the member and runner counts are bounded.
exposed_candidates.into_iter().for_each(|c| {
// any candidate who is not a member and not a runner up.
if new_members.binary_search_by_key(&c, |(m, _)| m.clone()).is_err()
&& !Self::runners_up_ids().contains(&c)
&& !new_runners_up_ids.contains(&c)
{
let (imbalance, _) = T::Currency::slash_reserved(&c, T::CandidacyBond::get());
T::LoserCandidate::on_unbalanced(imbalance);
}
});
Self::deposit_event(RawEvent::NewTerm(new_members.to_vec()));
// Burn outgoing bonds
to_burn_bond.into_iter().for_each(|x| {
let (imbalance, _) = T::Currency::slash_reserved(&x, T::CandidacyBond::get());
T::LoserCandidate::on_unbalanced(imbalance);
});
<Members<T>>::put(&new_members);
<RunnersUp<T>>::put(new_runners_up);
Self::deposit_event(RawEvent::NewTerm(new_members.clone().to_vec()));
} else {
Self::deposit_event(RawEvent::EmptyTerm);
}
// unreserve the bond of all the outgoings.
to_release_bond.iter().for_each(|m| {
T::Currency::unreserve(&m, T::CandidacyBond::get());
});
// clean candidates.
<Candidates<T>>::kill();
ElectionRounds::mutate(|v| *v += 1);
}
/// Perform the storage update needed to migrate the module from the initial version of the
/// storage.
///
/// If decoding the old storage fails in any way, the consequence is that we start with an empty
/// set.
fn do_migrate() {
// old storage format.
let old_members: Vec<T::AccountId> = unhashed::get_raw(&<Members<T>>::hashed_key())
.and_then(|bytes| Decode::decode(&mut &*bytes).ok()).unwrap_or_default();
let old_runners: Vec<T::AccountId> = unhashed::get_raw(&<RunnersUp<T>>::hashed_key())
.and_then(|bytes| Decode::decode(&mut &*bytes).ok()).unwrap_or_default();
// new storage format.
let new_runners: Vec<(T::AccountId, BalanceOf<T>)> = old_runners
.into_iter()
.map(|r| (r, Zero::zero()))
.collect();
let new_members: Vec<(T::AccountId, BalanceOf<T>)> = old_members
.into_iter()
.map(|r| (r, Zero::zero()))
.collect();
<Members<T>>::put(new_members);
<RunnersUp<T>>::put(new_runners);
}
}
#[cfg(test)]
@@ -671,7 +747,7 @@ mod tests {
use primitives::H256;
use sr_primitives::{
Perbill, testing::Header, BuildStorage,
traits::{OnInitialize, BlakeTwo256, IdentityLookup, Block as BlockT},
traits::{BlakeTwo256, IdentityLookup, Block as BlockT},
};
use crate as elections;
@@ -860,30 +936,6 @@ mod tests {
lock.amount
}
#[test]
fn temp_migration_works() {
ExtBuilder::default().build().execute_with(|| {
use support::storage::unhashed;
use codec::Encode;
let old_members = vec![1u64, 2];
let old_runners = vec![3u64];
let members_key = <Members<Test>>::hashed_key();
let runners_key = <RunnersUp<Test>>::hashed_key();
unhashed::put_raw(&members_key, &old_members.encode()[..]);
unhashed::put_raw(&runners_key, &old_runners.encode()[..]);
assert_eq!(DidMigrate::get(), false);
<Elections as OnInitialize<u64>>::on_initialize(1);
assert_eq!(DidMigrate::get(), true);
assert_eq!(Elections::members(), vec![(1, 0), (2, 0)]);
assert_eq!(Elections::runners_up(), vec![(3, 0)]);
});
}
#[test]
fn params_should_work() {
ExtBuilder::default().build().execute_with(|| {
@@ -1017,13 +1069,36 @@ mod tests {
});
}
#[test]
fn runner_candidate_submission_should_not_work() {
ExtBuilder::default().desired_runners_up(2).build().execute_with(|| {
assert_ok!(Elections::submit_candidacy(Origin::signed(5)));
assert_ok!(Elections::submit_candidacy(Origin::signed(4)));
assert_ok!(Elections::submit_candidacy(Origin::signed(3)));
assert_ok!(Elections::vote(Origin::signed(2), vec![5, 4], 20));
assert_ok!(Elections::vote(Origin::signed(1), vec![3], 10));
System::set_block_number(5);
assert_ok!(Elections::end_block(System::block_number()));
assert_eq!(Elections::members_ids(), vec![4, 5]);
assert_eq!(Elections::runners_up_ids(), vec![3]);
assert_noop!(
Elections::submit_candidacy(Origin::signed(3)),
"runner cannot re-submit candidacy",
);
});
}
#[test]
fn poor_candidate_submission_should_not_work() {
ExtBuilder::default().build().execute_with(|| {
assert_eq!(Elections::candidates(), Vec::<u64>::new());
assert_noop!(
Elections::submit_candidacy(Origin::signed(7)),
"candidate does not have enough funds"
"candidate does not have enough funds",
);
});
}
@@ -1089,7 +1164,6 @@ mod tests {
#[test]
fn can_vote_for_old_members_even_when_no_new_candidates() {
// let allowed_votes = candidates_count as usize + Self::members().len()
ExtBuilder::default().build().execute_with(|| {
assert_ok!(Elections::submit_candidacy(Origin::signed(5)));
assert_ok!(Elections::submit_candidacy(Origin::signed(4)));
@@ -1114,7 +1188,7 @@ mod tests {
assert_noop!(
Elections::vote(Origin::signed(2), vec![10, 20, 30], 20),
"cannot vote more than candidates"
"cannot vote more than candidates",
);
});
}
@@ -1127,7 +1201,7 @@ mod tests {
assert_noop!(
Elections::vote(Origin::signed(2), vec![4], 1),
"cannot vote with stake less than minimum balance"
"cannot vote with stake less than minimum balance",
);
})
}
@@ -1484,7 +1558,6 @@ mod tests {
System::set_block_number(5);
assert_ok!(Elections::end_block(System::block_number()));
assert_eq!(Elections::members_ids(), vec![4, 5]);
assert_eq!(Elections::runners_up_ids(), vec![2]);
assert_eq!(balances(&2), (15, 5));
@@ -1493,16 +1566,63 @@ mod tests {
System::set_block_number(10);
assert_ok!(Elections::end_block(System::block_number()));
assert_eq!(Elections::members_ids(), vec![4, 5]);
assert_eq!(Elections::runners_up_ids(), vec![3]);
assert_eq!(balances(&3), (25, 5));
assert_eq!(balances(&2), (15, 2));
});
}
#[test]
fn current_members_are_always_implicitly_next_candidate() {
fn members_lose_bond_once_outgoing() {
ExtBuilder::default().build().execute_with(|| {
assert_eq!(balances(&5), (50, 0));
assert_ok!(Elections::submit_candidacy(Origin::signed(5)));
assert_eq!(balances(&5), (47, 3));
assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50));
assert_eq!(balances(&5), (45, 5));
System::set_block_number(5);
assert_ok!(Elections::end_block(System::block_number()));
assert_eq!(Elections::members_ids(), vec![5]);
assert_ok!(Elections::remove_voter(Origin::signed(5)));
assert_eq!(balances(&5), (47, 3));
System::set_block_number(10);
assert_ok!(Elections::end_block(System::block_number()));
assert_eq!(Elections::members_ids(), vec![]);
assert_eq!(balances(&5), (47, 0));
});
}
#[test]
fn losers_will_lose_the_bond() {
ExtBuilder::default().build().execute_with(|| {
assert_ok!(Elections::submit_candidacy(Origin::signed(5)));
assert_ok!(Elections::submit_candidacy(Origin::signed(3)));
assert_ok!(Elections::vote(Origin::signed(4), vec![5], 40));
assert_eq!(balances(&5), (47, 3));
assert_eq!(balances(&3), (27, 3));
System::set_block_number(5);
assert_ok!(Elections::end_block(System::block_number()));
assert_eq!(Elections::members_ids(), vec![5]);
// winner
assert_eq!(balances(&5), (47, 3));
// loser
assert_eq!(balances(&3), (27, 0));
});
}
#[test]
fn current_members_are_always_next_candidate() {
ExtBuilder::default().build().execute_with(|| {
assert_ok!(Elections::submit_candidacy(Origin::signed(5)));
assert_ok!(Elections::submit_candidacy(Origin::signed(4)));
@@ -1630,55 +1750,6 @@ mod tests {
});
}
#[test]
fn outgoing_will_get_the_bond_back() {
ExtBuilder::default().build().execute_with(|| {
assert_eq!(balances(&5), (50, 0));
assert_ok!(Elections::submit_candidacy(Origin::signed(5)));
assert_eq!(balances(&5), (47, 3));
assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50));
assert_eq!(balances(&5), (45, 5));
System::set_block_number(5);
assert_ok!(Elections::end_block(System::block_number()));
assert_eq!(Elections::members_ids(), vec![5]);
assert_ok!(Elections::remove_voter(Origin::signed(5)));
assert_eq!(balances(&5), (47, 3));
System::set_block_number(10);
assert_ok!(Elections::end_block(System::block_number()));
assert_eq!(Elections::members_ids(), vec![]);
assert_eq!(balances(&5), (50, 0));
});
}
#[test]
fn losers_will_lose_the_bond() {
ExtBuilder::default().build().execute_with(|| {
assert_ok!(Elections::submit_candidacy(Origin::signed(5)));
assert_ok!(Elections::submit_candidacy(Origin::signed(3)));
assert_ok!(Elections::vote(Origin::signed(4), vec![5], 40));
assert_eq!(balances(&5), (47, 3));
assert_eq!(balances(&3), (27, 3));
System::set_block_number(5);
assert_ok!(Elections::end_block(System::block_number()));
assert_eq!(Elections::members_ids(), vec![5]);
// winner
assert_eq!(balances(&5), (47, 3));
// loser
assert_eq!(balances(&3), (27, 0));
});
}
#[test]
fn incoming_outgoing_are_reported() {
ExtBuilder::default().build().execute_with(|| {
@@ -1717,8 +1788,8 @@ mod tests {
// 1 is a loser, slashed by 3.
assert_eq!(balances(&1), (5, 2));
// 5 is an outgoing loser, it will get their bond back.
assert_eq!(balances(&5), (48, 2));
// 5 is an outgoing loser. will also get slashed.
assert_eq!(balances(&5), (45, 2));
assert_eq!(
System::events()[0].event,
@@ -1766,4 +1837,149 @@ mod tests {
assert_eq!(Elections::runners_up(), vec![(3, 20), (2, 30)]);
});
}
#[test]
fn candidates_are_sorted() {
ExtBuilder::default().build().execute_with(|| {
assert_ok!(Elections::submit_candidacy(Origin::signed(5)));
assert_ok!(Elections::submit_candidacy(Origin::signed(3)));
assert_eq!(Elections::candidates(), vec![3, 5]);
assert_ok!(Elections::submit_candidacy(Origin::signed(2)));
assert_ok!(Elections::submit_candidacy(Origin::signed(4)));
assert_ok!(Elections::renounce_candidacy(Origin::signed(3)));
assert_eq!(Elections::candidates(), vec![2, 4, 5]);
})
}
#[test]
fn runner_up_replacement_maintains_members_order() {
ExtBuilder::default().desired_runners_up(2).build().execute_with(|| {
assert_ok!(Elections::submit_candidacy(Origin::signed(5)));
assert_ok!(Elections::submit_candidacy(Origin::signed(4)));
assert_ok!(Elections::submit_candidacy(Origin::signed(2)));
assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20));
assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40));
assert_ok!(Elections::vote(Origin::signed(5), vec![2], 50));
System::set_block_number(5);
assert_ok!(Elections::end_block(System::block_number()));
assert_eq!(Elections::members_ids(), vec![2, 4]);
assert_ok!(Elections::remove_member(Origin::ROOT, 2));
assert_eq!(Elections::members_ids(), vec![4, 5]);
});
}
#[test]
fn can_renounce_candidacy_member_with_runners_bond_is_refunded() {
ExtBuilder::default().desired_runners_up(2).build().execute_with(|| {
assert_ok!(Elections::submit_candidacy(Origin::signed(5)));
assert_ok!(Elections::submit_candidacy(Origin::signed(4)));
assert_ok!(Elections::submit_candidacy(Origin::signed(3)));
assert_ok!(Elections::submit_candidacy(Origin::signed(2)));
assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50));
assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40));
assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30));
assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20));
System::set_block_number(5);
assert_ok!(Elections::end_block(System::block_number()));
assert_eq!(Elections::members_ids(), vec![4, 5]);
assert_eq!(Elections::runners_up_ids(), vec![2, 3]);
assert_ok!(Elections::renounce_candidacy(Origin::signed(4)));
assert_eq!(balances(&4), (38, 2)); // 2 is voting bond.
assert_eq!(Elections::members_ids(), vec![3, 5]);
assert_eq!(Elections::runners_up_ids(), vec![2]);
})
}
#[test]
fn can_renounce_candidacy_member_without_runners_bond_is_refunded() {
ExtBuilder::default().desired_runners_up(2).build().execute_with(|| {
assert_ok!(Elections::submit_candidacy(Origin::signed(5)));
assert_ok!(Elections::submit_candidacy(Origin::signed(4)));
assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50));
assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40));
System::set_block_number(5);
assert_ok!(Elections::end_block(System::block_number()));
assert_ok!(Elections::submit_candidacy(Origin::signed(3)));
assert_ok!(Elections::submit_candidacy(Origin::signed(2)));
assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30));
assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20));
assert_eq!(Elections::members_ids(), vec![4, 5]);
assert_eq!(Elections::runners_up_ids(), vec![]);
assert_eq!(Elections::candidates(), vec![2, 3]);
assert_ok!(Elections::renounce_candidacy(Origin::signed(4)));
assert_eq!(balances(&4), (38, 2)); // 2 is voting bond.
// no replacement
assert_eq!(Elections::members_ids(), vec![5]);
assert_eq!(Elections::runners_up_ids(), vec![]);
// still candidate
assert_eq!(Elections::candidates(), vec![2, 3]);
})
}
#[test]
fn can_renounce_candidacy_runner() {
ExtBuilder::default().desired_runners_up(2).build().execute_with(|| {
assert_ok!(Elections::submit_candidacy(Origin::signed(5)));
assert_ok!(Elections::submit_candidacy(Origin::signed(4)));
assert_ok!(Elections::submit_candidacy(Origin::signed(3)));
assert_ok!(Elections::submit_candidacy(Origin::signed(2)));
assert_ok!(Elections::vote(Origin::signed(5), vec![4], 50));
assert_ok!(Elections::vote(Origin::signed(4), vec![5], 40));
assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30));
assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20));
System::set_block_number(5);
assert_ok!(Elections::end_block(System::block_number()));
assert_eq!(Elections::members_ids(), vec![4, 5]);
assert_eq!(Elections::runners_up_ids(), vec![2, 3]);
assert_ok!(Elections::renounce_candidacy(Origin::signed(3)));
assert_eq!(balances(&3), (28, 2)); // 2 is voting bond.
assert_eq!(Elections::members_ids(), vec![4, 5]);
assert_eq!(Elections::runners_up_ids(), vec![2]);
})
}
#[test]
fn can_renounce_candidacy_candidate() {
ExtBuilder::default().build().execute_with(|| {
assert_ok!(Elections::submit_candidacy(Origin::signed(5)));
assert_eq!(balances(&5), (47, 3));
assert_eq!(Elections::candidates(), vec![5]);
assert_ok!(Elections::renounce_candidacy(Origin::signed(5)));
assert_eq!(balances(&5), (50, 0));
assert_eq!(Elections::candidates(), vec![]);
})
}
#[test]
fn wrong_renounce_candidacy_should_fail() {
ExtBuilder::default().build().execute_with(|| {
assert_noop!(
Elections::renounce_candidacy(Origin::signed(5)),
"origin is not a candidate, member or a runner.",
);
})
}
}